summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-02-18 19:20:47 +0100
committerLennart Poettering <lennart@poettering.net>2015-02-18 19:42:24 +0100
commit1c8da044469acabcfc479ba3276954da53210830 (patch)
treea9252d87c59570ebec4f3004526e6f52637bb917
parent6e646d22f6f9215de5ccb5e5edf450558c59fed1 (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.c8
-rw-r--r--src/shared/ask-password-api.c2
-rw-r--r--src/shared/util.c10
-rw-r--r--src/shared/util.h2
-rw-r--r--src/shutdownd/shutdownd.c14
-rw-r--r--src/udev/udev-ctrl.c3
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);