diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/basic/missing.h | 7 | ||||
-rw-r--r-- | src/core/execute.c | 91 | ||||
-rw-r--r-- | src/network/networkd-link.c | 24 |
3 files changed, 73 insertions, 49 deletions
diff --git a/src/basic/missing.h b/src/basic/missing.h index dc1f244d4c..9811b6b23e 100644 --- a/src/basic/missing.h +++ b/src/basic/missing.h @@ -139,6 +139,8 @@ static inline int pivot_root(const char *new_root, const char *put_old) { # define __NR_memfd_create 385 # elif defined __aarch64__ # define __NR_memfd_create 279 +# elif defined __s390__ +# define __NR_memfd_create 350 # elif defined _MIPS_SIM # if _MIPS_SIM == _MIPS_SIM_ABI32 # define __NR_memfd_create 4354 @@ -1028,7 +1030,12 @@ static inline int renameat2(int oldfd, const char *oldname, int newfd, const cha #if !HAVE_DECL_KCMP static inline int kcmp(pid_t pid1, pid_t pid2, int type, unsigned long idx1, unsigned long idx2) { +#if defined(__NR_kcmp) return syscall(__NR_kcmp, pid1, pid2, type, idx1, idx2); +#else + errno = ENOSYS; + return -1; +#endif } #endif diff --git a/src/core/execute.c b/src/core/execute.c index 6e14848cd4..7796c07fcf 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -50,6 +50,7 @@ #include <sys/apparmor.h> #endif +#include "barrier.h" #include "sd-messages.h" #include "rm-rf.h" #include "strv.h" @@ -768,10 +769,11 @@ static int setup_pam( .appdata_ptr = NULL }; + _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL; pam_handle_t *handle = NULL; sigset_t old_ss; int pam_code = PAM_SUCCESS; - int err; + int err = 0; char **e = NULL; bool close_session = false; pid_t pam_pid = 0, parent_pid; @@ -788,6 +790,10 @@ static int setup_pam( * daemon. We do things this way to ensure that the main PID * of the daemon is the one we initially fork()ed. */ + err = barrier_create(&barrier); + if (err < 0) + goto fail; + if (log_get_max_level() < LOG_DEBUG) flags |= PAM_SILENT; @@ -836,6 +842,7 @@ static int setup_pam( /* The child's job is to reset the PAM session on * termination */ + barrier_set_role(&barrier, BARRIER_CHILD); /* This string must fit in 10 chars (i.e. the length * of "/sbin/init"), to look pretty in /bin/ps */ @@ -863,6 +870,11 @@ static int setup_pam( if (prctl(PR_SET_PDEATHSIG, SIGTERM) < 0) goto child_finish; + /* Tell the parent that our setup is done. This is especially + * important regarding dropping privileges. Otherwise, unit + * setup might race against our setresuid(2) call. */ + barrier_place(&barrier); + /* Check if our parent process might already have * died? */ if (getppid() == parent_pid) { @@ -898,6 +910,8 @@ static int setup_pam( _exit(r); } + barrier_set_role(&barrier, BARRIER_PARENT); + /* If the child was forked off successfully it will do all the * cleanups, so forget about the handle here. */ handle = NULL; @@ -909,6 +923,11 @@ static int setup_pam( * might have opened it, but we don't want this fd around. */ closelog(); + /* Synchronously wait for the child to initialize. We don't care for + * errors as we cannot recover. However, warn loudly if it happens. */ + if (!barrier_place_and_sync(&barrier)) + log_error("PAM initialization failed"); + *pam_env = e; e = NULL; @@ -919,7 +938,7 @@ fail: log_error("PAM failed: %s", pam_strerror(handle, pam_code)); err = -EPERM; /* PAM errors do not map to errno */ } else { - err = log_error_errno(errno, "PAM failed: %m"); + err = log_error_errno(err < 0 ? err : errno, "PAM failed: %m"); } if (handle) { @@ -1582,25 +1601,50 @@ static int exec_child( } } + umask(context->umask); + if (params->apply_permissions) { r = enforce_groups(context, username, gid); if (r < 0) { *exit_status = EXIT_GROUP; return r; } - } +#ifdef HAVE_SMACK + if (context->smack_process_label) { + r = mac_smack_apply_pid(0, context->smack_process_label); + if (r < 0) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + } +#ifdef SMACK_DEFAULT_PROCESS_LABEL + else { + _cleanup_free_ char *exec_label = NULL; - umask(context->umask); + r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label); + if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL); + if (r < 0) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + } +#endif +#endif #ifdef HAVE_PAM - if (params->apply_permissions && context->pam_name && username) { - r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); - if (r < 0) { - *exit_status = EXIT_PAM; - return r; + if (context->pam_name && username) { + r = setup_pam(context->pam_name, username, uid, context->tty_path, &pam_env, fds, n_fds); + if (r < 0) { + *exit_status = EXIT_PAM; + return r; + } } - } #endif + } if (context->private_network && runtime && runtime->netns_storage_socket[0] >= 0) { r = setup_netns(runtime->netns_storage_socket); @@ -1729,33 +1773,6 @@ static int exec_child( } } -#ifdef HAVE_SMACK - if (context->smack_process_label) { - r = mac_smack_apply_pid(0, context->smack_process_label); - if (r < 0) { - *exit_status = EXIT_SMACK_PROCESS_LABEL; - return r; - } - } -#ifdef SMACK_DEFAULT_PROCESS_LABEL - else { - _cleanup_free_ char *exec_label = NULL; - - r = mac_smack_read(command->path, SMACK_ATTR_EXEC, &exec_label); - if (r < 0 && r != -ENODATA && r != -EOPNOTSUPP) { - *exit_status = EXIT_SMACK_PROCESS_LABEL; - return r; - } - - r = mac_smack_apply_pid(0, exec_label ? : SMACK_DEFAULT_PROCESS_LABEL); - if (r < 0) { - *exit_status = EXIT_SMACK_PROCESS_LABEL; - return r; - } - } -#endif -#endif - if (context->user) { r = enforce_user(context, uid); if (r < 0) { diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 0a7e75c89c..5dd14b1104 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -1797,7 +1797,6 @@ static int link_set_ipv6_privacy_extensions(Link *link) { static int link_set_ipv6_accept_ra(Link *link) { const char *p = NULL, *v = NULL; - bool b; int r; /* Make this a NOP if IPv6 is not available */ @@ -1807,20 +1806,21 @@ static int link_set_ipv6_accept_ra(Link *link) { if (link->flags & IFF_LOOPBACK) return 0; - /* if unset check the ip forwarding setting maintained for the interface - * and then set it to depending on that. enabled if local forwarding - * is disabled. disabled if local forwarding is enabled. + /* If unset use system default (enabled if local forwarding is disabled. + * disabled if local forwarding is enabled). + * If set, ignore or enforce RA independent of local forwarding state. */ if (link->network->ipv6_accept_ra < 0) { - if (IN_SET(link->network->ip_forward, ADDRESS_FAMILY_YES, ADDRESS_FAMILY_IPV6)) - b = false; - else - b = true; - } else - b = link->network->ipv6_accept_ra; - + /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */ + v = "1"; + } else if (link->network->ipv6_accept_ra > 0) { + /* "2" means accept RA even if ip_forward is enabled */ + v = "2"; + } else { + /* "0" means ignore RA */ + v = "0"; + } p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/accept_ra"); - v = one_zero(b); r = write_string_file(p, v, 0); if (r < 0) { |