Commit d06a8fb1 authored by Latchesar Ionkov's avatar Latchesar Ionkov Committed by Linus Torvalds

[PATCH] v9fs: make conv functions to check for conv buffer overflow

buf_check_size function checks if the conv buffer has enough space for the
performed operation, but it doesn't return the result back to the calling
function, only logs an error in the log.

The report-back-error functionality was lost when buf_check_size was
converted from macro to inline function. The return in the macro used to
exit from the functions that include it, after the conversion it just exits
from the inline function itself.

The patch makes buf_check_size to return flag and all functions that use
it check if they should perform the operation, or exit.
Signed-off-by: default avatarLatchesar Ionkov <lucho@ionkov.net>
Cc: Eric Van Hensbergen <ericvh@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 89559a61
...@@ -3,6 +3,7 @@ ...@@ -3,6 +3,7 @@
* *
* 9P protocol conversion functions * 9P protocol conversion functions
* *
* Copyright (C) 2004, 2005 by Latchesar Ionkov <lucho@ionkov.net>
* Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com> * Copyright (C) 2004 by Eric Van Hensbergen <ericvh@gmail.com>
* Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov> * Copyright (C) 2002 by Ron Minnich <rminnich@lanl.gov>
* *
...@@ -55,66 +56,70 @@ static inline int buf_check_overflow(struct cbuf *buf) ...@@ -55,66 +56,70 @@ static inline int buf_check_overflow(struct cbuf *buf)
return buf->p > buf->ep; return buf->p > buf->ep;
} }
static inline void buf_check_size(struct cbuf *buf, int len) static inline int buf_check_size(struct cbuf *buf, int len)
{ {
if (buf->p+len > buf->ep) { if (buf->p+len > buf->ep) {
if (buf->p < buf->ep) { if (buf->p < buf->ep) {
eprintk(KERN_ERR, "buffer overflow\n"); eprintk(KERN_ERR, "buffer overflow\n");
buf->p = buf->ep + 1; buf->p = buf->ep + 1;
return 0;
} }
} }
return 1;
} }
static inline void *buf_alloc(struct cbuf *buf, int len) static inline void *buf_alloc(struct cbuf *buf, int len)
{ {
void *ret = NULL; void *ret = NULL;
buf_check_size(buf, len); if (buf_check_size(buf, len)) {
ret = buf->p; ret = buf->p;
buf->p += len; buf->p += len;
}
return ret; return ret;
} }
static inline void buf_put_int8(struct cbuf *buf, u8 val) static inline void buf_put_int8(struct cbuf *buf, u8 val)
{ {
buf_check_size(buf, 1); if (buf_check_size(buf, 1)) {
buf->p[0] = val;
buf->p[0] = val; buf->p++;
buf->p++; }
} }
static inline void buf_put_int16(struct cbuf *buf, u16 val) static inline void buf_put_int16(struct cbuf *buf, u16 val)
{ {
buf_check_size(buf, 2); if (buf_check_size(buf, 2)) {
*(__le16 *) buf->p = cpu_to_le16(val);
*(__le16 *) buf->p = cpu_to_le16(val); buf->p += 2;
buf->p += 2; }
} }
static inline void buf_put_int32(struct cbuf *buf, u32 val) static inline void buf_put_int32(struct cbuf *buf, u32 val)
{ {
buf_check_size(buf, 4); if (buf_check_size(buf, 4)) {
*(__le32 *)buf->p = cpu_to_le32(val);
*(__le32 *)buf->p = cpu_to_le32(val); buf->p += 4;
buf->p += 4; }
} }
static inline void buf_put_int64(struct cbuf *buf, u64 val) static inline void buf_put_int64(struct cbuf *buf, u64 val)
{ {
buf_check_size(buf, 8); if (buf_check_size(buf, 8)) {
*(__le64 *)buf->p = cpu_to_le64(val);
*(__le64 *)buf->p = cpu_to_le64(val); buf->p += 8;
buf->p += 8; }
} }
static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen) static inline void buf_put_stringn(struct cbuf *buf, const char *s, u16 slen)
{ {
buf_check_size(buf, slen + 2); if (buf_check_size(buf, slen + 2)) {
buf_put_int16(buf, slen);
buf_put_int16(buf, slen); memcpy(buf->p, s, slen);
memcpy(buf->p, s, slen); buf->p += slen;
buf->p += slen; }
} }
static inline void buf_put_string(struct cbuf *buf, const char *s) static inline void buf_put_string(struct cbuf *buf, const char *s)
...@@ -124,20 +129,20 @@ static inline void buf_put_string(struct cbuf *buf, const char *s) ...@@ -124,20 +129,20 @@ static inline void buf_put_string(struct cbuf *buf, const char *s)
static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen) static inline void buf_put_data(struct cbuf *buf, void *data, u32 datalen)
{ {
buf_check_size(buf, datalen); if (buf_check_size(buf, datalen)) {
memcpy(buf->p, data, datalen);
memcpy(buf->p, data, datalen); buf->p += datalen;
buf->p += datalen; }
} }
static inline u8 buf_get_int8(struct cbuf *buf) static inline u8 buf_get_int8(struct cbuf *buf)
{ {
u8 ret = 0; u8 ret = 0;
buf_check_size(buf, 1); if (buf_check_size(buf, 1)) {
ret = buf->p[0]; ret = buf->p[0];
buf->p++;
buf->p++; }
return ret; return ret;
} }
...@@ -146,10 +151,10 @@ static inline u16 buf_get_int16(struct cbuf *buf) ...@@ -146,10 +151,10 @@ static inline u16 buf_get_int16(struct cbuf *buf)
{ {
u16 ret = 0; u16 ret = 0;
buf_check_size(buf, 2); if (buf_check_size(buf, 2)) {
ret = le16_to_cpu(*(__le16 *)buf->p); ret = le16_to_cpu(*(__le16 *)buf->p);
buf->p += 2;
buf->p += 2; }
return ret; return ret;
} }
...@@ -158,10 +163,10 @@ static inline u32 buf_get_int32(struct cbuf *buf) ...@@ -158,10 +163,10 @@ static inline u32 buf_get_int32(struct cbuf *buf)
{ {
u32 ret = 0; u32 ret = 0;
buf_check_size(buf, 4); if (buf_check_size(buf, 4)) {
ret = le32_to_cpu(*(__le32 *)buf->p); ret = le32_to_cpu(*(__le32 *)buf->p);
buf->p += 4;
buf->p += 4; }
return ret; return ret;
} }
...@@ -170,10 +175,10 @@ static inline u64 buf_get_int64(struct cbuf *buf) ...@@ -170,10 +175,10 @@ static inline u64 buf_get_int64(struct cbuf *buf)
{ {
u64 ret = 0; u64 ret = 0;
buf_check_size(buf, 8); if (buf_check_size(buf, 8)) {
ret = le64_to_cpu(*(__le64 *)buf->p); ret = le64_to_cpu(*(__le64 *)buf->p);
buf->p += 8;
buf->p += 8; }
return ret; return ret;
} }
...@@ -181,27 +186,35 @@ static inline u64 buf_get_int64(struct cbuf *buf) ...@@ -181,27 +186,35 @@ static inline u64 buf_get_int64(struct cbuf *buf)
static inline int static inline int
buf_get_string(struct cbuf *buf, char *data, unsigned int datalen) buf_get_string(struct cbuf *buf, char *data, unsigned int datalen)
{ {
u16 len = 0;
len = buf_get_int16(buf);
if (!buf_check_overflow(buf) && buf_check_size(buf, len) && len+1>datalen) {
memcpy(data, buf->p, len);
data[len] = 0;
buf->p += len;
len++;
}
u16 len = buf_get_int16(buf); return len;
buf_check_size(buf, len);
if (len + 1 > datalen)
return 0;
memcpy(data, buf->p, len);
data[len] = 0;
buf->p += len;
return len + 1;
} }
static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
{ {
char *ret = NULL; char *ret;
int n = buf_get_string(buf, sbuf->p, sbuf->ep - sbuf->p); u16 len;
ret = NULL;
len = buf_get_int16(buf);
if (n > 0) { if (!buf_check_overflow(buf) && buf_check_size(buf, len) &&
buf_check_size(sbuf, len+1)) {
memcpy(sbuf->p, buf->p, len);
sbuf->p[len] = 0;
ret = sbuf->p; ret = sbuf->p;
sbuf->p += n; buf->p += len;
sbuf->p += len + 1;
} }
return ret; return ret;
...@@ -209,12 +222,15 @@ static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf) ...@@ -209,12 +222,15 @@ static inline char *buf_get_stringb(struct cbuf *buf, struct cbuf *sbuf)
static inline int buf_get_data(struct cbuf *buf, void *data, int datalen) static inline int buf_get_data(struct cbuf *buf, void *data, int datalen)
{ {
buf_check_size(buf, datalen); int ret = 0;
memcpy(data, buf->p, datalen); if (buf_check_size(buf, datalen)) {
buf->p += datalen; memcpy(data, buf->p, datalen);
buf->p += datalen;
ret = datalen;
}
return datalen; return ret;
} }
static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
...@@ -223,13 +239,12 @@ static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf, ...@@ -223,13 +239,12 @@ static inline void *buf_get_datab(struct cbuf *buf, struct cbuf *dbuf,
char *ret = NULL; char *ret = NULL;
int n = 0; int n = 0;
buf_check_size(dbuf, datalen); if (buf_check_size(dbuf, datalen)) {
n = buf_get_data(buf, dbuf->p, datalen);
n = buf_get_data(buf, dbuf->p, datalen); if (n > 0) {
ret = dbuf->p;
if (n > 0) { dbuf->p += n;
ret = dbuf->p; }
dbuf->p += n;
} }
return ret; return ret;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment