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