Re: [PATCH] dcache: error out on failures to store terminating NUL

2014-01-24 Thread Al Viro
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

2014-01-24 Thread Denys Vlasenko
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

2014-01-24 Thread Denys Vlasenko
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

2014-01-24 Thread Al Viro
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/