From 1d0106996c2f80cdd0510206b9fd2d81d3fcd0cc Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 1 Feb 2017 20:02:17 +0100 Subject: [PATCH 1/3] update TODO --- TODO | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/TODO b/TODO index c06a47b7ea..2004c394be 100644 --- a/TODO +++ b/TODO @@ -24,6 +24,13 @@ Janitorial Clean-ups: Features: +* journald: when we recv a log datagram via the native or syslog transports, + search for the PID in the active stream connections, and let's make sure to + always process the datagrams before the streams. Then, cache client metadata + per stream in the stream object. This way we can somewhat fix the race with + quickly exiting processes which log as long as they had their own stream + connection... + * Maybe add a small tool invoked early at boot, that adds in or resizes partitions automatically, to be used when the media used is actually larger than the image written onto it is. From 49bfc8774bf900fb2239a9b70b951aedccbfed5a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 2 Feb 2017 00:06:18 +0100 Subject: [PATCH 2/3] fs-util: unify code we use to check if dirent's d_name is "." or ".." We use different idioms at different places. Let's replace this is the one true new idiom, that is even a bit faster... --- src/basic/cgroup-util.c | 3 +-- src/basic/copy.c | 2 +- src/basic/path-util.c | 25 ++++++++++++++++----- src/basic/path-util.h | 2 ++ src/basic/rm-rf.c | 2 +- src/basic/socket-util.c | 2 +- src/gpt-auto-generator/gpt-auto-generator.c | 2 +- src/nspawn/nspawn-patch-uid.c | 2 +- src/resolve/resolved-manager.c | 2 +- src/shared/clean-ipc.c | 4 ++-- src/test/test-fs-util.c | 11 +++++++++ src/tmpfiles/tmpfiles.c | 6 ++--- 12 files changed, 43 insertions(+), 20 deletions(-) diff --git a/src/basic/cgroup-util.c b/src/basic/cgroup-util.c index d2d18f13f0..6948ed3931 100644 --- a/src/basic/cgroup-util.c +++ b/src/basic/cgroup-util.c @@ -182,8 +182,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 9883f5fa31..e9a7efd232 100644 --- a/src/basic/copy.c +++ b/src/basic/copy.c @@ -331,7 +331,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 9a51e0d8bc..1313a52c9c 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -699,10 +699,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, '/'); @@ -720,14 +717,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, "//")) @@ -892,3 +892,16 @@ int systemd_installation_has_version(const char *root, unsigned minimal_version) return false; } + +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 349cdac7d6..35aef3adc8 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -141,3 +141,5 @@ bool is_device_path(const char *path); bool is_deviceallow_pattern(const char *path); int systemd_installation_has_version(const char *root, unsigned minimal_version); + +bool dot_or_dot_dot(const char *path); diff --git a/src/basic/rm-rf.c b/src/basic/rm-rf.c index 07d42f78dd..08497af729 100644 --- a/src/basic/rm-rf.c +++ b/src/basic/rm-rf.c @@ -83,7 +83,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 77f81a60ba..17e90a8994 100644 --- a/src/basic/socket-util.c +++ b/src/basic/socket-util.c @@ -877,7 +877,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/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index e61ef8f249..b958070c90 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -658,7 +658,7 @@ static int get_block_device_harder(const char *path, dev_t *dev) { FOREACH_DIRENT_ALL(de, d, return -errno) { - if (STR_IN_SET(de->d_name, ".", "..")) + if (dot_or_dot_dot(de->d_name)) continue; if (!IN_SET(de->d_type, DT_LNK, DT_UNKNOWN)) diff --git a/src/nspawn/nspawn-patch-uid.c b/src/nspawn/nspawn-patch-uid.c index ded5866d05..1a3f129db0 100644 --- a/src/nspawn/nspawn-patch-uid.c +++ b/src/nspawn/nspawn-patch-uid.c @@ -375,7 +375,7 @@ static int recurse_fd(int fd, bool donate_fd, const struct stat *st, uid_t shift FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) { struct stat fst; - if (STR_IN_SET(de->d_name, ".", "..")) + if (dot_or_dot_dot(de->d_name)) continue; if (fstatat(dirfd(d), de->d_name, &fst, AT_SYMLINK_NOFOLLOW) < 0) { diff --git a/src/resolve/resolved-manager.c b/src/resolve/resolved-manager.c index 0954641c20..667774b906 100644 --- a/src/resolve/resolved-manager.c +++ b/src/resolve/resolved-manager.c @@ -1349,7 +1349,7 @@ void manager_cleanup_saved_user(Manager *m) { if (!IN_SET(de->d_type, DT_UNKNOWN, DT_REG)) continue; - if (STR_IN_SET(de->d_name, ".", "..")) + if (dot_or_dot_dot(de->d_name)) continue; r = parse_ifindex(de->d_name, &ifindex); diff --git a/src/shared/clean-ipc.c b/src/shared/clean-ipc.c index f2d1555c13..f59f6f23ae 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) { @@ -310,7 +310,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) { diff --git a/src/test/test-fs-util.c b/src/test/test-fs-util.c index 4cb465d0d2..e774f567e0 100644 --- a/src/test/test-fs-util.c +++ b/src/test/test-fs-util.c @@ -305,12 +305,23 @@ static void test_var_tmp(void) { } } +static void test_dot_or_dot_dot(void) { + assert_se(!dot_or_dot_dot(NULL)); + assert_se(!dot_or_dot_dot("")); + assert_se(!dot_or_dot_dot("xxx")); + assert_se(dot_or_dot_dot(".")); + assert_se(dot_or_dot_dot("..")); + assert_se(!dot_or_dot_dot(".foo")); + assert_se(!dot_or_dot_dot("..foo")); +} + int main(int argc, char *argv[]) { test_unlink_noerrno(); test_readlink_and_make_absolute(); test_get_files_in_directory(); test_var_tmp(); test_chase_symlinks(); + test_dot_or_dot_dot(); return 0; } diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index f4ce9791fb..c4f4d46ca1 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -385,7 +385,7 @@ static int dir_cleanup( usec_t age; _cleanup_free_ char *sub_path = NULL; - if (STR_IN_SET(dent->d_name, ".", "..")) + if (dot_or_dot_dot(dent->d_name)) continue; if (fstatat(dirfd(d), dent->d_name, &s, AT_SYMLINK_NOFOLLOW) < 0) { @@ -1070,9 +1070,7 @@ static int item_do_children(Item *i, const char *path, action_t action) { _cleanup_free_ char *p = NULL; int q; - errno = 0; - - if (STR_IN_SET(de->d_name, ".", "..")) + if (dot_or_dot_dot(de->d_name)) continue; p = strjoin(path, "/", de->d_name); From 9ff233dc1fa2f47fc4499a12a8ee0640aba30657 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 2 Feb 2017 00:10:44 +0100 Subject: [PATCH 3/3] hexdecoct: use typesafe new() instead of malloc() --- src/basic/hexdecoct.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/basic/hexdecoct.c b/src/basic/hexdecoct.c index 6843aedd0a..2d6e377f0a 100644 --- a/src/basic/hexdecoct.c +++ b/src/basic/hexdecoct.c @@ -72,10 +72,10 @@ int unhexchar(char c) { } char *hexmem(const void *p, size_t l) { - char *r, *z; const uint8_t *x; + char *r, *z; - z = r = malloc(l * 2 + 1); + z = r = new(char, l * 2 + 1); if (!r) return NULL;