mirror of
https://github.com/systemd/systemd.git
synced 2025-01-13 17:18:18 +03:00
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.
This commit is contained in:
parent
6e646d22f6
commit
1c8da04446
@ -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))) {
|
||||
|
||||
|
@ -475,6 +475,8 @@ int ask_password_agent(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
cmsg_close_all(&msghdr);
|
||||
|
||||
if (n <= 0) {
|
||||
log_error("Message too short");
|
||||
continue;
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user