Blame SOURCES/0371-tmpfiles-enforce-ordering-when-executing-lines.patch

17b0f1
From fd09d69b1bca2b4b602f4ee98d4749a39af04bb4 Mon Sep 17 00:00:00 2001
17b0f1
From: Lennart Poettering <lennart@poettering.net>
17b0f1
Date: Fri, 10 Apr 2015 16:22:22 +0200
17b0f1
Subject: [PATCH] tmpfiles: enforce ordering when executing lines
17b0f1
17b0f1
Always create files first, and then adjust their ACLs, xattrs, file
17b0f1
attributes, never the opposite. Previously the order was not
17b0f1
deterministic, thus possibly first adjusting ACLs/xattrs/file
17b0f1
attributes before actually creating the items.
17b0f1
17b0f1
Cherry-picked from: 17493fa5d17cadce3b773692d3eeab137de7d323
17b0f1
Resolves: #1365870
17b0f1
---
17b0f1
 src/tmpfiles/tmpfiles.c | 39 +++++++++++++++++++++++++++++++++++----
17b0f1
 1 file changed, 35 insertions(+), 4 deletions(-)
17b0f1
17b0f1
diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c
17b0f1
index 64c733aaa0..bda89df5be 100644
17b0f1
--- a/src/tmpfiles/tmpfiles.c
17b0f1
+++ b/src/tmpfiles/tmpfiles.c
17b0f1
@@ -78,18 +78,18 @@ typedef enum ItemType {
17b0f1
         COPY_FILES = 'C',
17b0f1
 
17b0f1
         /* These ones take globs */
17b0f1
+        WRITE_FILE = 'w',
17b0f1
         SET_XATTR = 't',
17b0f1
         RECURSIVE_SET_XATTR = 'T',
17b0f1
         SET_ACL = 'a',
17b0f1
         RECURSIVE_SET_ACL = 'A',
17b0f1
-        WRITE_FILE = 'w',
17b0f1
         IGNORE_PATH = 'x',
17b0f1
         IGNORE_DIRECTORY_PATH = 'X',
17b0f1
         REMOVE_PATH = 'r',
17b0f1
         RECURSIVE_REMOVE_PATH = 'R',
17b0f1
-        ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
17b0f1
         RELABEL_PATH = 'z',
17b0f1
         RECURSIVE_RELABEL_PATH = 'Z',
17b0f1
+        ADJUST_MODE = 'm', /* legacy, 'z' is identical to this */
17b0f1
 } ItemType;
17b0f1
 
17b0f1
 typedef struct Item {
17b0f1
@@ -1480,6 +1480,31 @@ static void item_array_free(ItemArray *a) {
17b0f1
         free(a);
17b0f1
 }
17b0f1
 
17b0f1
+static int item_compare(const void *a, const void *b) {
17b0f1
+        const Item *x = a, *y = b;
17b0f1
+
17b0f1
+        /* Make sure that the ownership taking item is put first, so
17b0f1
+         * that we first create the node, and then can adjust it */
17b0f1
+
17b0f1
+        if (takes_ownership(x->type) && !takes_ownership(y->type))
17b0f1
+                return -1;
17b0f1
+        if (!takes_ownership(x->type) && takes_ownership(y->type))
17b0f1
+                return 1;
17b0f1
+
17b0f1
+        return (int) x->type - (int) y->type;
17b0f1
+}
17b0f1
+
17b0f1
+static void item_array_sort(ItemArray *a) {
17b0f1
+
17b0f1
+        /* Sort an item array, to enforce stable ordering in which we
17b0f1
+         * apply things. */
17b0f1
+
17b0f1
+        if (a->count <= 1)
17b0f1
+                return;
17b0f1
+
17b0f1
+        qsort(a->items, a->count, sizeof(Item), item_compare);
17b0f1
+}
17b0f1
+
17b0f1
 static bool item_compatible(Item *a, Item *b) {
17b0f1
         assert(a);
17b0f1
         assert(b);
17b0f1
@@ -1806,6 +1831,8 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
17b0f1
                 return log_oom();
17b0f1
 
17b0f1
         memcpy(existing->items + existing->count++, &i, sizeof(i));
17b0f1
+        item_array_sort(existing);
17b0f1
+
17b0f1
         zero(i);
17b0f1
         return 0;
17b0f1
 }
17b0f1
@@ -2045,13 +2072,17 @@ int main(int argc, char *argv[]) {
17b0f1
                 }
17b0f1
         }
17b0f1
 
17b0f1
-        HASHMAP_FOREACH(a, globs, iterator) {
17b0f1
+        /* The non-globbing ones usually create things, hence we apply
17b0f1
+         * them first */
17b0f1
+        HASHMAP_FOREACH(a, items, iterator) {
17b0f1
                 k = process_item_array(a);
17b0f1
                 if (k < 0 && r == 0)
17b0f1
                         r = k;
17b0f1
         }
17b0f1
 
17b0f1
-        HASHMAP_FOREACH(a, items, iterator) {
17b0f1
+        /* The globbing ones usually alter things, hence we apply them
17b0f1
+         * second. */
17b0f1
+        HASHMAP_FOREACH(a, globs, iterator) {
17b0f1
                 k = process_item_array(a);
17b0f1
                 if (k < 0 && r == 0)
17b0f1
                         r = k;