kfifo: sanitize *_user error handling

Right now for kfifo_*_user it's not easily possible to distingush between
a user copy failing and the FIFO not containing enough data.  The problem
is that both conditions are multiplexed into the same return code.

Avoid this by moving the "copy length" into a separate output parameter
and only return 0/-EFAULT in the main return value.

I didn't fully adapt the weird "record" variants, those seem
to be unused anyways and were rather messy (should they be just removed?)

I would appreciate some double checking if I did all the conversions
correctly.

Signed-off-by: Andi Kleen <ak@linux.intel.com>
Cc: Stefani Seibold <stefani@seibold.net>
Cc: Roland Dreier <rdreier@cisco.com>
Cc: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Cc: Andy Walls <awalls@radix.net>
Cc: Vikram Dhillon <dhillonv10@gmail.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Andi Kleen
2010-01-15 17:01:15 -08:00
committed by Linus Torvalds
parent 8ecc295153
commit 64ce1037c5
2 changed files with 53 additions and 31 deletions

View File

@ -235,11 +235,11 @@ static inline __must_check unsigned int kfifo_out_locked(struct kfifo *fifo,
extern void kfifo_skip(struct kfifo *fifo, unsigned int len);
extern __must_check unsigned int kfifo_from_user(struct kfifo *fifo,
const void __user *from, unsigned int n);
extern __must_check int kfifo_from_user(struct kfifo *fifo,
const void __user *from, unsigned int n, unsigned *lenout);
extern __must_check unsigned int kfifo_to_user(struct kfifo *fifo,
void __user *to, unsigned int n);
extern __must_check int kfifo_to_user(struct kfifo *fifo,
void __user *to, unsigned int n, unsigned *lenout);
/*
* __kfifo_add_out internal helper function for updating the out offset