diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-23 00:28:40 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2014-03-23 00:28:40 -0400 |
commit | e825196d48d2b89a6ec3a8eff280098d2a78207e (patch) | |
tree | 719a3ab8be442c786a9d5b02276ad8aaf989075a /fs/dcache.c | |
parent | 99aea68134f3c2a27b4d463c91cfa298c3efaccf (diff) |
make prepend_name() work correctly when called with negative *buflen
In all callchains leading to prepend_name(), the value left in *buflen
is eventually discarded unused if prepend_name() has returned a negative.
So we are free to do what prepend() does, and subtract from *buflen
*before* checking for underflow (which turns into checking the sign
of subtraction result, of course).
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/dcache.c')
-rw-r--r-- | fs/dcache.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/fs/dcache.c b/fs/dcache.c index 265e0ce9769c..ca02c13a84aa 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -2833,9 +2833,9 @@ static int prepend_name(char **buffer, int *buflen, struct qstr *name) | |||
2833 | u32 dlen = ACCESS_ONCE(name->len); | 2833 | u32 dlen = ACCESS_ONCE(name->len); |
2834 | char *p; | 2834 | char *p; |
2835 | 2835 | ||
2836 | if (*buflen < dlen + 1) | ||
2837 | return -ENAMETOOLONG; | ||
2838 | *buflen -= dlen + 1; | 2836 | *buflen -= dlen + 1; |
2837 | if (*buflen < 0) | ||
2838 | return -ENAMETOOLONG; | ||
2839 | p = *buffer -= dlen + 1; | 2839 | p = *buffer -= dlen + 1; |
2840 | *p++ = '/'; | 2840 | *p++ = '/'; |
2841 | while (dlen--) { | 2841 | while (dlen--) { |