diff options
author | Kirill A. Shutemov <kirill.shutemov@linux.intel.com> | 2014-12-29 19:48:09 -0500 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2015-03-20 10:34:42 -0400 |
commit | 6250a8badb311953a49bedb16ed17eb59d21c03a (patch) | |
tree | 53432ea0f158736b5a1f839935098cfba577d2c4 /net/9p | |
parent | b642f7269bd40ae9abe9cff01581b2eb5e2c2287 (diff) |
9p: use unsigned integers for nwqid/count
As specification says, all integers in messages are unsigned. Let's fix
behaviour of p9pdu_vreadf()/p9pdu_vwritef() accordingly.
Fix for p9pdu_vreadf() is critical. If server replies with Rwalk, where
nwqid > SHRT_MAX, the value will be interpreted as negative. kmalloc, in
its order, will cast the value to (very big) size_t.
It should never happen in normal situation: we never submit Twalk with
nwname > 16, but malicious or broken server can still produce
problematic Rwalk.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com>
Signed-off-by: Dominique Martinet <dominique.martinet@cea.fr>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'net/9p')
-rw-r--r-- | net/9p/protocol.c | 6 |
1 files changed, 3 insertions, 3 deletions
diff --git a/net/9p/protocol.c b/net/9p/protocol.c index ab9127ec5b7a..305e4789f2cc 100644 --- a/net/9p/protocol.c +++ b/net/9p/protocol.c | |||
@@ -273,7 +273,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
273 | } | 273 | } |
274 | break; | 274 | break; |
275 | case 'R':{ | 275 | case 'R':{ |
276 | int16_t *nwqid = va_arg(ap, int16_t *); | 276 | uint16_t *nwqid = va_arg(ap, uint16_t *); |
277 | struct p9_qid **wqids = | 277 | struct p9_qid **wqids = |
278 | va_arg(ap, struct p9_qid **); | 278 | va_arg(ap, struct p9_qid **); |
279 | 279 | ||
@@ -448,7 +448,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
448 | } | 448 | } |
449 | break; | 449 | break; |
450 | case 'U':{ | 450 | case 'U':{ |
451 | int32_t count = va_arg(ap, int32_t); | 451 | uint32_t count = va_arg(ap, uint32_t); |
452 | const char __user *udata = | 452 | const char __user *udata = |
453 | va_arg(ap, const void __user *); | 453 | va_arg(ap, const void __user *); |
454 | errcode = p9pdu_writef(pdu, proto_version, "d", | 454 | errcode = p9pdu_writef(pdu, proto_version, "d", |
@@ -479,7 +479,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt, | |||
479 | } | 479 | } |
480 | break; | 480 | break; |
481 | case 'R':{ | 481 | case 'R':{ |
482 | int16_t nwqid = va_arg(ap, int); | 482 | uint16_t nwqid = va_arg(ap, int); |
483 | struct p9_qid *wqids = | 483 | struct p9_qid *wqids = |
484 | va_arg(ap, struct p9_qid *); | 484 | va_arg(ap, struct p9_qid *); |
485 | 485 | ||