1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2025-02-10 13:57:25 +03:00

libudev: add missing errno initialization/error propagation (#6781)

In libudev (which es much older code than the rest of systemd), we
propagate errors in functions not returning an int, via (positive) errno
(i.e. libc-style), and as negative Exyz values in those returning an int
(much preferred, i.e. Linux kernel style). Let's fix up a few place,
where this was incorrectly done, or not done at all.

Fixes: #6613
This commit is contained in:
Lennart Poettering 2017-09-09 22:31:09 +02:00 committed by Zbigniew Jędrzejewski-Szmek
parent 0aabe74749
commit 309f631d41
5 changed files with 63 additions and 16 deletions

View File

@ -159,6 +159,8 @@ _public_ struct udev *udev_enumerate_get_udev(struct udev_enumerate *udev_enumer
* Returns: a udev_list_entry. * Returns: a udev_list_entry.
*/ */
_public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate) { _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enumerate *udev_enumerate) {
struct udev_list_entry *e;
assert_return_errno(udev_enumerate, NULL, EINVAL); assert_return_errno(udev_enumerate, NULL, EINVAL);
if (!udev_enumerate->devices_uptodate) { if (!udev_enumerate->devices_uptodate) {
@ -182,7 +184,11 @@ _public_ struct udev_list_entry *udev_enumerate_get_list_entry(struct udev_enume
udev_enumerate->devices_uptodate = true; udev_enumerate->devices_uptodate = true;
} }
return udev_list_get_entry(&udev_enumerate->devices_list); e = udev_list_get_entry(&udev_enumerate->devices_list);
if (!e)
errno = ENODATA;
return e;
} }
/** /**

View File

@ -57,15 +57,19 @@ _public_ struct udev_hwdb *udev_hwdb_new(struct udev *udev) {
struct udev_hwdb *hwdb; struct udev_hwdb *hwdb;
int r; int r;
assert_return(udev, NULL); assert_return_errno(udev, NULL, EINVAL);
r = sd_hwdb_new(&hwdb_internal); r = sd_hwdb_new(&hwdb_internal);
if (r < 0) if (r < 0) {
errno = -r;
return NULL; return NULL;
}
hwdb = new0(struct udev_hwdb, 1); hwdb = new0(struct udev_hwdb, 1);
if (!hwdb) if (!hwdb) {
errno = ENOMEM;
return NULL; return NULL;
}
hwdb->refcount = 1; hwdb->refcount = 1;
hwdb->hwdb = hwdb_internal; hwdb->hwdb = hwdb_internal;
@ -127,6 +131,7 @@ _public_ struct udev_hwdb *udev_hwdb_unref(struct udev_hwdb *hwdb) {
*/ */
_public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) { _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev_hwdb *hwdb, const char *modalias, unsigned int flags) {
const char *key, *value; const char *key, *value;
struct udev_list_entry *e;
if (!hwdb || !modalias) { if (!hwdb || !modalias) {
errno = EINVAL; errno = EINVAL;
@ -142,5 +147,9 @@ _public_ struct udev_list_entry *udev_hwdb_get_properties_list_entry(struct udev
} }
} }
return udev_list_get_entry(&hwdb->properties_list); e = udev_list_get_entry(&hwdb->properties_list);
if (!e)
errno = ENODATA;
return e;
} }

View File

