mirror of
https://github.com/systemd/systemd.git
synced 2024-10-29 21:55:36 +03:00
Merge pull request #14218 from poettering/homed-preparatory-small-stuff
Assorted smaller stuff split out from homed PR
This commit is contained in:
commit
f9f8268ac6
@ -101,3 +101,11 @@ static inline bool ERRNO_IS_PRIVILEGE(int r) {
|
||||
EACCES,
|
||||
EPERM);
|
||||
}
|
||||
|
||||
/* Three difference errors for "not enough disk space" */
|
||||
static inline bool ERRNO_IS_DISK_SPACE(int r) {
|
||||
return IN_SET(abs(r),
|
||||
ENOSPC,
|
||||
EDQUOT,
|
||||
EFBIG);
|
||||
}
|
||||
|
@ -80,14 +80,21 @@ static inline void* explicit_bzero_safe(void *p, size_t l) {
|
||||
void *explicit_bzero_safe(void *p, size_t l);
|
||||
#endif
|
||||
|
||||
static inline void erase_and_freep(void *p) {
|
||||
void *ptr = *(void**) p;
|
||||
static inline void* erase_and_free(void *p) {
|
||||
size_t l;
|
||||
|
||||
if (ptr) {
|
||||
size_t l = malloc_usable_size(ptr);
|
||||
explicit_bzero_safe(ptr, l);
|
||||
free(ptr);
|
||||
}
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
l = malloc_usable_size(p);
|
||||
explicit_bzero_safe(p, l);
|
||||
free(p);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline void erase_and_freep(void *p) {
|
||||
erase_and_free(*(void**) p);
|
||||
}
|
||||
|
||||
/* Use with _cleanup_ to erase a single 'char' when leaving scope */
|
||||
|
@ -50,6 +50,10 @@ static inline void* ordered_set_remove(OrderedSet *s, void *p) {
|
||||
return ordered_hashmap_remove((OrderedHashmap*) s, p);
|
||||
}
|
||||
|
||||
static inline void* ordered_set_first(OrderedSet *s) {
|
||||
return ordered_hashmap_first((OrderedHashmap*) s);
|
||||
}
|
||||
|
||||
static inline void* ordered_set_steal_first(OrderedSet *s) {
|
||||
return ordered_hashmap_steal_first((OrderedHashmap*) s);
|
||||
}
|
||||
|
@ -365,7 +365,6 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret_u);
|
||||
assert(base <= 16);
|
||||
|
||||
/* strtoul() is happy to parse negative values, and silently
|
||||
@ -389,7 +388,9 @@ int safe_atou_full(const char *s, unsigned base, unsigned *ret_u) {
|
||||
if ((unsigned long) (unsigned) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
*ret_u = (unsigned) l;
|
||||
if (ret_u)
|
||||
*ret_u = (unsigned) l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -398,7 +399,6 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret_i);
|
||||
|
||||
errno = 0;
|
||||
l = strtol(s, &x, 0);
|
||||
@ -409,7 +409,9 @@ int safe_atoi(const char *s, int *ret_i) {
|
||||
if ((long) (int) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
*ret_i = (int) l;
|
||||
if (ret_i)
|
||||
*ret_i = (int) l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -418,7 +420,6 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
unsigned long long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret_llu);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
@ -431,7 +432,9 @@ int safe_atollu(const char *s, long long unsigned *ret_llu) {
|
||||
if (*s == '-')
|
||||
return -ERANGE;
|
||||
|
||||
*ret_llu = l;
|
||||
if (ret_llu)
|
||||
*ret_llu = l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -440,7 +443,6 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
long long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret_lli);
|
||||
|
||||
errno = 0;
|
||||
l = strtoll(s, &x, 0);
|
||||
@ -449,7 +451,9 @@ int safe_atolli(const char *s, long long int *ret_lli) {
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*ret_lli = l;
|
||||
if (ret_lli)
|
||||
*ret_lli = l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -458,7 +462,6 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||
unsigned long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret);
|
||||
|
||||
s += strspn(s, WHITESPACE);
|
||||
|
||||
@ -473,7 +476,8 @@ int safe_atou8(const char *s, uint8_t *ret) {
|
||||
if ((unsigned long) (uint8_t) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
*ret = (uint8_t) l;
|
||||
if (ret)
|
||||
*ret = (uint8_t) l;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -507,7 +511,6 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||
long l;
|
||||
|
||||
assert(s);
|
||||
assert(ret);
|
||||
|
||||
errno = 0;
|
||||
l = strtol(s, &x, 0);
|
||||
@ -518,7 +521,9 @@ int safe_atoi16(const char *s, int16_t *ret) {
|
||||
if ((long) (int16_t) l != l)
|
||||
return -ERANGE;
|
||||
|
||||
*ret = (int16_t) l;
|
||||
if (ret)
|
||||
*ret = (int16_t) l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -528,7 +533,6 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
double d = 0;
|
||||
|
||||
assert(s);
|
||||
assert(ret_d);
|
||||
|
||||
loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t) 0);
|
||||
if (loc == (locale_t) 0)
|
||||
@ -541,7 +545,9 @@ int safe_atod(const char *s, double *ret_d) {
|
||||
if (!x || x == s || *x != 0)
|
||||
return -EINVAL;
|
||||
|
||||
*ret_d = (double) d;
|
||||
if (ret_d)
|
||||
*ret_d = (double) d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1338,6 +1338,13 @@ int safe_fork_full(
|
||||
log_full_errno(prio, r, "Failed to connect stdin/stdout to /dev/null: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
} else if (flags & FORK_STDOUT_TO_STDERR) {
|
||||
|
||||
if (dup2(STDERR_FILENO, STDOUT_FILENO) < 0) {
|
||||
log_full_errno(prio, r, "Failed to connect stdout to stderr: %m");
|
||||
_exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & FORK_RLIMIT_NOFILE_SAFE) {
|
||||
|
@ -147,16 +147,17 @@ void reset_cached_pid(void);
|
||||
int must_be_root(void);
|
||||
|
||||
typedef enum ForkFlags {
|
||||
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
|
||||
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
|
||||
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
|
||||
FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
|
||||
FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
|
||||
FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
|
||||
FORK_WAIT = 1 << 6, /* Wait until child exited */
|
||||
FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
|
||||
FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
|
||||
FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
||||
FORK_RESET_SIGNALS = 1 << 0, /* Reset all signal handlers and signal mask */
|
||||
FORK_CLOSE_ALL_FDS = 1 << 1, /* Close all open file descriptors in the child, except for 0,1,2 */
|
||||
FORK_DEATHSIG = 1 << 2, /* Set PR_DEATHSIG in the child */
|
||||
FORK_NULL_STDIO = 1 << 3, /* Connect 0,1,2 to /dev/null */
|
||||
FORK_REOPEN_LOG = 1 << 4, /* Reopen log connection */
|
||||
FORK_LOG = 1 << 5, /* Log above LOG_DEBUG log level about failures */
|
||||
FORK_WAIT = 1 << 6, /* Wait until child exited */
|
||||
FORK_NEW_MOUNTNS = 1 << 7, /* Run child in its own mount namespace */
|
||||
FORK_MOUNTNS_SLAVE = 1 << 8, /* Make child's mount namespace MS_SLAVE */
|
||||
FORK_RLIMIT_NOFILE_SAFE = 1 << 9, /* Set RLIMIT_NOFILE soft limit to 1K for select() compat */
|
||||
FORK_STDOUT_TO_STDERR = 1 << 10, /* Make stdout a copy of stderr */
|
||||
} ForkFlags;
|
||||
|
||||
int safe_fork_full(const char *name, const int except_fds[], size_t n_except_fds, ForkFlags flags, pid_t *ret_pid);
|
||||
|
@ -1064,3 +1064,13 @@ bool string_is_safe(const char *p) {
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
char* string_erase(char *x) {
|
||||
if (!x)
|
||||
return NULL;
|
||||
|
||||
/* A delicious drop of snake-oil! To be called on memory where we stored passphrases or so, after we
|
||||
* used them. */
|
||||
explicit_bzero_safe(x, strlen(x));
|
||||
return x;
|
||||
}
|
||||
|
@ -278,3 +278,5 @@ static inline char* str_realloc(char **p) {
|
||||
|
||||
return (*p = t);
|
||||
}
|
||||
|
||||
char* string_erase(char *x);
|
||||
|
@ -19,50 +19,60 @@
|
||||
#include "tmpfile-util.h"
|
||||
#include "umask-util.h"
|
||||
|
||||
int fopen_temporary(const char *path, FILE **_f, char **_temp_path) {
|
||||
FILE *f;
|
||||
char *t;
|
||||
int r, fd;
|
||||
int fopen_temporary(const char *path, FILE **ret_f, char **ret_temp_path) {
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
_cleanup_free_ char *t = NULL;
|
||||
_cleanup_close_ int fd = -1;
|
||||
int r;
|
||||
|
||||
assert(path);
|
||||
assert(_f);
|
||||
assert(_temp_path);
|
||||
if (path) {
|
||||
r = tempfn_xxxxxx(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else {
|
||||
const char *d;
|
||||
|
||||
r = tempfn_xxxxxx(path, NULL, &t);
|
||||
if (r < 0)
|
||||
return r;
|
||||
r = tmp_dir(&d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t = path_join(d, "XXXXXX");
|
||||
if (!t)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
fd = mkostemp_safe(t);
|
||||
if (fd < 0) {
|
||||
free(t);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
/* This assumes that returned FILE object is short-lived and used within the same single-threaded
|
||||
* context and never shared externally, hence locking is not necessary. */
|
||||
|
||||
r = fdopen_unlocked(fd, "w", &f);
|
||||
if (r < 0) {
|
||||
unlink(t);
|
||||
free(t);
|
||||
safe_close(fd);
|
||||
(void) unlink(t);
|
||||
return r;
|
||||
}
|
||||
|
||||
*_f = f;
|
||||
*_temp_path = t;
|
||||
TAKE_FD(fd);
|
||||
|
||||
if (ret_f)
|
||||
*ret_f = TAKE_PTR(f);
|
||||
|
||||
if (ret_temp_path)
|
||||
*ret_temp_path = TAKE_PTR(t);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* This is much like mkostemp() but is subject to umask(). */
|
||||
int mkostemp_safe(char *pattern) {
|
||||
_unused_ _cleanup_umask_ mode_t u = umask(0077);
|
||||
int fd;
|
||||
|
||||
assert(pattern);
|
||||
|
||||
fd = mkostemp(pattern, O_CLOEXEC);
|
||||
RUN_WITH_UMASK(0077)
|
||||
fd = mkostemp(pattern, O_CLOEXEC);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -84,7 +84,7 @@ char *getusername_malloc(void) {
|
||||
return uid_to_name(getuid());
|
||||
}
|
||||
|
||||
static bool is_nologin_shell(const char *shell) {
|
||||
bool is_nologin_shell(const char *shell) {
|
||||
|
||||
return PATH_IN_SET(shell,
|
||||
/* 'nologin' is the friendliest way to disable logins for a user account. It prints a nice
|
||||
|
@ -57,6 +57,14 @@ int take_etc_passwd_lock(const char *root);
|
||||
|
||||
#define ETC_PASSWD_LOCK_PATH "/etc/.pwd.lock"
|
||||
|
||||
static inline bool uid_is_system(uid_t uid) {
|
||||
return uid <= SYSTEM_UID_MAX;
|
||||
}
|
||||
|
||||
static inline bool gid_is_system(gid_t gid) {
|
||||
return gid <= SYSTEM_GID_MAX;
|
||||
}
|
||||
|
||||
static inline bool uid_is_dynamic(uid_t uid) {
|
||||
return DYNAMIC_UID_MIN <= uid && uid <= DYNAMIC_UID_MAX;
|
||||
}
|
||||
@ -65,12 +73,12 @@ static inline bool gid_is_dynamic(gid_t gid) {
|
||||
return uid_is_dynamic((uid_t) gid);
|
||||
}
|
||||
|
||||
static inline bool uid_is_system(uid_t uid) {
|
||||
return uid <= SYSTEM_UID_MAX;
|
||||
static inline bool uid_is_container(uid_t uid) {
|
||||
return CONTAINER_UID_BASE_MIN <= uid && uid <= CONTAINER_UID_BASE_MAX;
|
||||
}
|
||||
|
||||
static inline bool gid_is_system(gid_t gid) {
|
||||
return gid <= SYSTEM_GID_MAX;
|
||||
static inline bool gid_is_container(gid_t gid) {
|
||||
return uid_is_container((uid_t) gid);
|
||||
}
|
||||
|
||||
/* The following macros add 1 when converting things, since UID 0 is a valid UID, while the pointer
|
||||
@ -127,3 +135,5 @@ int putsgent_sane(const struct sgrp *sg, FILE *stream);
|
||||
#endif
|
||||
|
||||
int make_salt(char **ret);
|
||||
|
||||
bool is_nologin_shell(const char *shell);
|
||||
|
@ -3,6 +3,8 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "sd-daemon.h"
|
||||
|
||||
#include "pager.h"
|
||||
#include "selinux-util.h"
|
||||
#include "spawn-ask-password-agent.h"
|
||||
@ -16,6 +18,8 @@
|
||||
save_argc_argv(argc, argv); \
|
||||
intro; \
|
||||
r = impl; \
|
||||
if (r < 0) \
|
||||
(void) sd_notifyf(0, "ERRNO=%i", -r); \
|
||||
ask_password_agent_close(); \
|
||||
polkit_agent_close(); \
|
||||
pager_close(); \
|
||||
|
@ -9,6 +9,29 @@
|
||||
#include "utf8.h"
|
||||
#include "util.h"
|
||||
|
||||
static void test_string_erase(void) {
|
||||
char *x;
|
||||
|
||||
x = strdupa("");
|
||||
assert_se(streq(string_erase(x), ""));
|
||||
|
||||
x = strdupa("1");
|
||||
assert_se(streq(string_erase(x), ""));
|
||||
|
||||
x = strdupa("123456789");
|
||||
assert_se(streq(string_erase(x), ""));
|
||||
|
||||
assert_se(x[1] == '\0');
|
||||
assert_se(x[2] == '\0');
|
||||
assert_se(x[3] == '\0');
|
||||
assert_se(x[4] == '\0');
|
||||
assert_se(x[5] == '\0');
|
||||
assert_se(x[6] == '\0');
|
||||
assert_se(x[7] == '\0');
|
||||
assert_se(x[8] == '\0');
|
||||
assert_se(x[9] == '\0');
|
||||
}
|
||||
|
||||
static void test_free_and_strndup_one(char **t, const char *src, size_t l, const char *expected, bool change) {
|
||||
int r;
|
||||
|
||||
@ -543,6 +566,7 @@ static void test_memory_startswith_no_case(void) {
|
||||
int main(int argc, char *argv[]) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_string_erase();
|
||||
test_free_and_strndup();
|
||||
test_ascii_strcasecmp_n();
|
||||
test_ascii_strcasecmp_nn();
|
||||
|
Loading…
Reference in New Issue
Block a user