Re: [PATCH] dcache: error out on failures to store terminating NUL
On Fri, Jan 24, 2014 at 01:17:46PM +0100, Denys Vlasenko wrote: > A number of routines wasn't checking that the initial call > to prepend "\0" to result buffer doesn't fail. > > Coredump code was seeing d_path() with zero-sized buffer > to erroneously return bogus data (non-error pointer > pointing before buffer start). > > Users report that this change fixes it. NAK. Again, this is not dealing with overflows - it's basic sanity check on arguments. Choose which level should that be done at and just do it there. As in "if (!buflen) return -ENAMETOOLONG;". > char *cwd = page + PATH_MAX; > int buflen = PATH_MAX; > > - prepend(, , "\0", 1); > - error = prepend_path(, , , ); > + error = prepend(, , "\0", 1); > + if (!error) > + error = prepend_path(, , , ); Ah, yes - the dreadful case of zero PATH_MAX... -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] dcache: error out on failures to store terminating NUL
A number of routines wasn't checking that the initial call to prepend "\0" to result buffer doesn't fail. Coredump code was seeing d_path() with zero-sized buffer to erroneously return bogus data (non-error pointer pointing before buffer start). Users report that this change fixes it. Cc: Jan Kratochvil Cc: Oleg Nesterov Cc: linux-kernel@vger.kernel.org Signed-off-by: Denys Vlasenko --- fs/dcache.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 24a01fc..93f651b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2974,7 +2974,9 @@ char *__d_path(const struct path *path, char *res = buf + buflen; int error; - prepend(, , "\0", 1); + error = prepend(, , "\0", 1); + if (error) + return ERR_PTR(error); error = prepend_path(path, root, , ); if (error < 0) @@ -2991,7 +2993,9 @@ char *d_absolute_path(const struct path *path, char *res = buf + buflen; int error; - prepend(, , "\0", 1); + error = prepend(, , "\0", 1); + if (error) + return ERR_PTR(error); error = prepend_path(path, , , ); if (error > 1) @@ -3008,7 +3012,11 @@ static int path_with_deleted(const struct path *path, const struct path *root, char **buf, int *buflen) { - prepend(buf, buflen, "\0", 1); + int error; + + error = prepend(buf, buflen, "\0", 1); + if (error) + return error; if (d_unlinked(path->dentry)) { int error = prepend(buf, buflen, " (deleted)", 10); if (error) @@ -3126,12 +3134,12 @@ static char *__dentry_path(struct dentry *dentry, char *buf, int buflen) restart: end = buf + buflen; len = buflen; - prepend(, , "\0", 1); if (buflen < 1) { if (!(seq & 1)) rcu_read_unlock(); goto Elong; } + prepend(, , "\0", 1); /* Get '/' right */ retval = end-1; *retval = '/'; @@ -3235,8 +3243,9 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) char *cwd = page + PATH_MAX; int buflen = PATH_MAX; - prepend(, , "\0", 1); - error = prepend_path(, , , ); + error = prepend(, , "\0", 1); + if (!error) + error = prepend_path(, , , ); rcu_read_unlock(); if (error < 0) -- 1.8.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
[PATCH] dcache: error out on failures to store terminating NUL
A number of routines wasn't checking that the initial call to prepend \0 to result buffer doesn't fail. Coredump code was seeing d_path() with zero-sized buffer to erroneously return bogus data (non-error pointer pointing before buffer start). Users report that this change fixes it. Cc: Jan Kratochvil jan.kratoch...@redhat.com Cc: Oleg Nesterov o...@redhat.com Cc: linux-kernel@vger.kernel.org Signed-off-by: Denys Vlasenko dvlas...@redhat.com --- fs/dcache.c | 21 +++-- 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/fs/dcache.c b/fs/dcache.c index 24a01fc..93f651b 100644 --- a/fs/dcache.c +++ b/fs/dcache.c @@ -2974,7 +2974,9 @@ char *__d_path(const struct path *path, char *res = buf + buflen; int error; - prepend(res, buflen, \0, 1); + error = prepend(res, buflen, \0, 1); + if (error) + return ERR_PTR(error); error = prepend_path(path, root, res, buflen); if (error 0) @@ -2991,7 +2993,9 @@ char *d_absolute_path(const struct path *path, char *res = buf + buflen; int error; - prepend(res, buflen, \0, 1); + error = prepend(res, buflen, \0, 1); + if (error) + return ERR_PTR(error); error = prepend_path(path, root, res, buflen); if (error 1) @@ -3008,7 +3012,11 @@ static int path_with_deleted(const struct path *path, const struct path *root, char **buf, int *buflen) { - prepend(buf, buflen, \0, 1); + int error; + + error = prepend(buf, buflen, \0, 1); + if (error) + return error; if (d_unlinked(path-dentry)) { int error = prepend(buf, buflen, (deleted), 10); if (error) @@ -3126,12 +3134,12 @@ static char *__dentry_path(struct dentry *dentry, char *buf, int buflen) restart: end = buf + buflen; len = buflen; - prepend(end, len, \0, 1); if (buflen 1) { if (!(seq 1)) rcu_read_unlock(); goto Elong; } + prepend(end, len, \0, 1); /* Get '/' right */ retval = end-1; *retval = '/'; @@ -3235,8 +3243,9 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size) char *cwd = page + PATH_MAX; int buflen = PATH_MAX; - prepend(cwd, buflen, \0, 1); - error = prepend_path(pwd, root, cwd, buflen); + error = prepend(cwd, buflen, \0, 1); + if (!error) + error = prepend_path(pwd, root, cwd, buflen); rcu_read_unlock(); if (error 0) -- 1.8.1.4 -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
Re: [PATCH] dcache: error out on failures to store terminating NUL
On Fri, Jan 24, 2014 at 01:17:46PM +0100, Denys Vlasenko wrote: A number of routines wasn't checking that the initial call to prepend \0 to result buffer doesn't fail. Coredump code was seeing d_path() with zero-sized buffer to erroneously return bogus data (non-error pointer pointing before buffer start). Users report that this change fixes it. NAK. Again, this is not dealing with overflows - it's basic sanity check on arguments. Choose which level should that be done at and just do it there. As in if (!buflen) return -ENAMETOOLONG;. char *cwd = page + PATH_MAX; int buflen = PATH_MAX; - prepend(cwd, buflen, \0, 1); - error = prepend_path(pwd, root, cwd, buflen); + error = prepend(cwd, buflen, \0, 1); + if (!error) + error = prepend_path(pwd, root, cwd, buflen); Ah, yes - the dreadful case of zero PATH_MAX... -- To unsubscribe from this list: send the line unsubscribe linux-kernel in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/