X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fjournal%2Fjournal-send.c;h=bfc404e3750cd3856d9ee0df43a48f43852f8bea;hp=960c5776b0350bf2e6b9828a19361d8b3c9d0efe;hb=c79e98eadd3056a36a662699fa650db5b1bca0c3;hpb=65b3903ff576488eaabb51d3c4fbf9c73d867d7c diff --git a/src/journal/journal-send.c b/src/journal/journal-send.c index 960c5776b..bfc404e37 100644 --- a/src/journal/journal-send.c +++ b/src/journal/journal-send.c @@ -66,7 +66,7 @@ retry: fd_inc_sndbuf(fd, SNDBUF_SIZE); if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) { - close_nointr_nofail(fd); + safe_close(fd); goto retry; } @@ -198,7 +198,8 @@ finish: _public_ int sd_journal_sendv(const struct iovec *iov, int n) { PROTECT_ERRNO; - int fd, buffer_fd; + int fd, r; + _cleanup_close_ int buffer_fd = -1; struct iovec *w; uint64_t *l; int i, j = 0; @@ -217,6 +218,7 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { } control; struct cmsghdr *cmsg; bool have_syslog_identifier = false; + bool seal = true; assert_return(iov, -EINVAL); assert_return(n > 0, -EINVAL); @@ -303,21 +305,34 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { if (errno != EMSGSIZE && errno != ENOBUFS) return -errno; - /* Message doesn't fit... Let's dump the data in a temporary - * file and just pass a file descriptor of it to the other - * side. + /* Message doesn't fit... Let's dump the data in a memfd or + * temporary file and just pass a file descriptor of it to the + * other side. * - * We use /dev/shm instead of /tmp here, since we want this to - * be a tmpfs, and one that is available from early boot on - * and where unprivileged users can create files. */ - buffer_fd = open_tmpfile("/dev/shm", O_RDWR | O_CLOEXEC); - if (buffer_fd < 0) - return buffer_fd; - - n = writev_safe(buffer_fd, w, j); - if (n < 0) { - close_nointr_nofail(buffer_fd); + * For the temporary files we use /dev/shm instead of /tmp + * here, since we want this to be a tmpfs, and one that is + * available from early boot on and where unprivileged users + * can create files. */ + buffer_fd = memfd_create("journal-message", MFD_ALLOW_SEALING | MFD_CLOEXEC); + if (buffer_fd < 0) { + if (errno == ENOSYS) { + buffer_fd = open_tmpfile("/dev/shm", O_RDWR | O_CLOEXEC); + if (buffer_fd < 0) + return buffer_fd; + + seal = false; + } else + return -errno; + } + + n = writev(buffer_fd, w, j); + if (n < 0) return -errno; + + if (seal) { + r = fcntl(buffer_fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL); + if (r < 0) + return -errno; } mh.msg_iov = NULL; @@ -336,8 +351,6 @@ _public_ int sd_journal_sendv(const struct iovec *iov, int n) { mh.msg_controllen = cmsg->cmsg_len; k = sendmsg(fd, &mh, MSG_NOSIGNAL); - close_nointr_nofail(buffer_fd); - if (k < 0) return -errno; @@ -398,10 +411,10 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve .un.sun_family = AF_UNIX, .un.sun_path = "/run/systemd/journal/stdout", }; - int fd; + _cleanup_close_ int fd = -1; char *header; size_t l; - ssize_t r; + int r; assert_return(priority >= 0, -EINVAL); assert_return(priority <= 7, -EINVAL); @@ -411,15 +424,11 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve return -errno; r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path)); - if (r < 0) { - close_nointr_nofail(fd); + if (r < 0) return -errno; - } - if (shutdown(fd, SHUT_RD) < 0) { - close_nointr_nofail(fd); + if (shutdown(fd, SHUT_RD) < 0) return -errno; - } fd_inc_sndbuf(fd, SNDBUF_SIZE); @@ -443,18 +452,16 @@ _public_ int sd_journal_stream_fd(const char *identifier, int priority, int leve header[l++] = '0'; header[l++] = '\n'; - r = loop_write(fd, header, l, false); - if (r < 0) { - close_nointr_nofail(fd); - return (int) r; - } + r = (int) loop_write(fd, header, l, false); + if (r < 0) + return r; - if ((size_t) r != l) { - close_nointr_nofail(fd); + if ((size_t) r != l) return -errno; - } - return fd; + r = fd; + fd = -1; + return r; } _public_ int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) {