a19bc6
From 0e39139e505a8310ae8530fb2463a9e8f2170d2f Mon Sep 17 00:00:00 2001
a19bc6
From: HATAYAMA Daisuke <d.hatayama@jp.fujitsu.com>
a19bc6
Date: Sat, 24 Sep 2016 21:56:07 +0900
a19bc6
Subject: [PATCH] sysctl: configure kernel parameters in the order they occur
a19bc6
 in each sysctl configuration files (#4205)
a19bc6
a19bc6
Currently, systemd-sysctl command configures kernel parameters in each sysctl
a19bc6
configuration files in random order due to characteristics of iterator of
a19bc6
Hashmap.
a19bc6
a19bc6
However, kernel parameters need to be configured in the order they occur in
a19bc6
each sysctl configuration files.
a19bc6
a19bc6
- For example, consider fs.suid_coredump and kernel.core_pattern. If
a19bc6
  fs.suid_coredump=2 is configured before kernel.core_pattern= whose default
a19bc6
  value is "core", then kernel outputs the following message:
a19bc6
a19bc6
      Unsafe core_pattern used with suid_dumpable=2. Pipe handler or fully qualified core dump path required.
a19bc6
a19bc6
  Note that the security issue mentioned in this message has already been fixed
a19bc6
  on recent kernels, so this is just a warning message on such kernels. But
a19bc6
  it's still confusing to users that this message is output on some boot and
a19bc6
  not output on another boot.
a19bc6
a19bc6
- I don't know but there could be other kernel parameters that are significant
a19bc6
  in the order they are configured.
a19bc6
a19bc6
- The legacy sysctl command configures kernel parameters in the order they
a19bc6
  occur in each sysctl configuration files. Although I didn't find any official
a19bc6
  specification explaining this behavior of sysctl command, I don't think there
a19bc6
  is any meaningful reason to change this behavior, in particular, to the
a19bc6
  random one.
a19bc6
a19bc6
This commit does the change by simply using OrderedHashmap instead of
a19bc6
Hashmap.
a19bc6
a19bc6
(cherry picked from commit 886cf982d3018f7451f0548dadbc05bd2d583bb6)
a19bc6
a19bc6
Resolves: #1382244
a19bc6
---
a19bc6
 src/sysctl/sysctl.c | 20 ++++++++++----------
a19bc6
 1 file changed, 10 insertions(+), 10 deletions(-)
a19bc6
a19bc6
diff --git a/src/sysctl/sysctl.c b/src/sysctl/sysctl.c
a19bc6
index 4fb293b..bb2bea7 100644
a19bc6
--- a/src/sysctl/sysctl.c
a19bc6
+++ b/src/sysctl/sysctl.c
a19bc6
@@ -90,14 +90,14 @@ static int apply_sysctl(const char *property, const char *value) {
a19bc6
         return r;
a19bc6
 }
a19bc6
 
a19bc6
-static int apply_all(Hashmap *sysctl_options) {
a19bc6
-        int r = 0;
a19bc6
+static int apply_all(OrderedHashmap *sysctl_options) {
a19bc6
+        int r;
a19bc6
         char *property, *value;
a19bc6
         Iterator i;
a19bc6
 
a19bc6
         assert(sysctl_options);
a19bc6
 
a19bc6
-        HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
a19bc6
+        ORDERED_HASHMAP_FOREACH_KEY(value, property, sysctl_options, i) {
a19bc6
                 int k;
a19bc6
 
a19bc6
                 k = apply_sysctl(property, value);
a19bc6
@@ -107,7 +107,7 @@ static int apply_all(Hashmap *sysctl_options) {
a19bc6
         return r;
a19bc6
 }
a19bc6
 
a19bc6
-static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_enoent) {
a19bc6
+static int parse_file(OrderedHashmap *sysctl_options, const char *path, bool ignore_enoent) {
a19bc6
         _cleanup_fclose_ FILE *f = NULL;
a19bc6
         int r;
a19bc6
 
a19bc6
@@ -171,13 +171,13 @@ static int parse_file(Hashmap *sysctl_options, const char *path, bool ignore_eno
a19bc6
                 }
a19bc6
 
a19bc6
 found:
a19bc6
-                existing = hashmap_get2(sysctl_options, p, &v);
a19bc6
+                existing = ordered_hashmap_get2(sysctl_options, p, &v);
a19bc6
                 if (existing) {
a19bc6
                         if (streq(value, existing))
a19bc6
                                 continue;
a19bc6
 
a19bc6
                         log_debug("Overwriting earlier assignment of %s in file '%s'.", p, path);
a19bc6
-                        free(hashmap_remove(sysctl_options, p));
a19bc6
+                        free(ordered_hashmap_remove(sysctl_options, p));
a19bc6
                         free(v);
a19bc6
                 }
a19bc6
 
a19bc6
@@ -191,7 +191,7 @@ found:
a19bc6
                         return log_oom();
a19bc6
                 }
a19bc6
 
a19bc6
-                k = hashmap_put(sysctl_options, property, new_value);
a19bc6
+                k = ordered_hashmap_put(sysctl_options, property, new_value);
a19bc6
                 if (k < 0) {
a19bc6
                         log_error_errno(k, "Failed to add sysctl variable %s to hashmap: %m", property);
a19bc6
                         free(property);
a19bc6
@@ -277,7 +277,7 @@ static int parse_argv(int argc, char *argv[]) {
a19bc6
 
a19bc6
 int main(int argc, char *argv[]) {
a19bc6
         int r = 0, k;
a19bc6
-        Hashmap *sysctl_options;
a19bc6
+        OrderedHashmap *sysctl_options;
a19bc6
 
a19bc6
         r = parse_argv(argc, argv);
a19bc6
         if (r <= 0)
a19bc6
@@ -289,7 +289,7 @@ int main(int argc, char *argv[]) {
a19bc6
 
a19bc6
         umask(0022);
a19bc6
 
a19bc6
-        sysctl_options = hashmap_new(&string_hash_ops);
a19bc6
+        sysctl_options = ordered_hashmap_new(&string_hash_ops);
a19bc6
         if (!sysctl_options) {
a19bc6
                 r = log_oom();
a19bc6
                 goto finish;
a19bc6
@@ -331,7 +331,7 @@ int main(int argc, char *argv[]) {
a19bc6
                 r = k;
a19bc6
 
a19bc6
 finish:
a19bc6
-        hashmap_free_free_free(sysctl_options);
a19bc6
+        ordered_hashmap_free_free_free(sysctl_options);
a19bc6
         strv_free(arg_prefixes);
a19bc6
 
a19bc6
         return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;