net/9p: Check errno validity
authorSimon Derr <simon.derr@bull.net>
Fri, 10 Aug 2012 13:52:06 +0000 (15:52 +0200)
committerEric Van Hensbergen <ericvh@gmail.com>
Thu, 6 Sep 2012 18:54:55 +0000 (13:54 -0500)
While working on a modified server I had the Linux clients crash
a few times. This lead me to find this:

Some error codes are directly extracted from the server replies.
A malformed server reply could contain an invalid error code, with a
very large value. If this value is then passed to ERR_PTR() it will
not be properly detected as an error code by IS_ERR() and as a result
the kernel will dereference an invalid pointer.

This patch tries to avoid this.

Signed-off-by: Simon Derr <simon.derr@bull.net>
Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
net/9p/client.c

index 8260f132b32e0a9d706c38b0969d0879a3f6bf94..34d41767093500ba7cda60a2a1990ede456f35bd 100644 (file)
@@ -76,6 +76,20 @@ inline int p9_is_proto_dotu(struct p9_client *clnt)
 }
 EXPORT_SYMBOL(p9_is_proto_dotu);
 
+/*
+ * Some error codes are taken directly from the server replies,
+ * make sure they are valid.
+ */
+static int safe_errno(int err)
+{
+       if ((err > 0) || (err < -MAX_ERRNO)) {
+               p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err);
+               return -EPROTO;
+       }
+       return err;
+}
+
+
 /* Interpret mount option for protocol version */
 static int get_protocol_version(char *s)
 {
@@ -782,7 +796,7 @@ again:
                return req;
 reterr:
        p9_free_req(c, req);
-       return ERR_PTR(err);
+       return ERR_PTR(safe_errno(err));
 }
 
 /**
@@ -865,7 +879,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
                return req;
 reterr:
        p9_free_req(c, req);
-       return ERR_PTR(err);
+       return ERR_PTR(safe_errno(err));
 }
 
 static struct p9_fid *p9_fid_create(struct p9_client *clnt)