Преглед на файлове

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>
Kirill A. Shutemov преди 10 години
родител
ревизия
6250a8badb
променени са 1 файла, в които са добавени 3 реда и са изтрити 3 реда
  1. 3 3
      net/9p/protocol.c

+ 3 - 3
net/9p/protocol.c

@@ -273,7 +273,7 @@ p9pdu_vreadf(struct p9_fcall *pdu, int proto_version, const char *fmt,
 			}
 			}
 			break;
 			break;
 		case 'R':{
 		case 'R':{
-				int16_t *nwqid = va_arg(ap, int16_t *);
+				uint16_t *nwqid = va_arg(ap, uint16_t *);
 				struct p9_qid **wqids =
 				struct p9_qid **wqids =
 				    va_arg(ap, struct p9_qid **);
 				    va_arg(ap, struct p9_qid **);
 
 
@@ -448,7 +448,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
 			}
 			}
 			break;
 			break;
 		case 'U':{
 		case 'U':{
-				int32_t count = va_arg(ap, int32_t);
+				uint32_t count = va_arg(ap, uint32_t);
 				const char __user *udata =
 				const char __user *udata =
 						va_arg(ap, const void __user *);
 						va_arg(ap, const void __user *);
 				errcode = p9pdu_writef(pdu, proto_version, "d",
 				errcode = p9pdu_writef(pdu, proto_version, "d",
@@ -479,7 +479,7 @@ p9pdu_vwritef(struct p9_fcall *pdu, int proto_version, const char *fmt,
 			}
 			}
 			break;
 			break;
 		case 'R':{
 		case 'R':{
-				int16_t nwqid = va_arg(ap, int);
+				uint16_t nwqid = va_arg(ap, int);
 				struct p9_qid *wqids =
 				struct p9_qid *wqids =
 				    va_arg(ap, struct p9_qid *);
 				    va_arg(ap, struct p9_qid *);