2

I am trying to pass a struct from user space to kernel space. I had been trying for many hours and it isn't working. Here is what I have done so far..

int device_ioctl(struct inode *inode, struct file *filep, unsigned int cmd, unsigned long arg){

int ret, SIZE;


switch(cmd){

    case PASS_STRUCT_ARRAY_SIZE:

        SIZE = (int *)arg;
        if(ret < 0){
            printk("Error in PASS_STRUCT_ARRAY_SIZE\n");
            return -1;  
        }
        printk("Struct Array Size : %d\n",SIZE);
        break;

    case PASS_STRUCT:


        struct mesg{
            int pIDs[SIZE];
            int niceVal;
        };

        struct mesg data;

        ret = copy_from_user(&data, arg, sizeof(*data));
        if(ret < 0){
            printk("PASS_STRUCT\n");
            return -1;  
        }

        printk("Message PASS_STRUCT : %d\n",data.niceVal);
        break;

    default :
        return -ENOTTY;
}

return 0;
  }

I have trouble defining the struct. What is the correct way to define it? I want to have int pIDs[SIZE]. Will int *pIDs do it(in user space it is defined like pIDs[SIZE])?

EDIT:

With the above change I get this error? error: expected expression before 'struct' any ideas?

user340
  • 375
  • 12
  • 28
  • regarding PASS_STRUCT case, you should define "data" as struct , not a pointer to struct, then pass the size to copy_from_user correctly. You're problem is more likely C. imho you should be more experienced with C before digging the kernel. – sardok Aug 26 '12 at 14:33
  • How do you think I should define this function, #define PASS_STRUCT _IOW(MY_MAGIC, 2, struct mesg* )? – user340 Aug 26 '12 at 15:05
  • I defined data as struct, (struct mesg data;). But gives the error error: storage size of 'data' isn't known..any ideas? – user340 Aug 26 '12 at 15:12
  • this error most probably indicates problem in the switch statement, not in macro.which line is it? if you think that macro is problematic, then try compiling with gcc -E option to see what happens to after pre-proccessing. – sardok Aug 26 '12 at 15:51
  • @sardok yeah the problem is not with the macro..I checked it after changing the mesg struct, it compiles.. – user340 Aug 26 '12 at 15:56

1 Answers1

1

There are two variants of the structure in your question.

 struct mesg1{
  int *pIDs;
  int niceVal;
 };

 struct mesg2{
  int pIDs[SIZE];
  int niceVal;
 };

They are different; in case of mesg1 you has pointer to int array (which is outside the struct). In other case (mesg2) there is int array inside the struct.

If your SIZE is fixed (in API of your module; the same value used in user- and kernel- space), you can use second variant (mesg2).

To use first variant of structure (mesg1) you may add field size to the structure itself, like:

 struct mesg1{
  int pIDs_size;
  int *pIDs;
  int niceVal;
 };

and fill it with count of ints, pointed by *pIDs.

PS: And please, never use structures with variable-sized arrays in the middle of the struct (aka VLAIS). This is proprietary, wierd, buggy and non-documented extension to C language by GCC compiler. Only last field of struct can be array with variable size (VLA) according to international C standard. Some examples here: 1 2

PPS:

You can declare you struct with VLA (if there is only single array with variable size):

 struct mesg2{
  int niceVal;
  int pIDs[];
 };

but you should be careful when allocating memory for such struct with VLA

Community
  • 1
  • 1
osgx
  • 90,338
  • 53
  • 357
  • 513
  • Well I want to use the mesg2 type. Before passing the struct I plan on passing the SIZE. will it work? – user340 Aug 26 '12 at 15:03
  • no, you should either fix SIZE at design step and then never pass it. Or you should rewrite your structure in such way that array will be last field of the struct. – osgx Aug 26 '12 at 19:33
  • as defined by [Merriam-Webster](http://www.merriam-webster.com/dictionary/proprietary): "something that is used, produced, or marketed under exclusive legal right of the inventor or maker; // used, made, or marketed by one having the exclusive legal right". Is there any non-GCC compiler with support of VLAIS? – osgx Mar 19 '13 at 11:35