diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-02-18 19:20:47 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-02-18 19:42:24 +0100 |
commit | 1c8da044469acabcfc479ba3276954da53210830 (patch) | |
tree | a9252d87c59570ebec4f3004526e6f52637bb917 | |
parent | 6e646d22f6f9215de5ccb5e5edf450558c59fed1 (diff) |
shared: introduce cmsg_close_all() call
The call iterates through cmsg list and closes all fds passed via
SCM_RIGHTS.
This patch also ensures the call is used wherever appropriate, where we
might get spurious fds sent and we should better close them, then leave
them lying around.
-rw-r--r-- | src/import/importd.c | 8 | ||||
-rw-r--r-- | src/shared/ask-password-api.c | 2 | ||||
-rw-r--r-- | src/shared/util.c | 10 | ||||
-rw-r--r-- | src/shared/util.h | 2 | ||||
-rw-r--r-- | src/shutdownd/shutdownd.c | 14 | ||||
-rw-r--r-- | src/udev/udev-ctrl.c | 3 |
6 files changed, 28 insertions, 11 deletions
diff --git a/src/import/importd.c b/src/import/importd.c index 2eef476015..eaf04e6a2b 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -518,12 +518,10 @@ static int manager_on_notify(sd_event_source *s, int fd, uint32_t revents, void return -errno; } + cmsg_close_all(&msghdr); + for (cmsg = CMSG_FIRSTHDR(&msghdr); cmsg; cmsg = CMSG_NXTHDR(&msghdr, cmsg)) { - if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { - close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); - log_warning("Somebody sent us unexpected fds, ignoring."); - return 0; - } else if (cmsg->cmsg_level == SOL_SOCKET && + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS && cmsg->cmsg_len == CMSG_LEN(sizeof(struct ucred))) { diff --git a/src/shared/ask-password-api.c b/src/shared/ask-password-api.c index 0a61dafc59..44ebc58491 100644 --- a/src/shared/ask-password-api.c +++ b/src/shared/ask-password-api.c @@ -475,6 +475,8 @@ int ask_password_agent( goto finish; } + cmsg_close_all(&msghdr); + if (n <= 0) { log_error("Message too short"); continue; diff --git a/src/shared/util.c b/src/shared/util.c index deb9839633..dc6528013b 100644 --- a/src/shared/util.c +++ b/src/shared/util.c @@ -8110,3 +8110,13 @@ ssize_t string_table_lookup(const char * const *table, size_t len, const char *k return -1; } + +void cmsg_close_all(struct msghdr *mh) { + struct cmsghdr *cmsg; + + assert(mh); + + for (cmsg = CMSG_FIRSTHDR(mh); cmsg; cmsg = CMSG_NXTHDR(mh, cmsg)) + if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) + close_many((int*) CMSG_DATA(cmsg), (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int)); +} diff --git a/src/shared/util.h b/src/shared/util.h index 45cb09443d..759d053c25 100644 --- a/src/shared/util.h +++ b/src/shared/util.h @@ -1080,3 +1080,5 @@ void sigkill_wait(pid_t *pid); #define _cleanup_sigkill_wait_ _cleanup_(sigkill_wait) int syslog_parse_priority(const char **p, int *priority, bool with_facility); + +void cmsg_close_all(struct msghdr *mh); diff --git a/src/shutdownd/shutdownd.c b/src/shutdownd/shutdownd.c index 701882b96d..60a646878e 100644 --- a/src/shutdownd/shutdownd.c +++ b/src/shutdownd/shutdownd.c @@ -70,12 +70,7 @@ static int read_packet(int fd, union shutdown_buffer *_b) { assert(_b); n = recvmsg(fd, &msghdr, MSG_DONTWAIT); - if (n <= 0) { - if (n == 0) { - log_error("Short read"); - return -EIO; - } - + if (n < 0) { if (errno == EAGAIN || errno == EINTR) return 0; @@ -83,6 +78,13 @@ static int read_packet(int fd, union shutdown_buffer *_b) { return -errno; } + cmsg_close_all(&msghdr); + + if (n == 0) { + log_error("Short read"); + return -EIO; + } + if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) || control.cmsghdr.cmsg_level != SOL_SOCKET || control.cmsghdr.cmsg_type != SCM_CREDENTIALS || diff --git a/src/udev/udev-ctrl.c b/src/udev/udev-ctrl.c index 7b5ef6b2a8..59a3eceaad 100644 --- a/src/udev/udev-ctrl.c +++ b/src/udev/udev-ctrl.c @@ -377,6 +377,9 @@ struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl_connection *conn) { log_error_errno(errno, "unable to receive ctrl message: %m"); goto err; } + + cmsg_close_all(&smsg); + cmsg = CMSG_FIRSTHDR(&smsg); cred = (struct ucred *) CMSG_DATA(cmsg); |