Zbigniew Jędrzejewski-Szmek 126222
From 9b9103a07cc32fa76be4c71fcd9a93b5d946edd4 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 126222
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek 126222
Date: Sat, 28 Dec 2013 19:33:23 -0500
Zbigniew Jędrzejewski-Szmek 126222
Subject: [PATCH] journal: fix access to munmapped memory in
Zbigniew Jędrzejewski-Szmek 126222
 sd_journal_enumerate_unique
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
sd_j_e_u needs to keep a reference to an object while comparing it
Zbigniew Jędrzejewski-Szmek 126222
with possibly duplicate objects in other files. Because the size of
Zbigniew Jędrzejewski-Szmek 126222
mmap cache is limited, with enough files and object to compare to,
Zbigniew Jędrzejewski-Szmek 126222
at some point the object being compared would be munmapped, resulting
Zbigniew Jędrzejewski-Szmek 126222
in a segmentation fault.
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
Fix this issue by turning keep_always into a reference count that can
Zbigniew Jędrzejewski-Szmek 126222
be increased and decreased. Other callers which set keep_always=true
Zbigniew Jędrzejewski-Szmek 126222
are unmodified: their references are never released but are ignored
Zbigniew Jędrzejewski-Szmek 126222
when the whole file is closed, which happens at some point. keep_always
Zbigniew Jędrzejewski-Szmek 126222
is increased in sd_j_e_u and later on released.
Zbigniew Jędrzejewski-Szmek 126222
---
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/journal-file.c   |  5 +---
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/journal-file.h   | 24 +++++++++++++++++++
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/journal-verify.c |  4 ----
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/mmap-cache.c     | 57 +++++++++++++++++++++++++++++++++++---------
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/mmap-cache.h     | 18 +++++++++++++-
Zbigniew Jędrzejewski-Szmek 126222
 src/journal/sd-journal.c     | 18 +++++++++++---
Zbigniew Jędrzejewski-Szmek 126222
 6 files changed, 103 insertions(+), 23 deletions(-)
Zbigniew Jędrzejewski-Szmek 126222
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/journal-file.c b/src/journal/journal-file.c
Zbigniew Jędrzejewski-Szmek 126222
index ba65464..4d9787a 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/journal-file.c
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/journal-file.c
Zbigniew Jędrzejewski-Szmek 126222
@@ -419,7 +419,6 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
Zbigniew Jędrzejewski-Szmek 126222
         void *t;
Zbigniew Jędrzejewski-Szmek 126222
         Object *o;
Zbigniew Jędrzejewski-Szmek 126222
         uint64_t s;
Zbigniew Jędrzejewski-Szmek 126222
-        unsigned context;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         assert(f);
Zbigniew Jędrzejewski-Szmek 126222
         assert(ret);
Zbigniew Jędrzejewski-Szmek 126222
@@ -428,10 +427,8 @@ int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Objec
Zbigniew Jędrzejewski-Szmek 126222
         if (!VALID64(offset))
Zbigniew Jędrzejewski-Szmek 126222
                 return -EFAULT;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        /* One context for each type, plus one catch-all for the rest */
Zbigniew Jędrzejewski-Szmek 126222
-        context = type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        r = journal_file_move_to(f, context, false, offset, sizeof(ObjectHeader), &t);
Zbigniew Jędrzejewski-Szmek 126222
+        r = journal_file_move_to(f, type_to_context(type), false, offset, sizeof(ObjectHeader), &t);
Zbigniew Jędrzejewski-Szmek 126222
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 126222
                 return r;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/journal-file.h b/src/journal/journal-file.h
