From: Yu Watanabe Date: Thu, 20 Jul 2023 06:17:27 +0000 (+0900) Subject: chase: carefully handle result of extracting parent directory X-Git-Tag: v255-rc1~875^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4de5b4e3751609e6a0fe5e3f5dfef22ccae56fad;p=thirdparty%2Fsystemd.git chase: carefully handle result of extracting parent directory Should not change any behavior. --- diff --git a/src/basic/chase.c b/src/basic/chase.c index 4d883e18d8e..b612a2fef61 100644 --- a/src/basic/chase.c +++ b/src/basic/chase.c @@ -292,9 +292,25 @@ int chaseat(int dir_fd, const char *path, ChaseFlags flags, char **ret_path, int } r = path_extract_directory(done, &parent); - if (r >= 0 || r == -EDESTADDRREQ) + if (r >= 0) { + assert(!need_absolute || path_is_absolute(parent)); free_and_replace(done, parent); - else if (IN_SET(r, -EINVAL, -EADDRNOTAVAIL)) { + } else if (r == -EDESTADDRREQ) { + /* 'done' contains filename only (i.e. no slash). */ + assert(!need_absolute); + done = mfree(done); + } else if (r == -EADDRNOTAVAIL) { + /* 'done' is "/". This branch should be already handled in the above. */ + assert(!FLAGS_SET(flags, CHASE_AT_RESOLVE_IN_ROOT)); + assert_not_reached(); + } else if (r == -EINVAL) { + /* 'done' is an empty string, ends with '..', or an invalid path. */ + assert(!need_absolute); + assert(!FLAGS_SET(flags, CHASE_AT_RESOLVE_IN_ROOT)); + + if (!path_is_valid(done)) + return -EINVAL; + /* If we're at the top of "dir_fd", start appending ".." to "done". */ if (!path_extend(&done, "..")) return -ENOMEM;