diff options
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/btrfs-util.c | 5 | ||||
-rw-r--r-- | src/basic/io-util.h | 18 | ||||
-rw-r--r-- | src/basic/nss-util.h | 2 | ||||
-rw-r--r-- | src/basic/signal-util.h | 11 | ||||
-rw-r--r-- | src/basic/unit-name.c | 45 |
5 files changed, 70 insertions, 11 deletions
diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index d07d1df5a8..03c7609c92 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -43,6 +43,7 @@ #include "copy.h" #include "fd-util.h" #include "fileio.h" +#include "io-util.h" #include "macro.h" #include "missing.h" #include "path-util.h" @@ -913,6 +914,10 @@ int btrfs_resize_loopback_fd(int fd, uint64_t new_size, bool grow_only) { dev_t dev = 0; int r; + /* In contrast to btrfs quota ioctls ftruncate() cannot make sense of "infinity" or file sizes > 2^31 */ + if (!FILE_SIZE_VALID(new_size)) + return -EINVAL; + /* btrfs cannot handle file systems < 16M, hence use this as minimum */ if (new_size < 16*1024*1024) new_size = 16*1024*1024; diff --git a/src/basic/io-util.h b/src/basic/io-util.h index 5f77a556c0..7d0d2bd810 100644 --- a/src/basic/io-util.h +++ b/src/basic/io-util.h @@ -77,3 +77,21 @@ static inline size_t IOVEC_INCREMENT(struct iovec *i, unsigned n, size_t k) { return k; } + +static inline bool FILE_SIZE_VALID(uint64_t l) { + /* ftruncate() and friends take an unsigned file size, but actually cannot deal with file sizes larger than + * 2^63 since the kernel internally handles it as signed value. This call allows checking for this early. */ + + return (l >> 63) == 0; +} + +static inline bool FILE_SIZE_VALID_OR_INFINITY(uint64_t l) { + + /* Same as above, but allows one extra value: -1 as indication for infinity. */ + + if (l == (uint64_t) -1) + return true; + + return FILE_SIZE_VALID(l); + +} diff --git a/src/basic/nss-util.h b/src/basic/nss-util.h index cc30d93aad..4be0136da6 100644 --- a/src/basic/nss-util.h +++ b/src/basic/nss-util.h @@ -27,6 +27,8 @@ #include <pwd.h> #include <resolv.h> +#define NSS_SIGNALS_BLOCK SIGALRM,SIGVTALRM,SIGPIPE,SIGCHLD,SIGTSTP,SIGIO,SIGHUP,SIGUSR1,SIGUSR2,SIGPROF,SIGURG,SIGWINCH + #define NSS_GETHOSTBYNAME_PROTOTYPES(module) \ enum nss_status _nss_##module##_gethostbyname4_r( \ const char *name, \ diff --git a/src/basic/signal-util.h b/src/basic/signal-util.h index e7393e2dac..5d94d1c363 100644 --- a/src/basic/signal-util.h +++ b/src/basic/signal-util.h @@ -41,3 +41,14 @@ int signal_from_string(const char *s) _pure_; int signal_from_string_try_harder(const char *s); void nop_signal_handler(int sig); + +static inline void block_signals_reset(sigset_t *ss) { + assert_se(sigprocmask(SIG_SETMASK, ss, NULL) >= 0); +} + +#define BLOCK_SIGNALS(...) \ + _cleanup_(block_signals_reset) sigset_t _saved_sigset = ({ \ + sigset_t t; \ + assert_se(sigprocmask_many(SIG_BLOCK, &t, __VA_ARGS__, -1) >= 0); \ + t; \ + }) diff --git a/src/basic/unit-name.c b/src/basic/unit-name.c index 5fc3b9d6fd..d4a3062658 100644 --- a/src/basic/unit-name.c +++ b/src/basic/unit-name.c @@ -27,6 +27,7 @@ #include "alloc-util.h" #include "bus-label.h" +#include "glob-util.h" #include "hexdecoct.h" #include "macro.h" #include "path-util.h" @@ -35,10 +36,22 @@ #include "strv.h" #include "unit-name.h" +/* Characters valid in a unit name. */ #define VALID_CHARS \ - DIGITS LETTERS \ + DIGITS \ + LETTERS \ ":-_.\\" +/* The same, but also permits the single @ character that may appear */ +#define VALID_CHARS_WITH_AT \ + "@" \ + VALID_CHARS + +/* All chars valid in a unit name glob */ +#define VALID_CHARS_GLOB \ + VALID_CHARS_WITH_AT \ + "[]!-*?" + bool unit_name_is_valid(const char *n, UnitNameFlags flags) { const char *e, *i, *at; @@ -637,7 +650,7 @@ static char *do_escape_mangle(const char *f, UnitNameMangle allow_globs, char *t /* We'll only escape the obvious characters here, to play * safe. */ - valid_chars = allow_globs == UNIT_NAME_GLOB ? "@" VALID_CHARS "[]!-*?" : "@" VALID_CHARS; + valid_chars = allow_globs == UNIT_NAME_GLOB ? VALID_CHARS_GLOB : VALID_CHARS_WITH_AT; for (; *f; f++) { if (*f == '/') @@ -672,15 +685,15 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, c if (!unit_suffix_is_valid(suffix)) return -EINVAL; - if (unit_name_is_valid(name, UNIT_NAME_ANY)) { - /* No mangling necessary... */ - s = strdup(name); - if (!s) - return -ENOMEM; + /* Already a fully valid unit name? If so, no mangling is necessary... */ + if (unit_name_is_valid(name, UNIT_NAME_ANY)) + goto good; - *ret = s; - return 0; - } + /* Already a fully valid globbing expression? If so, no mangling is necessary either... */ + if (allow_globs == UNIT_NAME_GLOB && + string_is_glob(name) && + in_charset(name, VALID_CHARS_GLOB)) + goto good; if (is_device_path(name)) { r = unit_name_from_path(name, ".device", ret); @@ -705,11 +718,21 @@ int unit_name_mangle_with_suffix(const char *name, UnitNameMangle allow_globs, c t = do_escape_mangle(name, allow_globs, s); *t = 0; - if (unit_name_to_type(s) < 0) + /* Append a suffix if it doesn't have any, but only if this is not a glob, so that we can allow "foo.*" as a + * valid glob. */ + if ((allow_globs != UNIT_NAME_GLOB || !string_is_glob(s)) && unit_name_to_type(s) < 0) strcpy(t, suffix); *ret = s; return 1; + +good: + s = strdup(name); + if (!s) + return -ENOMEM; + + *ret = s; + return 0; } int slice_build_parent_slice(const char *slice, char **ret) { |