@ -100,8 +100,10 @@ static struct udev_monitor *udev_monitor_new(struct udev *udev)
struct udev_monitor *udev_monitor; struct udev_monitor *udev_monitor;
udev_monitor = new0(struct udev_monitor, 1); udev_monitor = new0(struct udev_monitor, 1);
if (udev_monitor == NULL) if (udev_monitor == NULL) {
errno = ENOMEM;
return NULL; return NULL;
}
udev_monitor->refcount = 1; udev_monitor->refcount = 1;
udev_monitor->udev = udev; udev_monitor->udev = udev;
udev_list_init(udev, &udev_monitor->filter_subsystem_list, false); udev_list_init(udev, &udev_monitor->filter_subsystem_list, false);
@ -171,8 +173,10 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
struct udev_monitor *udev_monitor; struct udev_monitor *udev_monitor;
unsigned int group; unsigned int group;
if (udev == NULL) if (udev == NULL) {
errno = EINVAL;
return NULL; return NULL;
}
if (name == NULL) if (name == NULL)
group = UDEV_MONITOR_NONE; group = UDEV_MONITOR_NONE;
@ -196,8 +200,10 @@ struct udev_monitor *udev_monitor_new_from_netlink_fd(struct udev *udev, const c
group = UDEV_MONITOR_UDEV; group = UDEV_MONITOR_UDEV;
} else if (streq(name, "kernel")) } else if (streq(name, "kernel"))
group = UDEV_MONITOR_KERNEL; group = UDEV_MONITOR_KERNEL;
else else {
errno = EINVAL;
return NULL; return NULL;
}
udev_monitor = udev_monitor_new(udev); udev_monitor = udev_monitor_new(udev);
if (udev_monitor == NULL) if (udev_monitor == NULL)
@ -438,7 +444,10 @@ _public_ int udev_monitor_set_receive_buffer_size(struct udev_monitor *udev_moni
{ {
if (udev_monitor == NULL) if (udev_monitor == NULL)
return -EINVAL; return -EINVAL;
return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)); if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_RCVBUFFORCE, &size, sizeof(size)) < 0)
return -errno;
return 0;
} }
int udev_monitor_disconnect(struct udev_monitor *udev_monitor) int udev_monitor_disconnect(struct udev_monitor *udev_monitor)
@ -596,8 +605,10 @@ _public_ struct udev_device *udev_monitor_receive_device(struct udev_monitor *ud
bool is_initialized = false; bool is_initialized = false;
retry: retry:
if (udev_monitor == NULL) if (udev_monitor == NULL) {
errno = EINVAL;
return NULL; return NULL;
}
iov.iov_base = &buf; iov.iov_base = &buf;
iov.iov_len = sizeof(buf); iov.iov_len = sizeof(buf);
memzero(&smsg, sizeof(struct msghdr)); memzero(&smsg, sizeof(struct msghdr));
@ -617,6 +628,7 @@ retry:
if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) { if (buflen < 32 || (smsg.msg_flags & MSG_TRUNC)) {
log_debug("invalid message length"); log_debug("invalid message length");
errno = EINVAL;
return NULL; return NULL;
} }
@ -625,12 +637,14 @@ retry:
if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 || if (udev_monitor->snl_trusted_sender.nl.nl_pid == 0 ||
snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) { snl.nl.nl_pid != udev_monitor->snl_trusted_sender.nl.nl_pid) {
log_debug("unicast netlink message ignored"); log_debug("unicast netlink message ignored");
errno = EAGAIN;
return NULL; return NULL;
} }
} else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) { } else if (snl.nl.nl_groups == UDEV_MONITOR_KERNEL) {
if (snl.nl.nl_pid > 0) { if (snl.nl.nl_pid > 0) {
log_debug("multicast kernel netlink message from PID %"PRIu32" ignored", log_debug("multicast kernel netlink message from PID %"PRIu32" ignored",
snl.nl.nl_pid); snl.nl.nl_pid);
errno = EAGAIN;
return NULL; return NULL;
} }
} }
@ -638,12 +652,14 @@ retry:
cmsg = CMSG_FIRSTHDR(&smsg); cmsg = CMSG_FIRSTHDR(&smsg);
if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) { if (cmsg == NULL || cmsg->cmsg_type != SCM_CREDENTIALS) {
log_debug("no sender credentials received, message ignored"); log_debug("no sender credentials received, message ignored");
errno = EAGAIN;
return NULL; return NULL;
} }
cred = (struct ucred *)CMSG_DATA(cmsg); cred = (struct ucred *)CMSG_DATA(cmsg);
if (cred->uid != 0) { if (cred->uid != 0) {
log_debug("sender uid="UID_FMT", message ignored", cred->uid); log_debug("sender uid="UID_FMT", message ignored", cred->uid);
errno = EAGAIN;
return NULL; return NULL;
} }
@ -652,11 +668,13 @@ retry:
if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) { if (buf.nlh.magic != htobe32(UDEV_MONITOR_MAGIC)) {
log_debug("unrecognized message signature (%x != %x)", log_debug("unrecognized message signature (%x != %x)",
buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC)); buf.nlh.magic, htobe32(UDEV_MONITOR_MAGIC));
errno = EAGAIN;
return NULL; return NULL;
} }
if (buf.nlh.properties_off+32 > (size_t)buflen) { if (buf.nlh.properties_off+32 > (size_t)buflen) {
log_debug("message smaller than expected (%u > %zd)", log_debug("message smaller than expected (%u > %zd)",
buf.nlh.properties_off+32, buflen); buf.nlh.properties_off+32, buflen);
errno = EAGAIN;
return NULL; return NULL;
} }
@ -669,12 +687,14 @@ retry:
bufpos = strlen(buf.raw) + 1; bufpos = strlen(buf.raw) + 1;
if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) { if ((size_t)bufpos < sizeof("a@/d") || bufpos >= buflen) {
log_debug("invalid message length"); log_debug("invalid message length");
errno = EAGAIN;
return NULL; return NULL;
} }
/* check message header */ /* check message header */
if (strstr(buf.raw, "@/") == NULL) { if (strstr(buf.raw, "@/") == NULL) {
log_debug("unrecognized message header"); log_debug("unrecognized message header");
errno = EAGAIN;
return NULL; return NULL;
} }
} }
@ -701,6 +721,8 @@ retry:
rc = poll(pfd, 1, 0); rc = poll(pfd, 1, 0);
if (rc > 0) if (rc > 0)
goto retry; goto retry;
errno = EAGAIN;
return NULL; return NULL;
} }
@ -837,8 +859,11 @@ _public_ int udev_monitor_filter_add_match_tag(struct udev_monitor *udev_monitor
*/ */
_public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor) _public_ int udev_monitor_filter_remove(struct udev_monitor *udev_monitor)
{ {
static struct sock_fprog filter = { 0, NULL }; static const struct sock_fprog filter = { 0, NULL };
udev_list_cleanup(&udev_monitor->filter_subsystem_list); udev_list_cleanup(&udev_monitor->filter_subsystem_list);
return setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)); if (setsockopt(udev_monitor->sock, SOL_SOCKET, SO_ATTACH_FILTER, &filter, sizeof(filter)) < 0)
return -errno;
return 0;
} }