Zbigniew Jędrzejewski-Szmek 126222
index 50bdb67..0bd23f7 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/journal-file.h
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/journal-file.h
Zbigniew Jędrzejewski-Szmek 126222
@@ -128,6 +128,10 @@ int journal_file_open_reliably(
Zbigniew Jędrzejewski-Szmek 126222
 #define ALIGN64(x) (((x) + 7ULL) & ~7ULL)
Zbigniew Jędrzejewski-Szmek 126222
 #define VALID64(x) (((x) & 7ULL) == 0ULL)
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
+/* Use six characters to cover the offsets common in smallish journal
Zbigniew Jędrzejewski-Szmek 126222
+ * files without adding too many zeros. */
Zbigniew Jędrzejewski-Szmek 126222
+#define OFSfmt "%06"PRIx64
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
 static inline bool VALID_REALTIME(uint64_t u) {
Zbigniew Jędrzejewski-Szmek 126222
         /* This considers timestamps until the year 3112 valid. That should be plenty room... */
Zbigniew Jędrzejewski-Szmek 126222
         return u > 0 && u < (1ULL << 55);
Zbigniew Jędrzejewski-Szmek 126222
@@ -197,3 +201,23 @@ int journal_file_get_cutoff_realtime_usec(JournalFile *f, usec_t *from, usec_t *
Zbigniew Jędrzejewski-Szmek 126222
 int journal_file_get_cutoff_monotonic_usec(JournalFile *f, sd_id128_t boot, usec_t *from, usec_t *to);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
 bool journal_file_rotate_suggested(JournalFile *f, usec_t max_file_usec);
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+static unsigned type_to_context(int type) {
Zbigniew Jędrzejewski-Szmek 126222
+        /* One context for each type, plus one catch-all for the rest */
Zbigniew Jędrzejewski-Szmek 126222
+        return type > 0 && type < _OBJECT_TYPE_MAX ? type : 0;
Zbigniew Jędrzejewski-Szmek 126222
+}
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+static inline int journal_file_object_keep(JournalFile *f, Object *o, uint64_t offset) {
Zbigniew Jędrzejewski-Szmek 126222
+        unsigned context = type_to_context(o->object.type);
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        return mmap_cache_get(f->mmap, f->fd, f->prot, context, true,
Zbigniew Jędrzejewski-Szmek 126222
+                              offset, o->object.size, &f->last_stat, NULL);
Zbigniew Jędrzejewski-Szmek 126222
+}
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+static inline int journal_file_object_release(JournalFile *f, Object *o, uint64_t offset) {
Zbigniew Jędrzejewski-Szmek 126222
+        unsigned context = type_to_context(o->object.type);
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        return mmap_cache_release(f->mmap, f->fd, f->prot, context,
Zbigniew Jędrzejewski-Szmek 126222
+                                  offset, o->object.size);
Zbigniew Jędrzejewski-Szmek 126222
+}
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/journal-verify.c b/src/journal/journal-verify.c
Zbigniew Jędrzejewski-Szmek 126222
index 82b0f0a..f2422ff 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/journal-verify.c
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/journal-verify.c
Zbigniew Jędrzejewski-Szmek 126222
@@ -34,10 +34,6 @@
Zbigniew Jędrzejewski-Szmek 126222
 #include "compress.h"
Zbigniew Jędrzejewski-Szmek 126222
 #include "fsprg.h"
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-/* Use six characters to cover the offsets common in smallish journal
Zbigniew Jędrzejewski-Szmek 126222
- * files without adding to many zeros. */
Zbigniew Jędrzejewski-Szmek 126222
-#define OFSfmt "%06"PRIx64
Zbigniew Jędrzejewski-Szmek 126222
-
Zbigniew Jędrzejewski-Szmek 126222
 static int journal_file_object_verify(JournalFile *f, uint64_t offset, Object *o) {
Zbigniew Jędrzejewski-Szmek 126222
         uint64_t i;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/mmap-cache.c b/src/journal/mmap-cache.c
Zbigniew Jędrzejewski-Szmek 126222
index 42a8a7d..24b2bb8 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/mmap-cache.c
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/mmap-cache.c
Zbigniew Jędrzejewski-Szmek 126222
@@ -38,7 +38,7 @@ typedef struct FileDescriptor FileDescriptor;
Zbigniew Jędrzejewski-Szmek 126222
 struct Window {
Zbigniew Jędrzejewski-Szmek 126222
         MMapCache *cache;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        bool keep_always;
Zbigniew Jędrzejewski-Szmek 126222
+        unsigned keep_always;
Zbigniew Jędrzejewski-Szmek 126222
         bool in_unused;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         int prot;
Zbigniew Jędrzejewski-Szmek 126222
@@ -185,7 +185,7 @@ static void context_detach_window(Context *c) {
Zbigniew Jędrzejewski-Szmek 126222
         c->window = NULL;
Zbigniew Jędrzejewski-Szmek 126222
         LIST_REMOVE(Context, by_window, w->contexts, c);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        if (!w->contexts && !w->keep_always) {
Zbigniew Jędrzejewski-Szmek 126222
+        if (!w->contexts && w->keep_always == 0) {
Zbigniew Jędrzejewski-Szmek 126222
                 /* Not used anymore? */
Zbigniew Jędrzejewski-Szmek 126222
                 LIST_PREPEND(Window, unused, c->cache->unused, w);
Zbigniew Jędrzejewski-Szmek 126222
                 if (!c->cache->last_unused)
Zbigniew Jędrzejewski-Szmek 126222
@@ -360,7 +360,6 @@ static int try_context(
Zbigniew Jędrzejewski-Szmek 126222
         assert(m->n_ref > 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(fd >= 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(size > 0);
Zbigniew Jędrzejewski-Szmek 126222
-        assert(ret);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         c = hashmap_get(m->contexts, UINT_TO_PTR(context+1));
Zbigniew Jędrzejewski-Szmek 126222
         if (!c)
Zbigniew Jędrzejewski-Szmek 126222
@@ -378,9 +377,10 @@ static int try_context(
Zbigniew Jędrzejewski-Szmek 126222
                 return 0;
Zbigniew Jędrzejewski-Szmek 126222
         }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        c->window->keep_always = c->window->keep_always || keep_always;
Zbigniew Jędrzejewski-Szmek 126222
+        c->window->keep_always += keep_always;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
Zbigniew Jędrzejewski-Szmek 126222
+        if (ret)
Zbigniew Jędrzejewski-Szmek 126222
+                *ret = (uint8_t*) c->window->ptr + (offset - c->window->offset);
Zbigniew Jędrzejewski-Szmek 126222
         return 1;
Zbigniew Jędrzejewski-Szmek 126222
 }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
@@ -402,7 +402,6 @@ static int find_mmap(
Zbigniew Jędrzejewski-Szmek 126222
         assert(m->n_ref > 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(fd >= 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(size > 0);
Zbigniew Jędrzejewski-Szmek 126222
-        assert(ret);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
Zbigniew Jędrzejewski-Szmek 126222
         if (!f)
Zbigniew Jędrzejewski-Szmek 126222
@@ -422,9 +421,10 @@ static int find_mmap(
Zbigniew Jędrzejewski-Szmek 126222
                 return -ENOMEM;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         context_attach_window(c, w);
Zbigniew Jędrzejewski-Szmek 126222
-        w->keep_always = w->keep_always || keep_always;
Zbigniew Jędrzejewski-Szmek 126222
+        w->keep_always += keep_always;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        *ret = (uint8_t*) w->ptr + (offset - w->offset);
Zbigniew Jędrzejewski-Szmek 126222
+        if (ret)
Zbigniew Jędrzejewski-Szmek 126222
+                *ret = (uint8_t*) w->ptr + (offset - w->offset);
Zbigniew Jędrzejewski-Szmek 126222
         return 1;
Zbigniew Jędrzejewski-Szmek 126222
 }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
@@ -450,7 +450,6 @@ static int add_mmap(
Zbigniew Jędrzejewski-Szmek 126222
         assert(m->n_ref > 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(fd >= 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(size > 0);
Zbigniew Jędrzejewski-Szmek 126222
-        assert(ret);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         woffset = offset & ~((uint64_t) page_size() - 1ULL);
Zbigniew Jędrzejewski-Szmek 126222
         wsize = size + (offset - woffset);
Zbigniew Jędrzejewski-Szmek 126222
@@ -520,7 +519,8 @@ static int add_mmap(
Zbigniew Jędrzejewski-Szmek 126222
         c->window = w;
Zbigniew Jędrzejewski-Szmek 126222
         LIST_PREPEND(Context, by_window, w->contexts, c);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-        *ret = (uint8_t*) w->ptr + (offset - w->offset);
Zbigniew Jędrzejewski-Szmek 126222
+        if (ret)
Zbigniew Jędrzejewski-Szmek 126222
+                *ret = (uint8_t*) w->ptr + (offset - w->offset);
Zbigniew Jędrzejewski-Szmek 126222
         return 1;
Zbigniew Jędrzejewski-Szmek 126222
 }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
@@ -541,7 +541,6 @@ int mmap_cache_get(
Zbigniew Jędrzejewski-Szmek 126222
         assert(m->n_ref > 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(fd >= 0);
Zbigniew Jędrzejewski-Szmek 126222
         assert(size > 0);
Zbigniew Jędrzejewski-Szmek 126222
-        assert(ret);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         /* Check whether the current context is the right one already */
Zbigniew Jędrzejewski-Szmek 126222
         r = try_context(m, fd, prot, context, keep_always, offset, size, ret);
Zbigniew Jędrzejewski-Szmek 126222
@@ -563,6 +562,42 @@ int mmap_cache_get(
Zbigniew Jędrzejewski-Szmek 126222
         return add_mmap(m, fd, prot, context, keep_always, offset, size, st, ret);
Zbigniew Jędrzejewski-Szmek 126222
 }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
+int mmap_cache_release(
Zbigniew Jędrzejewski-Szmek 126222
+                MMapCache *m,
Zbigniew Jędrzejewski-Szmek 126222
+                int fd,
Zbigniew Jędrzejewski-Szmek 126222
+                int prot,
Zbigniew Jędrzejewski-Szmek 126222
+                unsigned context,
Zbigniew Jędrzejewski-Szmek 126222
+                uint64_t offset,
Zbigniew Jędrzejewski-Szmek 126222
+                size_t size) {
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        FileDescriptor *f;
Zbigniew Jędrzejewski-Szmek 126222
+        Window *w;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        assert(m);
Zbigniew Jędrzejewski-Szmek 126222
+        assert(m->n_ref > 0);
Zbigniew Jędrzejewski-Szmek 126222
+        assert(fd >= 0);
Zbigniew Jędrzejewski-Szmek 126222
+        assert(size > 0);
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        f = hashmap_get(m->fds, INT_TO_PTR(fd + 1));
Zbigniew Jędrzejewski-Szmek 126222
+        if (!f)
Zbigniew Jędrzejewski-Szmek 126222
+                return -EBADF;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        assert(f->fd == fd);
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        LIST_FOREACH(by_fd, w, f->windows)
Zbigniew Jędrzejewski-Szmek 126222
+                if (window_matches(w, fd, prot, offset, size))
Zbigniew Jędrzejewski-Szmek 126222
+                        break;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        if (!w)
Zbigniew Jędrzejewski-Szmek 126222
+                return -ENOENT;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        if (w->keep_always == 0)
Zbigniew Jędrzejewski-Szmek 126222
+                return -ENOLCK;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+        w->keep_always -= 1;
Zbigniew Jędrzejewski-Szmek 126222
+        return 0;
Zbigniew Jędrzejewski-Szmek 126222
+}
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
 void mmap_cache_close_fd(MMapCache *m, int fd) {
Zbigniew Jędrzejewski-Szmek 126222
         FileDescriptor *f;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/mmap-cache.h b/src/journal/mmap-cache.h
Zbigniew Jędrzejewski-Szmek 126222
index 912336d..647555a 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/mmap-cache.h
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/mmap-cache.h
Zbigniew Jędrzejewski-Szmek 126222
@@ -31,7 +31,23 @@ MMapCache* mmap_cache_new(void);
Zbigniew Jędrzejewski-Szmek 126222
 MMapCache* mmap_cache_ref(MMapCache *m);
Zbigniew Jędrzejewski-Szmek 126222
 MMapCache* mmap_cache_unref(MMapCache *m);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
-int mmap_cache_get(MMapCache *m, int fd, int prot, unsigned context, bool keep_always, uint64_t offset, size_t size, struct stat *st, void **ret);
Zbigniew Jędrzejewski-Szmek 126222
+int mmap_cache_get(
Zbigniew Jędrzejewski-Szmek 126222
+        MMapCache *m,
Zbigniew Jędrzejewski-Szmek 126222
+        int fd,
Zbigniew Jędrzejewski-Szmek 126222
+        int prot,
Zbigniew Jędrzejewski-Szmek 126222
+        unsigned context,
Zbigniew Jędrzejewski-Szmek 126222
+        bool keep_always,
Zbigniew Jędrzejewski-Szmek 126222
+        uint64_t offset,
Zbigniew Jędrzejewski-Szmek 126222
+        size_t size,
Zbigniew Jędrzejewski-Szmek 126222
+        struct stat *st,
Zbigniew Jędrzejewski-Szmek 126222
+        void **ret);
Zbigniew Jędrzejewski-Szmek 126222
+int mmap_cache_release(
Zbigniew Jędrzejewski-Szmek 126222
+        MMapCache *m,
Zbigniew Jędrzejewski-Szmek 126222
+        int fd,
Zbigniew Jędrzejewski-Szmek 126222
+        int prot,
Zbigniew Jędrzejewski-Szmek 126222
+        unsigned context,
Zbigniew Jędrzejewski-Szmek 126222
+        uint64_t offset,
Zbigniew Jędrzejewski-Szmek 126222
+        size_t size);
Zbigniew Jędrzejewski-Szmek 126222
 void mmap_cache_close_fd(MMapCache *m, int fd);
Zbigniew Jędrzejewski-Szmek 126222
 void mmap_cache_close_context(MMapCache *m, unsigned context);
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
diff --git a/src/journal/sd-journal.c b/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek 126222
index 52abbe9..46c3feb 100644
Zbigniew Jędrzejewski-Szmek 126222
--- a/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek 126222
+++ b/src/journal/sd-journal.c
Zbigniew Jędrzejewski-Szmek 126222
@@ -2508,9 +2508,7 @@ _public_ int sd_journal_query_unique(sd_journal *j, const char *field) {
Zbigniew Jędrzejewski-Szmek 126222
 }
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
 _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l) {
Zbigniew Jędrzejewski-Szmek 126222
-        Object *o;
Zbigniew Jędrzejewski-Szmek 126222
         size_t k;
Zbigniew Jędrzejewski-Szmek 126222
-        int r;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
         if (!j)
Zbigniew Jędrzejewski-Szmek 126222
                 return -EINVAL;
Zbigniew Jędrzejewski-Szmek 126222
@@ -2535,9 +2533,11 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
Zbigniew Jędrzejewski-Szmek 126222
         for (;;) {
Zbigniew Jędrzejewski-Szmek 126222
                 JournalFile *of;
Zbigniew Jędrzejewski-Szmek 126222
                 Iterator i;
Zbigniew Jędrzejewski-Szmek 126222
+                Object *o;
Zbigniew Jędrzejewski-Szmek 126222
                 const void *odata;
Zbigniew Jędrzejewski-Szmek 126222
                 size_t ol;
Zbigniew Jędrzejewski-Szmek 126222
                 bool found;
Zbigniew Jędrzejewski-Szmek 126222
+                int r;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
                 /* Proceed to next data object in the field's linked list */
Zbigniew Jędrzejewski-Szmek 126222
                 if (j->unique_offset == 0) {
Zbigniew Jędrzejewski-Szmek 126222
@@ -2574,8 +2574,16 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
Zbigniew Jędrzejewski-Szmek 126222
                         return r;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
                 /* Let's do the type check by hand, since we used 0 context above. */
Zbigniew Jędrzejewski-Szmek 126222
-                if (o->object.type != OBJECT_DATA)
Zbigniew Jędrzejewski-Szmek 126222
+                if (o->object.type != OBJECT_DATA) {
Zbigniew Jędrzejewski-Szmek 126222
+                        log_error("%s:offset " OFSfmt ": object has type %d, expected %d",
Zbigniew Jędrzejewski-Szmek 126222
+                                  j->unique_file->path, j->unique_offset,
Zbigniew Jędrzejewski-Szmek 126222
+                                  o->object.type, OBJECT_DATA);
Zbigniew Jędrzejewski-Szmek 126222
                         return -EBADMSG;
Zbigniew Jędrzejewski-Szmek 126222
+                }
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
+                r = journal_file_object_keep(j->unique_file, o, j->unique_offset);
Zbigniew Jędrzejewski-Szmek 126222
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 126222
+                        return r;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
                 r = return_data(j, j->unique_file, o, &odata, &ol);
Zbigniew Jędrzejewski-Szmek 126222
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 126222
@@ -2609,6 +2617,10 @@ _public_ int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_
Zbigniew Jędrzejewski-Szmek 126222
                 if (found)
Zbigniew Jędrzejewski-Szmek 126222
                         continue;
Zbigniew Jędrzejewski-Szmek 126222
 
Zbigniew Jędrzejewski-Szmek 126222
+                r = journal_file_object_release(j->unique_file, o, j->unique_offset);
Zbigniew Jędrzejewski-Szmek 126222
+                if (r < 0)
Zbigniew Jędrzejewski-Szmek 126222
+                        return r;
Zbigniew Jędrzejewski-Szmek 126222
+
Zbigniew Jędrzejewski-Szmek 126222
                 r = return_data(j, j->unique_file, o, data, l);
Zbigniew Jędrzejewski-Szmek 126222
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 126222
                         return r;