Compare commits

..

No commits in common. "c13f4643f4326b007a7baf85298f03a85ee48a78" and "9494da41c271bb9519d3484b6016526a72cc6be5" have entirely different histories.

29 changed files with 186 additions and 312 deletions

View File

@ -262,7 +262,6 @@ manpages = [
['sd_bus_get_events', 'sd_bus_get_timeout', 'sd_bus_set_fd'],
''],
['sd_bus_get_n_queued_read', '3', ['sd_bus_get_n_queued_write'], ''],
['sd_bus_get_name_creds', '3', ['sd_bus_get_owner_creds'], ''],
['sd_bus_get_name_machine_id', '3', [], ''],
['sd_bus_is_open', '3', ['sd_bus_is_ready'], ''],
['sd_bus_list_names', '3', [], ''],

View File

@ -83,8 +83,6 @@
<citerefentry><refentrytitle>sd_bus_get_method_call_timeout</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_n_queued_read</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_name_machine_id</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_name_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_owner_creds</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_scope</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_tid</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd_bus_get_unique_name</refentrytitle><manvolnum>3</manvolnum></citerefentry>,

View File

@ -1,120 +0,0 @@
<?xml version='1.0'?>
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<!-- SPDX-License-Identifier: LGPL-2.1+ -->
<refentry id="sd_bus_get_name_creds" xmlns:xi="http://www.w3.org/2001/XInclude">
<refentryinfo>
<title>sd_bus_get_name_creds</title>
<productname>systemd</productname>
</refentryinfo>
<refmeta>
<refentrytitle>sd_bus_get_name_creds</refentrytitle>
<manvolnum>3</manvolnum>
</refmeta>
<refnamediv>
<refname>sd_bus_get_name_creds</refname>
<refname>sd_bus_get_owner_creds</refname>
<refpurpose>Query bus client credentials</refpurpose>
</refnamediv>
<refsynopsisdiv>
<funcsynopsis>
<funcsynopsisinfo>#include &lt;systemd/sd-bus.h&gt;</funcsynopsisinfo>
<funcprototype>
<funcdef>int <function>sd_bus_get_name_creds</function></funcdef>
<paramdef>sd_bus *<parameter>bus</parameter></paramdef>
<paramdef>const char *<parameter>name</parameter></paramdef>
<paramdef>uint64_t <parameter>mask</parameter></paramdef>
<paramdef>sd_bus_creds **<parameter>creds</parameter></paramdef>
</funcprototype>
<funcprototype>
<funcdef>int <function>sd_bus_get_owner_creds</function></funcdef>
<paramdef>sd_bus *<parameter>bus</parameter></paramdef>
<paramdef>uint64_t <parameter>mask</parameter></paramdef>
<paramdef>sd_bus_creds **<parameter>creds</parameter></paramdef>
</funcprototype>
</funcsynopsis>
</refsynopsisdiv>
<refsect1>
<title>Description</title>
<para><function>sd_bus_get_name_creds()</function> queries the credentials of the bus client
identified by <parameter>name</parameter>. The <parameter>mask</parameter> parameter is a combo of
<constant index='false'>SD_BUS_CREDS_*</constant> flags that indicate which credential info the caller is
interested in. See
<citerefentry><refentrytitle>sd_bus_creds_new_from_pid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
for a list of possible flags. On success, <parameter>creds</parameter> contains a new
<structname>sd_bus_creds</structname> instance with the requested information. Ownership of this instance
belongs to the caller and it should be freed once no longer needed by calling
<function>sd_bus_creds_unref()</function>.</para>
<para><function>sd_bus_get_owner_creds()</function> queries the credentials of the creator of the given
bus. The <parameter>mask</parameter> and <parameter>creds</parameter> parameters behave the same as in
<function>sd_bus_get_name_creds()</function>.</para>
</refsect1>
<refsect1>
<title>Return Value</title>
<para>On success, these functions return a non-negative integer. On failure, they return a negative
errno-style error code.</para>
<refsect2>
<title>Errors</title>
<para>Returned errors may indicate the following problems:</para>
<variablelist>
<varlistentry>
<term><constant>-EINVAL</constant></term>
<listitem><para>An argument is invalid.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOPKG</constant></term>
<listitem><para>The bus cannot be resolved.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-EPERM</constant></term>
<listitem><para>The bus has already been started.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ECHILD</constant></term>
<listitem><para>The bus was created in a different process.</para></listitem>
</varlistentry>
<varlistentry>
<term><constant>-ENOMEM</constant></term>
<listitem><para>Memory allocation failed.</para></listitem>
</varlistentry>
</variablelist>
</refsect2>
</refsect1>
<xi:include href="libsystemd-pkgconfig.xml" />
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>
</para>
</refsect1>
</refentry>

