diff options
author | Simon Derr <simon.derr@bull.net> | 2012-08-10 09:52:06 -0400 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2012-09-06 14:54:55 -0400 |
commit | 43def35c1030d91a7414936c7c1b416828b20afb (patch) | |
tree | 58e6a3f765f7319c91abf45978c34c60f188b9ee /net/9p | |
parent | ba413ab2ccc49e6aa1ebc3523a75635b5e4a0494 (diff) |
net/9p: Check errno validity
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>
Diffstat (limited to 'net/9p')
-rw-r--r-- | net/9p/client.c | 18 |
1 files changed, 16 insertions, 2 deletions
diff --git a/net/9p/client.c b/net/9p/client.c index 8260f132b32e..34d417670935 100644 --- a/net/9p/client.c +++ b/net/9p/client.c | |||
@@ -76,6 +76,20 @@ inline int p9_is_proto_dotu(struct p9_client *clnt) | |||
76 | } | 76 | } |
77 | EXPORT_SYMBOL(p9_is_proto_dotu); | 77 | EXPORT_SYMBOL(p9_is_proto_dotu); |
78 | 78 | ||
79 | /* | ||
80 | * Some error codes are taken directly from the server replies, | ||
81 | * make sure they are valid. | ||
82 | */ | ||
83 | static int safe_errno(int err) | ||
84 | { | ||
85 | if ((err > 0) || (err < -MAX_ERRNO)) { | ||
86 | p9_debug(P9_DEBUG_ERROR, "Invalid error code %d\n", err); | ||
87 | return -EPROTO; | ||
88 | } | ||
89 | return err; | ||
90 | } | ||
91 | |||
92 | |||
79 | /* Interpret mount option for protocol version */ | 93 | /* Interpret mount option for protocol version */ |
80 | static int get_protocol_version(char *s) | 94 | static int get_protocol_version(char *s) |
81 | { | 95 | { |
@@ -782,7 +796,7 @@ again: | |||
782 | return req; | 796 | return req; |
783 | reterr: | 797 | reterr: |
784 | p9_free_req(c, req); | 798 | p9_free_req(c, req); |
785 | return ERR_PTR(err); | 799 | return ERR_PTR(safe_errno(err)); |
786 | } | 800 | } |
787 | 801 | ||
788 | /** | 802 | /** |
@@ -865,7 +879,7 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type, | |||
865 | return req; | 879 | return req; |
866 | reterr: | 880 | reterr: |
867 | p9_free_req(c, req); | 881 | p9_free_req(c, req); |
868 | return ERR_PTR(err); | 882 | return ERR_PTR(safe_errno(err)); |
869 | } | 883 | } |
870 | 884 | ||
871 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) | 885 | static struct p9_fid *p9_fid_create(struct p9_client *clnt) |