1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-30 10:50:15 +03:00

Merge pull request #4299 from poettering/variety

ioctl socket fixes, sd-bus error updates, resolved error addition, PAM stub process priv fix
This commit is contained in:
Evgeny Vereshchagin 2016-10-06 23:43:08 +03:00 committed by GitHub
commit 36264e0de5
12 changed files with 98 additions and 34 deletions

4
TODO
View File

@ -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

View File

@ -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)

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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),

View File

@ -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)

View File

@ -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;

View File

@ -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);

View File

@ -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 */
};

View File

@ -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;