diff options
author | Simon Derr <simon.derr@bull.net> | 2012-08-10 15:52:06 +0200 |
---|---|---|
committer | Eric Van Hensbergen <ericvh@gmail.com> | 2012-09-06 13:54:55 -0500 |
commit | 43def35c1030d91a7414936c7c1b416828b20afb (patch) | |
tree | 58e6a3f765f7319c91abf45978c34c60f188b9ee /net/9p | |
parent | ba413ab2ccc49e6aa1ebc3523a75635b5e4a0494 (diff) | |
download | linux-43def35c1030d91a7414936c7c1b416828b20afb.tar.gz linux-43def35c1030d91a7414936c7c1b416828b20afb.tar.bz2 linux-43def35c1030d91a7414936c7c1b416828b20afb.zip |
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) } 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) |