coredump: truncate overly long coredump metadata fields (#3780)

Fixes: #3573
Replaces: #3588
This commit is contained in:
Lennart Poettering 2016-07-22 17:39:47 +02:00 committed by GitHub
parent e08ab37902
commit fec603eb6c

View file

@ -852,12 +852,42 @@ static int send_iovec(const struct iovec iovec[], size_t n_iovec, int input_fd)
return log_error_errno(errno, "Failed to connect to coredump service: %m");
for (i = 0; i < n_iovec; i++) {
ssize_t n;
assert(iovec[i].iov_len > 0);
struct msghdr mh = {
.msg_iov = (struct iovec*) iovec + i,
.msg_iovlen = 1,
};
struct iovec copy[2];
for (;;) {
if (sendmsg(fd, &mh, MSG_NOSIGNAL) >= 0)
break;
if (errno == EMSGSIZE && mh.msg_iov[0].iov_len > 0) {
/* This field didn't fit? That's a pity. Given that this is just metadata,
* let's truncate the field at half, and try again. We append three dots, in
* order to show that this is truncated. */
if (mh.msg_iov != copy) {
/* We don't want to modify the caller's iovec, hence let's create our
* own array, consisting of two new iovecs, where the first is a
* (truncated) copy of what we want to send, and the second one
* contains the trailing dots. */
copy[0] = iovec[i];
copy[1] = (struct iovec) {
.iov_base = (char[]) { '.', '.', '.' },
.iov_len = 3,
};
mh.msg_iov = copy;
mh.msg_iovlen = 2;
}
copy[0].iov_len /= 2; /* halve it, and try again */
continue;
}
n = send(fd, iovec[i].iov_base, iovec[i].iov_len, MSG_NOSIGNAL);
if (n < 0)
return log_error_errno(errno, "Failed to send coredump datagram: %m");
}
}
r = send_one_fd(fd, input_fd, 0);