From 941f374947c8db8311bbde1bba478749d455be43 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 4 Jan 2018 20:00:28 +0100 Subject: fs-util: add new chase_symlinks() flag CHASE_OPEN The new flag returns the O_PATH fd of the final component, which may be converted into a proper fd by open()ing it again through the /proc/self/fd/xyz path. Together with O_SAFE this provides us with a somewhat safe way to open() files in directories potentially owned by unprivileged code, where we want to refuse operation if any symlink tricks are played pointing to privileged files. --- src/test/test-fs-util.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'src/test/test-fs-util.c') diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 1c453e11a..22aa64f4c 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -22,12 +22,15 @@ #include "alloc-util.h" #include "fd-util.h" +//#include "fd-util.h" #include "fileio.h" #include "fs-util.h" +//#include "id128-util.h" #include "macro.h" #include "mkdir.h" #include "path-util.h" #include "rm-rf.h" +//#include "stdio-util.h" #include "string-util.h" #include "strv.h" //#include "user-util.h" @@ -37,7 +40,7 @@ static void test_chase_symlinks(void) { _cleanup_free_ char *result = NULL; char temp[] = "/tmp/test-chase.XXXXXX"; const char *top, *p, *pslash, *q, *qslash; - int r; + int r, pfd; assert_se(mkdtemp(temp)); @@ -262,6 +265,29 @@ static void test_chase_symlinks(void) { assert_se(chase_symlinks(q, NULL, CHASE_SAFE, NULL) >= 0); } + p = strjoina(temp, "/machine-id-test"); + assert_se(symlink("/usr/../etc/./machine-id", p) >= 0); + + pfd = chase_symlinks(p, NULL, CHASE_OPEN, NULL); + if (pfd != -ENOENT) { + char procfs[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(pfd) + 1]; + _cleanup_close_ int fd = -1; + sd_id128_t a, b; + + assert_se(pfd >= 0); + + xsprintf(procfs, "/proc/self/fd/%i", pfd); + + fd = open(procfs, O_RDONLY|O_CLOEXEC); + assert_se(fd >= 0); + + safe_close(pfd); + + assert_se(id128_read_fd(fd, ID128_PLAIN, &a) >= 0); + assert_se(sd_id128_get_machine(&b) >= 0); + assert_se(sd_id128_equal(a, b)); + } + assert_se(rm_rf(temp, REMOVE_ROOT|REMOVE_PHYSICAL) >= 0); } -- cgit v1.2.3