ravi
ravi

Reputation: 487

ioctl payload type/size violation

What can a driver do defensively to protect against a user-space app that issues an ioctl call with a pointer whose pointee is of a type/size different from what the driver expects/specified as part of its interface.

For e.g. say IOCTL x expects a (struct foo *) but caller issues it with (unsigned long) ((struct bar *)&bar). Will copy_from_user blow up/compromise the system stability?

Maybe one way is to expect caller to have CAP_SYS_ADMIN and have the implicit trust but is there another/better way?

Thanks.

Upvotes: 3

Views: 276

Answers (1)

BjoernD
BjoernD

Reputation: 4780

copy_to/from_user use void pointers, meaning they are ignorant of any data types you pass. And given your example, even if they were aware of the data type, you still cannot trust your user: He could simply cast to the type you want:

struct bar *x;
copy_to_kernel_aware_of_foo((struct foo*)x);

Expecting the caller to have any kinds of root privileges or capabilities also does not solve your problem - root can also make mistakes or be evil.

Things that can help a bit:

  • Only use copy_to/from_user to copy around untyped byte buffers. Don't rely on kernel and user space having the same notion of complex data structures.
  • If you only worry about data types being wrong by mistake, you might consider tagging your data structure so that it contains some magic values in between the 'real' data. This will not help you against the caller deliberately faking data, though.
  • In terms of an attack surface, the attacker will probably not attack you by passing a wrong data type, but instead provide wrong values. There's nothing to help you instead of proper validation of all data that is passed to you from user space. Never trust anything without checking!

Upvotes: 4

Related Questions