View File

@ -60,12 +60,16 @@ _public_ struct udev_queue *udev_queue_new(struct udev *udev)
{ {
struct udev_queue *udev_queue; struct udev_queue *udev_queue;
if (udev == NULL) if (udev == NULL) {
errno = EINVAL;
return NULL; return NULL;
}
udev_queue = new0(struct udev_queue, 1); udev_queue = new0(struct udev_queue, 1);
if (udev_queue == NULL) if (udev_queue == NULL) {
errno = ENOMEM;
return NULL; return NULL;
}
udev_queue->refcount = 1; udev_queue->refcount = 1;
udev_queue->udev = udev; udev_queue->udev = udev;
@ -124,8 +128,10 @@ _public_ struct udev_queue *udev_queue_unref(struct udev_queue *udev_queue)
**/ **/
_public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue) _public_ struct udev *udev_queue_get_udev(struct udev_queue *udev_queue)
{ {
if (udev_queue == NULL) if (udev_queue == NULL) {
errno = EINVAL;
return NULL; return NULL;
}
return udev_queue->udev; return udev_queue->udev;
} }
@ -223,6 +229,7 @@ _public_ int udev_queue_get_seqnum_is_finished(struct udev_queue *udev_queue, un
**/ **/
_public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue) _public_ struct udev_list_entry *udev_queue_get_queued_list_entry(struct udev_queue *udev_queue)
{ {
errno = ENODATA;
return NULL; return NULL;
} }

View File

@ -97,7 +97,7 @@ _public_ struct udev *udev_new(void) {
udev = new0(struct udev, 1); udev = new0(struct udev, 1);
if (!udev) { if (!udev) {
errno = -ENOMEM; errno = ENOMEM;
return NULL; return NULL;
} }
udev->refcount = 1; udev->refcount = 1;