[PATCH 05/14] getcwd(2): saner logics around prepend_path() call

From: Al Viro
Date: Tue May 18 2021 - 20:51:49 EST


The only negative value that might get returned by prepend_path() is
-ENAMETOOLONG, and that happens only on overflow. The same goes for
prepend_unreachable(). Overflow is detectable by observing negative
buflen, so we can simplify the control flow around the prepend_path()
call. Expand prepend_unreachable(), while we are at it - that's the
only caller.

Signed-off-by: Al Viro <viro@xxxxxxxxxxxxxxxxxx>
---
fs/d_path.c | 17 ++++-------------
1 file changed, 4 insertions(+), 13 deletions(-)

diff --git a/fs/d_path.c b/fs/d_path.c
index 7f3fac544bbb..311d43287572 100644
--- a/fs/d_path.c
+++ b/fs/d_path.c
@@ -211,11 +211,6 @@ char *d_absolute_path(const struct path *path,
return res;
}

-static int prepend_unreachable(char **buffer, int *buflen)
-{
- return prepend(buffer, buflen, "(unreachable)", 13);
-}
-
static void get_fs_root_rcu(struct fs_struct *fs, struct path *root)
{
unsigned seq;
@@ -414,17 +409,13 @@ SYSCALL_DEFINE2(getcwd, char __user *, buf, unsigned long, size)
int buflen = PATH_MAX;

prepend(&cwd, &buflen, "", 1);
- error = prepend_path(&pwd, &root, &cwd, &buflen);
+ if (prepend_path(&pwd, &root, &cwd, &buflen) > 0)
+ prepend(&cwd, &buflen, "(unreachable)", 13);
rcu_read_unlock();

- if (error < 0)
+ if (buflen < 0) {
+ error = -ENAMETOOLONG;
goto out;
-
- /* Unreachable from current root */
- if (error > 0) {
- error = prepend_unreachable(&cwd, &buflen);
- if (error)
- goto out;
}

error = -ERANGE;
--
2.11.0