summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Vereshchagin <evvers@ya.ru>2016-10-06 23:43:08 +0300
committerGitHub <noreply@github.com>2016-10-06 23:43:08 +0300
commit36264e0de596d9b0264ae08b53832495a78c779c (patch)
tree658b2caae552a9a7be6810dab6b44e653a89fef9
parente057995bb1314a94ce460d8e5a2a20e73c0e2ad4 (diff)
parent97f0e76f18d322d29bcfbc4ab6bb9cd67a1cdd54 (diff)
Merge pull request #4299 from poettering/variety
ioctl socket fixes, sd-bus error updates, resolved error addition, PAM stub process priv fix
-rw-r--r--TODO4
-rw-r--r--src/basic/capability-util.c5
-rw-r--r--src/basic/socket-util.c17
-rw-r--r--src/basic/socket-util.h2
-rw-r--r--src/basic/user-util.c49
-rw-r--r--src/core/execute.c16
-rw-r--r--src/libsystemd/sd-bus/bus-common-errors.c22
-rw-r--r--src/libsystemd/sd-device/sd-device.c5
-rw-r--r--src/nspawn/nspawn.c2
-rw-r--r--src/resolve/resolved-dns-packet.c3
-rw-r--r--src/resolve/resolved-dns-packet.h1
-rw-r--r--src/udev/net/ethtool-util.c6
12 files changed, 98 insertions, 34 deletions
diff --git a/TODO b/TODO
index f215a4944b..9ca2736b2a 100644
--- a/TODO
+++ b/TODO
@@ -32,6 +32,10 @@ Janitorial Clean-ups:
Features:
+* in networkd, when matching device types, fix up DEVTYPE rubbish the kernel passes to us
+
+* enable LockMLOCK to take a percentage value relative to physical memory
+
* switch to ProtectSystem=strict for all our long-running services where that's possible
* introduce an "invocation ID" for units, that is randomly generated, and
diff --git a/src/basic/capability-util.c b/src/basic/capability-util.c
index f8db6e0212..c3de20a0e8 100644
--- a/src/basic/capability-util.c
+++ b/src/basic/capability-util.c
@@ -296,8 +296,9 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
if (setresgid(gid, gid, gid) < 0)
return log_error_errno(errno, "Failed to change group ID: %m");
- if (maybe_setgroups(0, NULL) < 0)
- return log_error_errno(errno, "Failed to drop auxiliary groups list: %m");
+ r = maybe_setgroups(0, NULL);
+ if (r < 0)
+ return log_error_errno(r, "Failed to drop auxiliary groups list: %m");
/* Ensure we keep the permitted caps across the setresuid() */
if (prctl(PR_SET_KEEPCAPS, 1) < 0)
diff --git a/src/basic/socket-util.c b/src/basic/socket-util.c
index 5c829e0e7e..1662c04705 100644
--- a/src/basic/socket-util.c
+++ b/src/basic/socket-util.c
@@ -1060,3 +1060,20 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
return NULL;
}
+
+int socket_ioctl_fd(void) {
+ int fd;
+
+ /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
+ * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
+ * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
+ * generic AF_NETLINK. */
+
+ fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
+ if (fd < 0)
+ fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
+ if (fd < 0)
+ return -errno;
+
+ return fd;
+}
diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h
index 2536b085f9..2ef572badb 100644
--- a/src/basic/socket-util.h
+++ b/src/basic/socket-util.h
@@ -154,3 +154,5 @@ struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t leng
1 + strnlen(_sa->sun_path+1, sizeof(_sa->sun_path)-1) : \
strnlen(_sa->sun_path, sizeof(_sa->sun_path))); \
})
+
+int socket_ioctl_fd(void);
diff --git a/src/basic/user-util.c b/src/basic/user-util.c
index 16496fccfa..de6c93056e 100644
--- a/src/basic/user-util.c
+++ b/src/basic/user-util.c
@@ -460,9 +460,11 @@ int get_shell(char **_s) {
}
int reset_uid_gid(void) {
+ int r;
- if (maybe_setgroups(0, NULL) < 0)
- return -errno;
+ r = maybe_setgroups(0, NULL);
+ if (r < 0)
+ return r;
if (setresgid(0, 0, 0) < 0)
return -errno;
@@ -605,25 +607,30 @@ bool valid_home(const char *p) {
}
int maybe_setgroups(size_t size, const gid_t *list) {
- static int cached_can_setgroups = -1;
- /* check if setgroups is allowed before we try to drop all the auxiliary groups */
- if (size == 0) {
- if (cached_can_setgroups < 0) {
- _cleanup_free_ char *setgroups_content = NULL;
- int r = read_one_line_file("/proc/self/setgroups", &setgroups_content);
- if (r < 0 && errno != ENOENT)
- return r;
- if (r < 0) {
- /* old kernels don't have /proc/self/setgroups, so assume we can use setgroups */
- cached_can_setgroups = true;
- } else {
- cached_can_setgroups = streq(setgroups_content, "allow");
- if (!cached_can_setgroups)
- log_debug("skip setgroups, /proc/self/setgroups is set to 'deny'");
- }
- }
- if (!cached_can_setgroups)
+ int r;
+
+ /* Check if setgroups is allowed before we try to drop all the auxiliary groups */
+ if (size == 0) { /* Dropping all aux groups? */
+ _cleanup_free_ char *setgroups_content = NULL;
+ bool can_setgroups;
+
+ r = read_one_line_file("/proc/self/setgroups", &setgroups_content);
+ if (r == -ENOENT)
+ /* Old kernels don't have /proc/self/setgroups, so assume we can use setgroups */
+ can_setgroups = true;
+ else if (r < 0)
+ return r;
+ else
+ can_setgroups = streq(setgroups_content, "allow");
+
+ if (!can_setgroups) {
+ log_debug("Skipping setgroups(), /proc/self/setgroups is set to 'deny'");
return 0;
+ }
}
- return setgroups(size, list);
+
+ if (setgroups(size, list) < 0)
+ return -errno;
+
+ return 0;
}
diff --git a/src/core/execute.c b/src/core/execute.c
index 019ff8490b..d5c4e60796 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -781,9 +781,10 @@ static int enforce_groups(const ExecContext *context, const char *username, gid_
k++;
}
- if (maybe_setgroups(k, gids) < 0) {
+ r = maybe_setgroups(k, gids);
+ if (r < 0) {
free(gids);
- return -errno;
+ return r;
}
free(gids);
@@ -843,6 +844,7 @@ static int setup_pam(
const char *name,
const char *user,
uid_t uid,
+ gid_t gid,
const char *tty,
char ***env,
int fds[], unsigned n_fds) {
@@ -948,8 +950,14 @@ static int setup_pam(
* and this will make PR_SET_PDEATHSIG work in most cases.
* If this fails, ignore the error - but expect sd-pam threads
* to fail to exit normally */
+
+ r = maybe_setgroups(0, NULL);
+ if (r < 0)
+ log_warning_errno(r, "Failed to setgroups() in sd-pam: %m");
+ if (setresgid(gid, gid, gid) < 0)
+ log_warning_errno(errno, "Failed to setresgid() in sd-pam: %m");
if (setresuid(uid, uid, uid) < 0)
- log_error_errno(r, "Error: Failed to setresuid() in sd-pam: %m");
+ log_warning_errno(errno, "Failed to setresuid() in sd-pam: %m");
(void) ignore_signals(SIGPIPE, -1);
@@ -2413,7 +2421,7 @@ static int exec_child(
}
if (context->pam_name && username) {
- r = setup_pam(context->pam_name, username, uid, context->tty_path, &accum_env, fds, n_fds);
+ r = setup_pam(context->pam_name, username, uid, gid, context->tty_path, &accum_env, fds, n_fds);
if (r < 0) {
*exit_status = EXIT_PAM;
return r;
diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c
index a69193aa32..9cc28ed564 100644
--- a/src/libsystemd/sd-bus/bus-common-errors.c
+++ b/src/libsystemd/sd-bus/bus-common-errors.c
@@ -52,6 +52,8 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_NO_MACHINE_FOR_PID, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_MACHINE_EXISTS, EEXIST),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_PRIVATE_NETWORKING, ENOSYS),
+ SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_USER_MAPPING, ENXIO),
+ SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_GROUP_MAPPING, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_SESSION, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SESSION_FOR_PID, ENXIO),
@@ -64,6 +66,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_DEVICE_NOT_TAKEN, EINVAL),
SD_BUS_ERROR_MAP(BUS_ERROR_OPERATION_IN_PROGRESS, EINPROGRESS),
SD_BUS_ERROR_MAP(BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED, EOPNOTSUPP),
+ SD_BUS_ERROR_MAP(BUS_ERROR_SESSION_BUSY, EBUSY),
SD_BUS_ERROR_MAP(BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED, EALREADY),
@@ -82,6 +85,25 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = {
SD_BUS_ERROR_MAP(BUS_ERROR_LINK_BUSY, EBUSY),
SD_BUS_ERROR_MAP(BUS_ERROR_NETWORK_DOWN, ENETDOWN),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "FORMERR", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "SERVFAIL", EHOSTDOWN),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "NXDOMAIN", ENXIO),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "NOTIMP", ENOSYS),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "REFUSED", EACCES),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "YXDOMAIN", EEXIST),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "YRRSET", EEXIST),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "NXRRSET", ENOENT),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "NOTAUTH", EACCES),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "NOTZONE", EREMOTE),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADVERS", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADKEY", EKEYREJECTED),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADTIME", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADMODE", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADNAME", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADALG", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADTRUNC", EBADMSG),
+ SD_BUS_ERROR_MAP(_BUS_ERROR_DNS "BADCOOKIE", EBADR),
+
SD_BUS_ERROR_MAP(BUS_ERROR_NO_SUCH_TRANSFER, ENXIO),
SD_BUS_ERROR_MAP(BUS_ERROR_TRANSFER_IN_PROGRESS, EBUSY),
diff --git a/src/libsystemd/sd-device/sd-device.c b/src/libsystemd/sd-device/sd-device.c
index 0c4ad966bd..411453e08d 100644
--- a/src/libsystemd/sd-device/sd-device.c
+++ b/src/libsystemd/sd-device/sd-device.c
@@ -36,6 +36,7 @@
#include "parse-util.h"
#include "path-util.h"
#include "set.h"
+#include "socket-util.h"
#include "stat-util.h"
#include "string-util.h"
#include "strv.h"
@@ -629,9 +630,9 @@ _public_ int sd_device_new_from_device_id(sd_device **ret, const char *id) {
if (r < 0)
return r;
- sk = socket(PF_INET, SOCK_DGRAM, 0);
+ sk = socket_ioctl_fd();
if (sk < 0)
- return -errno;
+ return sk;
r = ioctl(sk, SIOCGIFNAME, &ifr);
if (r < 0)
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 9a8274c8de..a08377b3a3 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3830,7 +3830,7 @@ int main(int argc, char *argv[]) {
_cleanup_(sd_event_unrefp) sd_event *event = NULL;
_cleanup_(pty_forward_freep) PTYForward *forward = NULL;
_cleanup_(sd_netlink_unrefp) sd_netlink *rtnl = NULL;
- ContainerStatus container_status;
+ ContainerStatus container_status = 0;
char last_char = 0;
int ifi = 0;
ssize_t l;
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index a8ad8fe342..337a8c473f 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -2143,7 +2143,7 @@ int dns_packet_extract(DnsPacket *p) {
for (i = 0; i < n; i++) {
_cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
- bool cache_flush;
+ bool cache_flush = false;
r = dns_packet_read_rr(p, &rr, &cache_flush, NULL);
if (r < 0)
@@ -2289,6 +2289,7 @@ static const char* const dns_rcode_table[_DNS_RCODE_MAX_DEFINED] = {
[DNS_RCODE_BADNAME] = "BADNAME",
[DNS_RCODE_BADALG] = "BADALG",
[DNS_RCODE_BADTRUNC] = "BADTRUNC",
+ [DNS_RCODE_BADCOOKIE] = "BADCOOKIE",
};
DEFINE_STRING_TABLE_LOOKUP(dns_rcode, int);
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index 7b7d4e14c9..054dc88a85 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -263,6 +263,7 @@ enum {
DNS_RCODE_BADNAME = 20,
DNS_RCODE_BADALG = 21,
DNS_RCODE_BADTRUNC = 22,
+ DNS_RCODE_BADCOOKIE = 23,
_DNS_RCODE_MAX_DEFINED,
_DNS_RCODE_MAX = 4095 /* 4 bit rcode in the header plus 8 bit rcode in OPT, makes 12 bit */
};
diff --git a/src/udev/net/ethtool-util.c b/src/udev/net/ethtool-util.c
index b1aa0223fd..708a665576 100644
--- a/src/udev/net/ethtool-util.c
+++ b/src/udev/net/ethtool-util.c
@@ -25,6 +25,7 @@
#include "conf-parser.h"
#include "ethtool-util.h"
#include "log.h"
+#include "socket-util.h"
#include "string-table.h"
#include "strxcpyx.h"
#include "util.h"
@@ -59,10 +60,9 @@ int ethtool_connect(int *ret) {
assert_return(ret, -EINVAL);
- fd = socket(PF_INET, SOCK_DGRAM, 0);
+ fd = socket_ioctl_fd();
if (fd < 0)
- return -errno;
-
+ return fd;
*ret = fd;
return 0;