]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/analyze/analyze-security.c
systemd-analyze: add new 'security' option to compare unit's overall exposure level...
[thirdparty/systemd.git] / src / analyze / analyze-security.c
index 6daa18ac1fabd1eebf0aa91ecdc34eccc3e50493..24500e3a5b9fd1af8ecf64216e33300db8c1f189 100644 (file)
@@ -1527,7 +1527,7 @@ static const struct security_assessor security_assessor_table[] = {
         },
 };
 
-static int assess(const SecurityInfo *info, Table *overview_table, AnalyzeSecurityFlags flags) {
+static int assess(const SecurityInfo *info, Table *overview_table, AnalyzeSecurityFlags flags, unsigned threshold) {
         static const struct {
                 uint64_t exposure;
                 const char *name;
@@ -1723,6 +1723,10 @@ static int assess(const SecurityInfo *info, Table *overview_table, AnalyzeSecuri
                         return table_log_add_error(r);
         }
 
+        /* Return error when overall exposure level is over threshold */
+        if (exposure > threshold)
+                return -EINVAL;
+
         return 0;
 }
 
@@ -2188,7 +2192,9 @@ static int acquire_security_info(sd_bus *bus, const char *name, SecurityInfo *in
         return 0;
 }
 
-static int analyze_security_one(sd_bus *bus, const char *name, Table *overview_table, AnalyzeSecurityFlags flags) {
+static int analyze_security_one(sd_bus *bus, const char *name, Table *overview_table,
+                                AnalyzeSecurityFlags flags, unsigned threshold) {
+
         _cleanup_(security_info_freep) SecurityInfo *info = security_info_new();
         if (!info)
                 return log_oom();
@@ -2204,7 +2210,7 @@ static int analyze_security_one(sd_bus *bus, const char *name, Table *overview_t
         if (r < 0)
                 return r;
 
-        r = assess(info, overview_table, flags);
+        r = assess(info, overview_table, flags, threshold);
         if (r < 0)
                 return r;
 
@@ -2390,7 +2396,7 @@ static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, Security
         return 0;
 }
 
-static int offline_security_check(Unit *u) {
+static int offline_security_check(Unit *u, unsigned threshold) {
         _cleanup_(table_unrefp) Table *overview_table = NULL;
         AnalyzeSecurityFlags flags = 0;
         _cleanup_(security_info_freep) SecurityInfo *info = NULL;
@@ -2405,10 +2411,10 @@ static int offline_security_check(Unit *u) {
         if (r < 0)
               return r;
 
-        return assess(info, overview_table, flags);
+        return assess(info, overview_table, flags, threshold);
 }
 
-static int offline_security_checks(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, const char *root) {
+static int offline_security_checks(char **filenames, UnitFileScope scope, bool check_man, bool run_generators, unsigned threshold, const char *root) {
         const ManagerTestRunFlags flags =
                 MANAGER_TEST_RUN_MINIMAL |
                 MANAGER_TEST_RUN_ENV_GENERATORS |
@@ -2467,7 +2473,7 @@ static int offline_security_checks(char **filenames, UnitFileScope scope, bool c
         }
 
         for (size_t i = 0; i < count; i++) {
-                k = offline_security_check(units[i]);
+                k = offline_security_check(units[i], threshold);
                 if (k < 0 && r == 0)
                         r = k;
         }
@@ -2475,14 +2481,16 @@ static int offline_security_checks(char **filenames, UnitFileScope scope, bool c
         return r;
 }
 
-int analyze_security(sd_bus *bus, char **units, UnitFileScope scope, bool check_man, bool run_generators, bool offline, const char *root, AnalyzeSecurityFlags flags) {
+int analyze_security(sd_bus *bus, char **units, UnitFileScope scope, bool check_man, bool run_generators,
+                     bool offline, unsigned threshold, const char *root, AnalyzeSecurityFlags flags) {
+
         _cleanup_(table_unrefp) Table *overview_table = NULL;
         int ret = 0, r;
 
         assert(bus);
 
         if (offline)
-                return offline_security_checks(units, scope, check_man, run_generators, root);
+                return offline_security_checks(units, scope, check_man, run_generators, threshold, root);
 
         if (strv_length(units) != 1) {
                 overview_table = table_new("unit", "exposure", "predicate", "happy");
@@ -2542,7 +2550,7 @@ int analyze_security(sd_bus *bus, char **units, UnitFileScope scope, bool check_
                 flags |= ANALYZE_SECURITY_SHORT|ANALYZE_SECURITY_ONLY_LOADED|ANALYZE_SECURITY_ONLY_LONG_RUNNING;
 
                 STRV_FOREACH(i, list) {
-                        r = analyze_security_one(bus, *i, overview_table, flags);
+                        r = analyze_security_one(bus, *i, overview_table, flags, threshold);
                         if (r < 0 && ret >= 0)
                                 ret = r;
                 }
@@ -2577,7 +2585,7 @@ int analyze_security(sd_bus *bus, char **units, UnitFileScope scope, bool check_
                         } else
                                 name = mangled;
 
-                        r = analyze_security_one(bus, name, overview_table, flags);
+                        r = analyze_security_one(bus, name, overview_table, flags, threshold);
                         if (r < 0 && ret >= 0)
                                 ret = r;
                 }