View File

@ -1149,6 +1149,7 @@ static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol
FOREACH_BTRFS_IOCTL_SEARCH_HEADER(i, sh, args) {
_cleanup_free_ char *p = NULL;
const struct btrfs_root_ref *ref;
struct btrfs_ioctl_ino_lookup_args ino_args;
btrfs_ioctl_search_args_set(&args, sh);
@ -1163,10 +1164,9 @@ static int subvol_remove_children(int fd, const char *subvolume, uint64_t subvol
if (!p)
return -ENOMEM;
struct btrfs_ioctl_ino_lookup_args ino_args = {
.treeid = subvol_id,
.objectid = htole64(ref->dirid),
};
zero(ino_args);
ino_args.treeid = subvol_id;
ino_args.objectid = htole64(ref->dirid);
if (ioctl(fd, BTRFS_IOC_INO_LOOKUP, &ino_args) < 0)
return -errno;
@ -1504,6 +1504,7 @@ static int subvol_snapshot_children(
FOREACH_BTRFS_IOCTL_SEARCH_HEADER(i, sh, args) {
_cleanup_free_ char *p = NULL, *c = NULL, *np = NULL;
struct btrfs_ioctl_ino_lookup_args ino_args;
const struct btrfs_root_ref *ref;
_cleanup_close_ int old_child_fd = -1, new_child_fd = -1;
@ -1527,10 +1528,9 @@ static int subvol_snapshot_children(
if (!p)
return -ENOMEM;
struct btrfs_ioctl_ino_lookup_args ino_args = {
.treeid = old_subvol_id,
.objectid = htole64(ref->dirid),
};
zero(ino_args);
ino_args.treeid = old_subvol_id;
ino_args.objectid = htole64(ref->dirid);
if (ioctl(old_fd, BTRFS_IOC_INO_LOOKUP, &ino_args) < 0)
return -errno;

View File

@ -21,10 +21,9 @@
#include "path-util.h"
#include "process-util.h"
#include "socket-util.h"
#include "stat-util.h"
#include "stdio-util.h"
#include "tmpfile-util.h"
#include "util.h"
#include "tmpfile-util.h"
/* The maximum number of iterations in the loop to close descriptors in the fallback case
* when /proc/self/fd/ is inaccessible. */
@ -940,15 +939,8 @@ int fd_reopen(int fd, int flags) {
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
new_fd = open(procfs_path, flags);
if (new_fd < 0) {
if (errno != ENOENT)
return -errno;
if (proc_mounted() == 0)
return -ENOSYS; /* if we have no /proc/, the concept is not implementable */
return -ENOENT;
}
if (new_fd < 0)
return -errno;
return new_fd;
}

View File

@ -337,15 +337,8 @@ int fchmod_opath(int fd, mode_t m) {
* fchownat() does. */
xsprintf(procfs_path, "/proc/self/fd/%i", fd);
if (chmod(procfs_path, m) < 0) {
if (errno != ENOENT)
return -errno;
if (proc_mounted() == 0)
return -ENOSYS; /* if we have no /proc/, the concept is not implementable */
return -ENOENT;
}
if (chmod(procfs_path, m) < 0)
return -errno;
return 0;
}

View File

@ -887,7 +887,7 @@ ssize_t receive_one_fd_iov(
.msg_iov = iov,
.msg_iovlen = iovlen,
};
struct cmsghdr *found;
struct cmsghdr *cmsg, *found = NULL;
ssize_t k;
assert(transport_fd >= 0);
@ -905,7 +905,16 @@ ssize_t receive_one_fd_iov(
if (k < 0)
return k;
found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int)));
CMSG_FOREACH(cmsg, &mh) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
assert(!found);
found = cmsg;
break;
}
}
if (!found) {
cmsg_close_all(&mh);

View File

@ -158,14 +158,6 @@ int flush_accept(int fd);
struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
/* Type-safe, dereferencing version of cmsg_find() */
#define CMSG_FIND_DATA(mh, level, type, ctype) \
({ \
struct cmsghdr *_found; \
_found = cmsg_find(mh, level, type, CMSG_LEN(sizeof(ctype))); \
(ctype*) (_found ? CMSG_DATA(_found) : NULL); \
})
/*
* Certain hardware address types (e.g Infiniband) do not fit into sll_addr
* (8 bytes) and run over the structure. This macro returns the correct size that

View File

@ -178,12 +178,13 @@ int fd_is_fs_type(int fd, statfs_f_type_t magic_value) {
}
int path_is_fs_type(const char *path, statfs_f_type_t magic_value) {
struct statfs s;
_cleanup_close_ int fd = -1;
if (statfs(path, &s) < 0)
fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_PATH);
if (fd < 0)
return -errno;
return is_fs_type(&s, magic_value);
return fd_is_fs_type(fd, magic_value);
}
bool is_temporary_fs(const struct statfs *s) {
@ -376,15 +377,3 @@ int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret
return 0;
}
int proc_mounted(void) {
int r;
/* A quick check of procfs is properly mounted */
r = path_is_fs_type("/proc/", PROC_SUPER_MAGIC);
if (r == -ENOENT) /* not mounted at all */
return false;
return r;
}

View File

@ -87,5 +87,3 @@ int fd_verify_directory(int fd);
int device_path_make_major_minor(mode_t mode, dev_t devno, char **ret);
int device_path_make_canonical(mode_t mode, dev_t devno, char **ret);
int device_path_parse_major_minor(const char *path, mode_t *ret_mode, dev_t *ret_devno);
int proc_mounted(void);

View File

@ -921,11 +921,19 @@ static int process_socket(int fd) {
/* The final zero-length datagram carries the file descriptor and tells us
* that we're done. */
if (n == 0) {
struct cmsghdr *found;
struct cmsghdr *cmsg, *found = NULL;
free(iovec.iov_base);
found = cmsg_find(&mh, SOL_SOCKET, SCM_RIGHTS, CMSG_LEN(sizeof(int)));
CMSG_FOREACH(cmsg, &mh) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_RIGHTS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
assert(!found);
found = cmsg;
}
}
if (!found) {
cmsg_close_all(&mh);
r = log_error_errno(SYNTHETIC_ERRNO(EBADMSG),

View File

@ -557,8 +557,9 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void
.msg_control = &control,
.msg_controllen = sizeof(control),
};
struct ucred *ucred;
struct ucred *ucred = NULL;
Manager *m = userdata;
struct cmsghdr *cmsg;
char *p, *e;
Transfer *t;
Iterator i;
@ -573,12 +574,17 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void
cmsg_close_all(&msghdr);
CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
ucred = (struct ucred*) CMSG_DATA(cmsg);
if (msghdr.msg_flags & MSG_TRUNC) {
log_warning("Got overly long notification datagram, ignoring.");
return 0;
}
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
if (!ucred || ucred->pid <= 0) {
log_warning("Got notification datagram lacking credential information, ignoring.");
return 0;

View File

@ -246,10 +246,9 @@ static int server_init(Server *s, unsigned n_sockets) {
assert(s);
assert(n_sockets > 0);
*s = (struct Server) {
.epoll_fd = epoll_create1(EPOLL_CLOEXEC),
};
zero(*s);
s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
if (s->epoll_fd < 0) {
r = log_error_errno(errno,
"Failed to create epoll object: %m");
@ -257,6 +256,7 @@ static int server_init(Server *s, unsigned n_sockets) {
}
for (i = 0; i < n_sockets; i++) {
struct epoll_event ev;
Fifo *f;
int fd;
@ -283,11 +283,9 @@ static int server_init(Server *s, unsigned n_sockets) {
f->fd = -1;
struct epoll_event ev = {
.events = EPOLLIN,
.data.ptr = f,
};
zero(ev);
ev.events = EPOLLIN;
ev.data.ptr = f;
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
r = -errno;
fifo_free(f);

View File

@ -1783,6 +1783,7 @@ static int setup_keys(void) {
int fd = -1, r;
sd_id128_t machine, boot;
char *p = NULL, *k = NULL;
struct FSSHeader h;
uint64_t n;
struct stat st;
@ -1872,17 +1873,15 @@ static int setup_keys(void) {
if (r < 0)
log_warning_errno(r, "Failed to set file attributes: %m");
struct FSSHeader h = {
.machine_id = machine,
.boot_id = boot,
.header_size = htole64(sizeof(h)),
.start_usec = htole64(n * arg_interval),
.interval_usec = htole64(arg_interval),
.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR),
.fsprg_state_size = htole64(state_size),
};
zero(h);
memcpy(h.signature, "KSHHRHLP", 8);
h.machine_id = machine;
h.boot_id = boot;
h.header_size = htole64(sizeof(h));
h.start_usec = htole64(n * arg_interval);
h.interval_usec = htole64(arg_interval);
h.fsprg_secpar = htole16(FSPRG_RECOMMENDED_SECPAR);
h.fsprg_state_size = htole64(state_size);
r = loop_write(fd, &h, sizeof(h), false);
if (r < 0) {

View File

@ -491,7 +491,8 @@ static int stdout_stream_scan(StdoutStream *s, bool force_flush) {
static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents, void *userdata) {
uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
StdoutStream *s = userdata;
struct ucred *ucred;
struct ucred *ucred = NULL;
struct cmsghdr *cmsg;
struct iovec iovec;
size_t limit;
ssize_t l;
@ -540,14 +541,25 @@ static int stdout_stream_process(sd_event_source *es, int fd, uint32_t revents,
goto terminate;
}
/* Invalidate the context if the pid of the sender changed. This happens when a forked process
* inherits stdout / stderr from a parent. In this case getpeercred returns the ucred of the parent,
* which can be invalid if the parent has exited in the meantime.
CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
assert(!ucred);
ucred = (struct ucred *)CMSG_DATA(cmsg);
break;
}
/* Invalidate the context if the pid of the sender changed.
* This happens when a forked process inherits stdout / stderr
* from a parent. In this case getpeercred returns the ucred
* of the parent, which can be invalid if the parent has exited
* in the meantime.
*/
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
if (ucred && ucred->pid != s->ucred.pid) {
/* force out any previously half-written lines from a different process, before we switch to
* the new ucred structure for everything we just added */
/* force out any previously half-written lines from a
* different process, before we switch to the new ucred
* structure for everything we just added */
r = stdout_stream_scan(s, true);
if (r < 0)
goto terminate;

View File

@ -162,7 +162,7 @@ static Window *window_add(MMapCache *m, MMapFileDescriptor *f, int prot, bool ke
if (!m->last_unused || m->n_windows <= WINDOWS_MIN) {
/* Allocate a new window */
w = new(Window, 1);
w = new0(Window, 1);
if (!w)
return NULL;
m->n_windows++;
@ -171,17 +171,16 @@ static Window *window_add(MMapCache *m, MMapFileDescriptor *f, int prot, bool ke
/* Reuse an existing one */
w = m->last_unused;
window_unlink(w);
zero(*w);
}
*w = (Window) {
.cache = m,
.fd = f,
.prot = prot,
.keep_always = keep_always,
.offset = offset,
.size = size,
.ptr = ptr,
};
w->cache = m;
w->fd = f;
w->prot = prot;
w->keep_always = keep_always;
w->offset = offset;
w->size = size;
w->ptr = ptr;
LIST_PREPEND(by_fd, f->windows, w);

View File

@ -167,9 +167,9 @@ int icmp6_receive(int fd, void *buffer, size_t size, struct in6_addr *dst,
iov = IOVEC_MAKE(buffer, size);
len = recvmsg_safe(fd, &msg, MSG_DONTWAIT);
len = recvmsg(fd, &msg, MSG_DONTWAIT);
if (len < 0)
return (int) len;
return -errno;
if ((size_t) len != size)
return -EINVAL;

View File

@ -1927,21 +1927,25 @@ static int client_receive_message_raw(
iov = IOVEC_MAKE(packet, buflen);
len = recvmsg_safe(fd, &msg, 0);
if (IN_SET(len, -EAGAIN, -EINTR, -ENETDOWN))
return 0;
if (len < 0)
return log_dhcp_client_errno(client, len,
len = recvmsg(fd, &msg, 0);
if (len < 0) {
if (IN_SET(errno, EAGAIN, EINTR, ENETDOWN))
return 0;
return log_dhcp_client_errno(client, errno,
"Could not receive message from raw socket: %m");
if ((size_t) len < sizeof(DHCPPacket))
} else if ((size_t)len < sizeof(DHCPPacket))
return 0;
cmsg = cmsg_find(&msg, SOL_PACKET, PACKET_AUXDATA, CMSG_LEN(sizeof(struct tpacket_auxdata)));
if (cmsg) {
struct tpacket_auxdata *aux = (struct tpacket_auxdata*) CMSG_DATA(cmsg);
checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
}
CMSG_FOREACH(cmsg, &msg)
if (cmsg->cmsg_level == SOL_PACKET &&
cmsg->cmsg_type == PACKET_AUXDATA &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct tpacket_auxdata))) {
struct tpacket_auxdata *aux = (struct tpacket_auxdata*)CMSG_DATA(cmsg);
checksum = !(aux->tp_status & TP_STATUS_CSUMNOTREADY);
break;
}
r = dhcp_packet_verify_headers(packet, len, checksum, client->port);
if (r < 0)

View File

@ -995,12 +995,14 @@ static int server_receive_message(sd_event_source *s, int fd,
iov = IOVEC_MAKE(message, buflen);
len = recvmsg_safe(fd, &msg, 0);
if (IN_SET(len, -EAGAIN, -EINTR))
return 0;
if (len < 0)
return len;
if ((size_t) len < sizeof(DHCPMessage))
len = recvmsg(fd, &msg, 0);
if (len < 0) {
if (IN_SET(errno, EAGAIN, EINTR))
return 0;
return -errno;
}
if ((size_t)len < sizeof(DHCPMessage))
return 0;
CMSG_FOREACH(cmsg, &msg) {

View File

@ -13,9 +13,8 @@
int introspect_begin(struct introspect *i, bool trusted) {
assert(i);
*i = (struct introspect) {
.trusted = trusted,
};
zero(*i);
i->trusted = trusted;
i->f = open_memstream_unlocked(&i->introspection, &i->size);
if (!i->f)

View File

@ -136,10 +136,11 @@ static int bus_socket_write_auth(sd_bus *b) {
if (b->prefer_writev)
k = writev(b->output_fd, b->auth_iovec + b->auth_index, ELEMENTSOF(b->auth_iovec) - b->auth_index);
else {
struct msghdr mh = {
.msg_iov = b->auth_iovec + b->auth_index,
.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index,
};
struct msghdr mh;
zero(mh);
mh.msg_iov = b->auth_iovec + b->auth_index;
mh.msg_iovlen = ELEMENTSOF(b->auth_iovec) - b->auth_index;
k = sendmsg(b->output_fd, &mh, MSG_DONTWAIT|MSG_NOSIGNAL);
if (k < 0 && errno == ENOTSOCK) {
@ -550,12 +551,11 @@ static int bus_socket_read_auth(sd_bus *b) {
if (b->prefer_readv)
k = readv(b->input_fd, &iov, 1);
else {
mh = (struct msghdr) {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = &control,
.msg_controllen = sizeof(control),
};
zero(mh);
mh.msg_iov = &iov;
mh.msg_iovlen = 1;
mh.msg_control = &control;
mh.msg_controllen = sizeof(control);
k = recvmsg_safe(b->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (k == -ENOTSOCK) {
@ -1194,12 +1194,11 @@ int bus_socket_read_message(sd_bus *bus) {
if (bus->prefer_readv)
k = readv(bus->input_fd, &iov, 1);
else {
mh = (struct msghdr) {
.msg_iov = &iov,
.msg_iovlen = 1,
.msg_control = &control,
.msg_controllen = sizeof(control),
};
zero(mh);
mh.msg_iov = &iov;
mh.msg_iovlen = 1;
mh.msg_control = &control;
mh.msg_controllen = sizeof(control);
k = recvmsg_safe(bus->input_fd, &mh, MSG_DONTWAIT|MSG_CMSG_CLOEXEC);
if (k == -ENOTSOCK) {

View File

@ -238,7 +238,7 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
return k;
}
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *_group, bool peek) {
union sockaddr_union sender;
uint8_t cmsg_buffer[CMSG_SPACE(sizeof(struct nl_pktinfo))];
struct msghdr msg = {
@ -249,6 +249,8 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
.msg_control = cmsg_buffer,
.msg_controllen = sizeof(cmsg_buffer),
};
struct cmsghdr *cmsg;
uint32_t group = 0;
ssize_t n;
assert(fd >= 0);
@ -279,16 +281,20 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
return 0;
}
if (ret_mcast_group) {
struct cmsghdr *cmsg;
CMSG_FOREACH(cmsg, &msg) {
if (cmsg->cmsg_level == SOL_NETLINK &&
cmsg->cmsg_type == NETLINK_PKTINFO &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct nl_pktinfo))) {
struct nl_pktinfo *pktinfo = (void *)CMSG_DATA(cmsg);
cmsg = cmsg_find(&msg, SOL_NETLINK, NETLINK_PKTINFO, CMSG_LEN(sizeof(struct nl_pktinfo)));
if (ret_mcast_group)
*ret_mcast_group = ((struct nl_pktinfo*) CMSG_DATA(cmsg))->group;
else
*ret_mcast_group = 0;
/* multi-cast group */
group = pktinfo->group;
}
}
if (_group)
*_group = group;
return (int) n;
}

View File

@ -3698,7 +3698,8 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
.msg_control = &control,
.msg_controllen = sizeof(control),
};
struct ucred *ucred;
struct cmsghdr *cmsg;
struct ucred *ucred = NULL;
ssize_t n;
pid_t inner_child_pid;
_cleanup_strv_free_ char **tags = NULL;
@ -3720,7 +3721,15 @@ static int nspawn_dispatch_notify_fd(sd_event_source *source, int fd, uint32_t r
cmsg_close_all(&msghdr);
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
CMSG_FOREACH(cmsg, &msghdr) {
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) {
ucred = (struct ucred*) CMSG_DATA(cmsg);
}
}
if (!ucred || ucred->pid != inner_child_pid) {
log_debug("Received notify message without valid credentials. Ignoring.");
return 0;

View File

@ -860,6 +860,7 @@ int ask_password_agent(
for (;;) {
char passphrase[LINE_MAX+1];
struct msghdr msghdr;
struct iovec iovec;
struct ucred *ucred;
union {
@ -918,12 +919,11 @@ int ask_password_agent(
iovec = IOVEC_MAKE(passphrase, sizeof(passphrase));
zero(control);
struct msghdr msghdr = {
.msg_iov = &iovec,
.msg_iovlen = 1,
.msg_control = &control,
.msg_controllen = sizeof(control),
};
zero(msghdr);
msghdr.msg_iov = &iovec;
msghdr.msg_iovlen = 1;
msghdr.msg_control = &control;
msghdr.msg_controllen = sizeof(control);
n = recvmsg_safe(socket_fd, &msghdr, 0);
if (IN_SET(n, -EAGAIN, -EINTR))
@ -940,12 +940,15 @@ int ask_password_agent(
continue;
}
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
if (!ucred) {
if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
control.cmsghdr.cmsg_level != SOL_SOCKET ||
control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
log_debug("Received message without credentials. Ignoring.");
continue;
}
ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
if (ucred->uid != 0) {
log_debug("Got request from unprivileged user. Ignoring.");
continue;

View File

@ -243,9 +243,8 @@ int socket_address_parse_netlink(SocketAddress *a, const char *s) {
assert(a);
assert(s);
*a = (SocketAddress) {
.type = SOCK_RAW,
};
zero(*a);
a->type = SOCK_RAW;
r = extract_first_word(&s, &word, NULL, 0);
if (r < 0)

View File

@ -1443,7 +1443,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (name) {
r = specifier_printf(name, specifier_table, NULL, &resolved_name);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, name);
log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, name);
if (!valid_user_group_name(resolved_name, 0))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
@ -1458,7 +1458,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (id) {
r = specifier_printf(id, specifier_table, NULL, &resolved_id);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
fname, line, name);
}
@ -1469,7 +1469,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (description) {
r = specifier_printf(description, specifier_table, NULL, &resolved_description);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
fname, line, description);
if (!valid_gecos(resolved_description))
@ -1485,7 +1485,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (home) {
r = specifier_printf(home, specifier_table, NULL, &resolved_home);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
fname, line, home);
if (!valid_home(resolved_home))
@ -1501,7 +1501,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
if (shell) {
r = specifier_printf(shell, specifier_table, NULL, &resolved_shell);
if (r < 0)
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m",
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s",
fname, line, shell);
if (!valid_shell(resolved_shell))

View File

@ -1078,11 +1078,6 @@ static int fd_set_acls(Item *item, int fd, const char *path, const struct stat *
if (r > 0)
return -r; /* already warned */
/* The above procfs paths don't work if /proc is not mounted. */
if (r == -ENOENT && proc_mounted() == 0)
r = -ENOSYS;
if (r == -EOPNOTSUPP) {
log_debug_errno(r, "ACLs not supported by file system at %s", path);
return 0;
@ -2561,7 +2556,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer, bool
if (r < 0) {
if (IN_SET(r, -EINVAL, -EBADSLT))
*invalid_config = true;
return log_error_errno(r, "[%s:%u] Failed to replace specifiers in '%s': %m", fname, line, path);
return log_error_errno(r, "[%s:%u] Failed to replace specifiers: %s", fname, line, path);
}
r = patch_var_run(fname, line, &i.path);

View File

@ -916,8 +916,9 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
.msg_control = &control,
.msg_controllen = sizeof(control),
};
struct cmsghdr *cmsg;
ssize_t size;
struct ucred *ucred;
struct ucred *ucred = NULL;
struct worker *worker;
size = recvmsg_safe(fd, &msghdr, MSG_DONTWAIT);
@ -936,7 +937,12 @@ static int on_worker(sd_event_source *s, int fd, uint32_t revents, void *userdat
continue;
}
ucred = CMSG_FIND_DATA(&msghdr, SOL_SOCKET, SCM_CREDENTIALS, struct ucred);
CMSG_FOREACH(cmsg, &msghdr)
if (cmsg->cmsg_level == SOL_SOCKET &&
cmsg->cmsg_type == SCM_CREDENTIALS &&
cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred)))
ucred = (struct ucred*) CMSG_DATA(cmsg);
if (!ucred || ucred->pid <= 0) {
log_warning("Ignoring worker message without valid PID");
continue;

View File

@ -48,30 +48,10 @@ FUZZIT_ARGS="--type ${FUZZING_TYPE} --branch ${FUZZIT_BRANCH} --revision ${TRAVI
wget -O fuzzit https://github.com/fuzzitdev/fuzzit/releases/latest/download/fuzzit_Linux_x86_64
chmod +x fuzzit
# Simple wrapper which retries given command up to three times if it fails
_retry() {
local EC=1
for _ in {0..2}; do
if "$@"; then
EC=0
break
fi
sleep 1
done
return $EC
}
find out/ -maxdepth 1 -name 'fuzz-*' -executable -type f -exec basename '{}' \; | while read -r fuzzer; do
_retry ./fuzzit create job ${FUZZIT_ARGS} ${fuzzer}-asan-ubsan out/${fuzzer} ${FUZZIT_ADDITIONAL_FILES}
done
find out/ -maxdepth 1 -name 'fuzz-*' -executable -type f -exec basename '{}' \; | xargs --verbose -n1 -I%FUZZER% ./fuzzit create job ${FUZZIT_ARGS} %FUZZER%-asan-ubsan out/%FUZZER% ${FUZZIT_ADDITIONAL_FILES}
export SANITIZER="memory -fsanitize-memory-track-origins"
FUZZIT_ARGS="--type ${FUZZING_TYPE} --branch ${FUZZIT_BRANCH} --revision ${TRAVIS_COMMIT}"
tools/oss-fuzz.sh
find out/ -maxdepth 1 -name 'fuzz-*' -executable -type f -exec basename '{}' \; | while read -r fuzzer; do
_retry ./fuzzit create job ${FUZZIT_ARGS} ${fuzzer}-msan out/${fuzzer} ${FUZZIT_ADDITIONAL_FILES}
done
find out/ -maxdepth 1 -name 'fuzz-*' -executable -type f -exec basename '{}' \; | xargs --verbose -n1 -I%FUZZER% ./fuzzit create job ${FUZZIT_ARGS} %FUZZER%-msan out/%FUZZER% ${FUZZIT_ADDITIONAL_FILES}