mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* ioctl arg passing
@ 2001-04-23 16:06 Matt
  2001-04-23 17:50 ` Ingo Oeser
                   ` (2 more replies)
  0 siblings, 3 replies; 13+ messages in thread
From: Matt @ 2001-04-23 16:06 UTC (permalink / raw)
  To: linux-kernel

Righto, first post to the list, here goes:

I'm writing a char device driver for a dsp card that drives a motion
platform. The basic flow is I basically have to reset the card and upload
an executable file to it, and then poke the card to run it. Once this is
done, I can issue instructions to the card/code to pass and return data
from the card about the platform it's controlling.

To pass the instructions I'm using a generic ioctl which passes the data
between user & kernel-space using a struct which is basically like:

struct instruction_t {
	__s16 code;
	__s16 rxlen;
	__s16 *rxbuf;
	__s16 txlen;
	__s16 *txbuf;
};

(rx|tx)len is the length of the extra data that is provided/requested
in/to be in (rx|tx)buf. Got me so far?

Am I allowed to do this across the ioctl interface? In my ioctl
"handler" I'm attempting to do:

--8<--

struct instruction_t local;
__s16 *temp;

copy_from_user( &local, ( struct instruction_t * ) arg, sizeof( struct instruction_t ) );
temp = kmalloc( sizeof( __s16 ) * local.rxlen, GFP_KERNEL );
copy_from_user( temp, arg, sizeof( __s16 ) * local.rxlen );
local.rxbuf = temp;
temp = kmalloc( sizeof( __s16 ) * local.txlen, GFP_KERNEL );
...

--8<--

Is this going to work as expected? Or am I gonna generate oops-a-plenty?

Cheers

Matt


^ permalink raw reply	[flat|nested] 13+ messages in thread
* Re: ioctl arg passing
@ 2001-04-23 18:29 Petr Vandrovec
  2001-04-23 16:40 ` Alex Bligh - linux-kernel
  0 siblings, 1 reply; 13+ messages in thread
From: Petr Vandrovec @ 2001-04-23 18:29 UTC (permalink / raw)
  To: Matt; +Cc: linux-kernel

On 23 Apr 01 at 17:06, Matt wrote:
> struct instruction_t {
>     __s16 code;
>     __s16 rxlen;
>     __s16 *rxbuf;
>     __s16 txlen;
>     __s16 *txbuf;
> };

You should reorder fields, starting with largest fields and going down
to smaller ones. That ways you'll not have troubles with alignment when
someone decides to play with alignment rules...

> struct instruction_t local;
> __s16 *temp;
> 
> copy_from_user( &local, ( struct instruction_t * ) arg, sizeof( struct instruction_t ) );
> temp = kmalloc( sizeof( __s16 ) * local.rxlen, GFP_KERNEL );
> copy_from_user( temp, arg, sizeof( __s16 ) * local.rxlen );
> local.rxbuf = temp;
> temp = kmalloc( sizeof( __s16 ) * local.txlen, GFP_KERNEL );
> ...

As you are using signed value for rxlen/txlen, you should check
for value < 0 ... And there is very low chance that kmalloc() for 
anything bigger than 4KB will succeed. You should either use
vmalloc unconditionally, or at least as fallback. And some error
checking (copy_from_user returns 0 if everything went OK) also
makes driver safer.
                                        Best regards,
                                            Petr Vandrovec
                                            vandrove@vc.cvut.cz


^ permalink raw reply	[flat|nested] 13+ messages in thread

end of thread, other threads:[~2001-04-23 23:41 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-04-23 16:06 ioctl arg passing Matt
2001-04-23 17:50 ` Ingo Oeser
2001-04-23 20:14   ` Matt
2001-04-23 20:17   ` rui.sousa
2001-04-23 20:34     ` Matt
2001-04-23 20:37     ` Mathieu Chouquet-Stringer
2001-04-23 21:11       ` [OFFTOPIC] " rui.sousa
2001-04-23 19:58 ` Matt
2001-04-23 21:33   ` Ingo Oeser
2001-04-23 22:09 ` Matt
2001-04-23 23:41   ` Jonathan Lundell
2001-04-23 18:29 Petr Vandrovec
2001-04-23 16:40 ` Alex Bligh - linux-kernel

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®