summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/basic/cgroup-util.c3
-rw-r--r--src/basic/copy.c2
-rw-r--r--src/basic/path-util.c25
-rw-r--r--src/basic/path-util.h2
-rw-r--r--src/basic/rm-rf.c2
-rw-r--r--src/basic/socket-util.c2
-rw-r--r--src/shared/clean-ipc.c4
7 files changed, 27 insertions, 13 deletions
diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c
index 0e2f2cbc0..32cf4298f 100644
--- a/src/basic/cgroup-util.c
+++ b/src/basic/cgroup-util.c
@@ -184,8 +184,7 @@ int cg_read_subgroup(DIR *d, char **fn) {
if (de->d_type != DT_DIR)
continue;
- if (streq(de->d_name, ".") ||
- streq(de->d_name, ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
b = strdup(de->d_name);
diff --git a/src/basic/copy.c b/src/basic/copy.c
index 4e5f392fe..20078a81e 100644
--- a/src/basic/copy.c
+++ b/src/basic/copy.c
@@ -333,7 +333,7 @@ static int fd_copy_directory(
struct stat buf;
int q;
- if (STR_IN_SET(de->d_name, ".", ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
diff --git a/src/basic/path-util.c b/src/basic/path-util.c
index 84f327d7d..05384c26b 100644
--- a/src/basic/path-util.c
+++ b/src/basic/path-util.c
@@ -703,10 +703,7 @@ bool filename_is_valid(const char *p) {
if (isempty(p))
return false;
- if (streq(p, "."))
- return false;
-
- if (streq(p, ".."))
+ if (dot_or_dot_dot(p))
return false;
e = strchrnul(p, '/');
@@ -724,14 +721,17 @@ bool path_is_safe(const char *p) {
if (isempty(p))
return false;
- if (streq(p, "..") || startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
+ if (dot_or_dot_dot(p))
+ return false;
+
+ if (startswith(p, "../") || endswith(p, "/..") || strstr(p, "/../"))
return false;
if (strlen(p)+1 > PATH_MAX)
return false;
/* The following two checks are not really dangerous, but hey, they still are confusing */
- if (streq(p, ".") || startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
+ if (startswith(p, "./") || endswith(p, "/.") || strstr(p, "/./"))
return false;
if (strstr(p, "//"))
@@ -898,3 +898,16 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version)
return false;
}
#endif // 0
+
+bool dot_or_dot_dot(const char *path) {
+ if (!path)
+ return false;
+ if (path[0] != '.')
+ return false;
+ if (path[1] == 0)
+ return true;
+ if (path[1] != '.')
+ return false;
+
+ return path[2] == 0;
+}
diff --git a/src/basic/path-util.h b/src/basic/path-util.h
index 6c906e54a..3e1519efe 100644
--- a/src/basic/path-util.h
+++ b/src/basic/path-util.h
@@ -157,3 +157,5 @@ bool is_deviceallow_pattern(const char *path);
int systemd_installation_has_version(const char *root, unsigned minimal_version);
#endif // 0
+
+bool dot_or_dot_dot(const char *path);
diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c
index a90359194..85854acf9 100644
--- a/src/basic/rm-rf.c
+++ b/src/basic/rm-rf.c
@@ -82,7 +82,7 @@ int rm_rf_children(int fd, RemoveFlags flags, struct stat *root_dev) {
bool is_dir;
struct stat st;
- if (streq(de->d_name, ".") || streq(de->d_name, ".."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (de->d_type == DT_UNKNOWN ||
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 6a8ca1d7e..9ec901261 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -881,7 +881,7 @@ bool ifname_valid(const char *p) {
if (strlen(p) >= IFNAMSIZ)
return false;
- if (STR_IN_SET(p, ".", ".."))
+ if (dot_or_dot_dot(p))
return false;
while (*p) {
diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c
index ba48fb0ec..3b4231827 100644
--- a/src/shared/clean-ipc.c
+++ b/src/shared/clean-ipc.c
@@ -225,7 +225,7 @@ static int clean_posix_shm_internal(DIR *dir, uid_t uid, gid_t gid) {
FOREACH_DIRENT_ALL(de, dir, goto fail) {
struct stat st;
- if (STR_IN_SET(de->d_name, "..", "."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
@@ -311,7 +311,7 @@ static int clean_posix_mq(uid_t uid, gid_t gid) {
struct stat st;
char fn[1+strlen(de->d_name)+1];
- if (STR_IN_SET(de->d_name, "..", "."))
+ if (dot_or_dot_dot(de->d_name))
continue;
if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {