blob: 3bf706fc55193188130a5fefb797107d60cedbf1 [file] [log] [blame]
Andrew Geisslerd159c7f2021-09-02 21:05:58 -05001From 88c8922f9e4d221402d9cb2e04b9c82e89125827 Mon Sep 17 00:00:00 2001
Brad Bishop19323692019-04-05 15:28:33 -04002From: Andre McCurdy <armccurdy@gmail.com>
3Date: Tue, 10 Oct 2017 14:33:30 -0700
William A. Kennington IIIac69b482021-06-02 12:28:27 -07004Subject: [PATCH] don't pass AT_SYMLINK_NOFOLLOW flag to faccessat()
Brad Bishop19323692019-04-05 15:28:33 -04005
6Avoid using AT_SYMLINK_NOFOLLOW flag. It doesn't seem like the right
7thing to do and it's not portable (not supported by musl). See:
8
9 http://lists.landley.net/pipermail/toybox-landley.net/2014-September/003610.html
10 http://www.openwall.com/lists/musl/2015/02/05/2
11
12Note that laccess() is never passing AT_EACCESS so a lot of the
13discussion in the links above doesn't apply. Note also that
14(currently) all systemd callers of laccess() pass mode as F_OK, so
15only check for existence of a file, not access permissions.
16Therefore, in this case, the only distiction between faccessat()
17with (flag == 0) and (flag == AT_SYMLINK_NOFOLLOW) is the behaviour
18for broken symlinks; laccess() on a broken symlink will succeed with
19(flag == AT_SYMLINK_NOFOLLOW) and fail (flag == 0).
20
21The laccess() macros was added to systemd some time ago and it's not
22clear if or why it needs to return success for broken symlinks. Maybe
23just historical and not actually necessary or desired behaviour?
24
25Upstream-Status: Inappropriate [musl specific]
26
27Signed-off-by: Andre McCurdy <armccurdy@gmail.com>
William A. Kennington IIIac69b482021-06-02 12:28:27 -070028
Brad Bishop19323692019-04-05 15:28:33 -040029---
William A. Kennington IIIac69b482021-06-02 12:28:27 -070030 src/basic/fs-util.h | 23 +++++++++++++++++++++--
Brad Bishop19323692019-04-05 15:28:33 -040031 src/shared/base-filesystem.c | 6 +++---
William A. Kennington IIIac69b482021-06-02 12:28:27 -070032 2 files changed, 24 insertions(+), 5 deletions(-)
Brad Bishop19323692019-04-05 15:28:33 -040033
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050034diff --git a/src/basic/fs-util.h b/src/basic/fs-util.h
35index 7f15b558ca..4263298cad 100644
Andrew Geisslerd1e89492021-02-12 15:35:20 -060036--- a/src/basic/fs-util.h
37+++ b/src/basic/fs-util.h
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050038@@ -47,8 +47,27 @@ int futimens_opath(int fd, const struct timespec ts[2]);
Brad Bishop19323692019-04-05 15:28:33 -040039 int fd_warn_permissions(const char *path, int fd);
Andrew Geissler635e0e42020-08-21 15:58:33 -050040 int stat_warn_permissions(const char *path, const struct stat *st);
Brad Bishop19323692019-04-05 15:28:33 -040041
William A. Kennington IIIac69b482021-06-02 12:28:27 -070042-#define laccess(path, mode) \
43- (faccessat(AT_FDCWD, (path), (mode), AT_SYMLINK_NOFOLLOW) < 0 ? -errno : 0)
Brad Bishop19323692019-04-05 15:28:33 -040044+/*
45+ Avoid using AT_SYMLINK_NOFOLLOW flag. It doesn't seem like the right thing to
46+ do and it's not portable (not supported by musl). See:
47+
48+ http://lists.landley.net/pipermail/toybox-landley.net/2014-September/003610.html
49+ http://www.openwall.com/lists/musl/2015/02/05/2
50+
51+ Note that laccess() is never passing AT_EACCESS so a lot of the discussion in
52+ the links above doesn't apply. Note also that (currently) all systemd callers
53+ of laccess() pass mode as F_OK, so only check for existence of a file, not
54+ access permissions. Therefore, in this case, the only distiction between
55+ faccessat() with (flag == 0) and (flag == AT_SYMLINK_NOFOLLOW) is the
56+ behaviour for broken symlinks; laccess() on a broken symlink will succeed
57+ with (flag == AT_SYMLINK_NOFOLLOW) and fail (flag == 0).
58+
59+ The laccess() macros was added to systemd some time ago and it's not clear if
60+ or why it needs to return success for broken symlinks. Maybe just historical
61+ and not actually necessary or desired behaviour?
62+*/
63+
64+#define laccess(path, mode) faccessat(AT_FDCWD, (path), (mode), 0)
65
66 int touch_file(const char *path, bool parents, usec_t stamp, uid_t uid, gid_t gid, mode_t mode);
67 int touch(const char *path);
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050068diff --git a/src/shared/base-filesystem.c b/src/shared/base-filesystem.c
69index 016eb7b82a..b1967f9f2f 100644
Andrew Geisslerd1e89492021-02-12 15:35:20 -060070--- a/src/shared/base-filesystem.c
71+++ b/src/shared/base-filesystem.c
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050072@@ -53,7 +53,7 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
Brad Bishop19323692019-04-05 15:28:33 -040073 return log_error_errno(errno, "Failed to open root file system: %m");
74
Patrick Williams213cb262021-08-07 19:21:33 -050075 for (size_t i = 0; i < ELEMENTSOF(table); i++) {
Brad Bishop19323692019-04-05 15:28:33 -040076- if (faccessat(fd, table[i].dir, F_OK, AT_SYMLINK_NOFOLLOW) >= 0)
77+ if (faccessat(fd, table[i].dir, F_OK, 0) >= 0)
78 continue;
79
80 if (table[i].target) {
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050081@@ -61,7 +61,7 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
Brad Bishop19323692019-04-05 15:28:33 -040082
83 /* check if one of the targets exists */
84 NULSTR_FOREACH(s, table[i].target) {
85- if (faccessat(fd, s, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
86+ if (faccessat(fd, s, F_OK, 0) < 0)
87 continue;
88
89 /* check if a specific file exists at the target path */
Andrew Geisslerd159c7f2021-09-02 21:05:58 -050090@@ -72,7 +72,7 @@ int base_filesystem_create(const char *root, uid_t uid, gid_t gid) {
Brad Bishop19323692019-04-05 15:28:33 -040091 if (!p)
92 return log_oom();
93
94- if (faccessat(fd, p, F_OK, AT_SYMLINK_NOFOLLOW) < 0)
95+ if (faccessat(fd, p, F_OK, 0) < 0)
96 continue;
97 }
98