chiark / gitweb /
fix a couple of things found with the llvm static analyzer
[elogind.git] / src / journal / journald.c
index fb298be758f91058028feb46aa140becfcc6485b..97d2ec05c7873eee59cab9aa2aac88ad4e271fff 100644 (file)
@@ -6,16 +6,16 @@
   Copyright 2011 Lennart Poettering
 
   systemd is free software; you can redistribute it and/or modify it
-  under the terms of the GNU General Public License as published by
-  the Free Software Foundation; either version 2 of the License, or
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
   (at your option) any later version.
 
   systemd is distributed in the hope that it will be useful, but
   WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-  General Public License for more details.
+  Lesser General Public License for more details.
 
-  You should have received a copy of the GNU General Public License
+  You should have received a copy of the GNU Lesser General Public License
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
 #include <sys/ioctl.h>
 #include <linux/sockios.h>
 #include <sys/statvfs.h>
-#include <sys/user.h>
 
 #include <systemd/sd-journal.h>
 #include <systemd/sd-login.h>
 #include <systemd/sd-messages.h>
 #include <systemd/sd-daemon.h>
 
+#include "mkdir.h"
 #include "hashmap.h"
 #include "journal-file.h"
 #include "socket-util.h"
@@ -154,24 +154,25 @@ static uint64_t available_space(Server *s) {
         for (;;) {
                 struct stat st;
                 struct dirent buf, *de;
-                int k;
 
-                k = readdir_r(d, &buf, &de);
-                if (k != 0) {
-                        r = -k;
-                        goto finish;
-                }
+                r = readdir_r(d, &buf, &de);
+                if (r != 0)
+                        break;
 
                 if (!de)
                         break;
 
-                if (!dirent_is_file_with_suffix(de, ".journal"))
+                if (!endswith(de->d_name, ".journal") &&
+                    !endswith(de->d_name, ".journal~"))
                         continue;
 
                 if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0)
                         continue;
 
-                sum += (uint64_t) st.st_blocks * (uint64_t) st.st_blksize;
+                if (!S_ISREG(st.st_mode))
+                        continue;
+
+                sum += (uint64_t) st.st_blocks * 512UL;
         }
 
         avail = sum >= m->max_use ? 0 : m->max_use - sum;
@@ -330,20 +331,26 @@ static void server_rotate(Server *s) {
                 r = journal_file_rotate(&s->runtime_journal);
                 if (r < 0)
                         log_error("Failed to rotate %s: %s", s->runtime_journal->path, strerror(-r));
+                else
+                        server_fix_perms(s, s->runtime_journal, 0);
         }
 
         if (s->system_journal) {
                 r = journal_file_rotate(&s->system_journal);
                 if (r < 0)
                         log_error("Failed to rotate %s: %s", s->system_journal->path, strerror(-r));
+                else
+                        server_fix_perms(s, s->system_journal, 0);
         }
 
         HASHMAP_FOREACH_KEY(f, k, s->user_journals, i) {
                 r = journal_file_rotate(&f);
                 if (r < 0)
                         log_error("Failed to rotate %s: %s", f->path, strerror(-r));
-                else
+                else {
                         hashmap_replace(s->user_journals, k, f);
+                        server_fix_perms(s, s->system_journal, PTR_TO_UINT32(k));
+                }
         }
 }
 
@@ -602,7 +609,15 @@ retry:
         else {
                 r = journal_file_append_entry(f, NULL, iovec, n, &s->seqnum, NULL, NULL);
 
-                if ((r == -EBADMSG || r == -E2BIG) && !vacuumed) {
+                if ((r == -E2BIG || /* hit limit */
+                     r == -EFBIG || /* hit fs limit */
+                     r == -EDQUOT || /* quota hit */
+                     r == -ENOSPC || /* disk full */
+                     r == -EBADMSG || /* corrupted */
+                     r == -ENODATA || /* truncated */
+                     r == -EHOSTDOWN || /* other machine */
+                     r == -EPROTONOSUPPORT) && /* unsupported feature */
+                    !vacuumed) {
 
                         if (r == -E2BIG)
                                 log_info("Allocation limit reached, rotating.");
@@ -1133,7 +1148,7 @@ static void process_native_message(
         char *identifier = NULL, *message = NULL;
 
         assert(s);
-        assert(buffer || n == 0);
+        assert(buffer || buffer_size == 0);
 
         p = buffer;
         remaining = buffer_size;
@@ -1244,6 +1259,7 @@ static void process_native_message(
                         p = e + 1;
                         continue;
                 } else {
+                        le64_t l_le;
                         uint64_t l;
                         char *k;
 
@@ -1252,8 +1268,8 @@ static void process_native_message(
                                 break;
                         }
 
-                        memcpy(&l, e + 1, sizeof(uint64_t));
-                        l = le64toh(l);
+                        memcpy(&l_le, e + 1, sizeof(uint64_t));
+                        l = le64toh(l_le);
 
                         if (remaining < e - p + 1 + sizeof(uint64_t) + l + 1 ||
                             e[1+sizeof(uint64_t)+l] != '\n') {
@@ -1908,7 +1924,7 @@ static int system_journal_open(Server *s) {
                          * if it already exists, so that we can flush
                          * it into the system journal */
 
-                        r = journal_file_open_reliably(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
+                        r = journal_file_open(fn, O_RDWR, 0640, NULL, &s->runtime_journal);
                         free(fn);
 
                         if (r < 0) {
@@ -2134,10 +2150,20 @@ static int process_event(Server *s, struct epoll_event *ev) {
                         size_t label_len = 0;
                         union {
                                 struct cmsghdr cmsghdr;
+
+                                /* We use NAME_MAX space for the
+                                 * SELinux label here. The kernel
+                                 * currently enforces no limit, but
+                                 * according to suggestions from the
+                                 * SELinux people this will change and
+                                 * it will probably be identical to
+                                 * NAME_MAX. For now we use that, but
+                                 * this should be updated one day when
+                                 * the final limit is known.*/
                                 uint8_t buf[CMSG_SPACE(sizeof(struct ucred)) +
                                             CMSG_SPACE(sizeof(struct timeval)) +
-                                            CMSG_SPACE(sizeof(int)) +
-                                            CMSG_SPACE(PAGE_SIZE)]; /* selinux label */
+                                            CMSG_SPACE(sizeof(int)) + /* fd */
+                                            CMSG_SPACE(NAME_MAX)]; /* selinux label */
                         } control;
                         ssize_t n;
                         int v;
@@ -2454,7 +2480,7 @@ static int open_proc_kmsg(Server *s) {
                 return 0;
 
 
-        s->proc_kmsg_fd = open("/proc/kmsg", O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
+        s->proc_kmsg_fd = open("/proc/kmsg", O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
         if (s->proc_kmsg_fd < 0) {
                 log_warning("Failed to open /proc/kmsg, ignoring: %m");
                 return 0;
@@ -2559,7 +2585,7 @@ static int server_parse_config_file(Server *s) {
 
         assert(s);
 
-        fn = "/etc/systemd/systemd-journald.conf";
+        fn = "/etc/systemd/journald.conf";
         f = fopen(fn, "re");
         if (!f) {
                 if (errno == ENOENT)
@@ -2740,6 +2766,7 @@ int main(int argc, char *argv[]) {
         }
 
         log_set_target(LOG_TARGET_CONSOLE);
+        log_set_facility(LOG_SYSLOG);
         log_parse_environment();
         log_open();