]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
setpriv: add --landlock-support option
authorSkye Soss <skye@soss.website>
Tue, 28 Jul 2026 21:32:02 +0000 (16:32 -0500)
committerSkye Soss <skye@soss.website>
Sun, 2 Aug 2026 02:16:50 +0000 (21:16 -0500)
Adds the --landlock-support option to query the current running kernel's
support for landlock. Also adds the --list-landlock-access and
--list-landlock-rights options which are used for implementing bash
completion (much like --list-caps).

Signed-off-by: Skye Soss <skye@soss.website>
sys-utils/setpriv-landlock.c
sys-utils/setpriv-landlock.h
sys-utils/setpriv.1.adoc
sys-utils/setpriv.c

index a40a2990a251bfcb50a9ad62cd2dc1ac934bcdd5..a9db71e20cc1fd511a61749bc92753b8843ffca6 100644 (file)
@@ -285,3 +285,38 @@ void usage_landlock(FILE *out)
                                        _(landlock_access_fs[i].help));
        }
 }
+
+void list_landlock_support(void)
+{
+       size_t i;
+
+       printf("ABI: %d\n", supported_landlock_abi());
+
+       printf("access: fs\n");
+
+       printf("rights:");
+       for (i = 0; i < ARRAY_SIZE(landlock_access_fs); i++)
+               printf(" %s", landlock_access_fs[i].type);
+       printf("\n");
+
+       printf("rules: path-beneath\n");
+}
+
+void list_landlock_access(void)
+{
+       printf("fs\n");
+}
+
+void list_landlock_rights(const char *access)
+{
+       uint64_t mask;
+       size_t i;
+
+       if (strcmp(access, "fs") != 0)
+               errx(EXIT_FAILURE, _("unknown landlock access: %s"), access);
+
+       mask = landlock_abi_fs_mask();
+       for (i = 0; i < ARRAY_SIZE(landlock_access_fs); i++)
+               if (landlock_access_fs[i].value & mask)
+                       printf("%s\n", landlock_access_fs[i].type);
+}
index 12c945a6eb4eb3ff1aff8095254cb0545cb3a89f..cde162c69f20cab572d31f1aff5df7a8390d9fa9 100644 (file)
@@ -28,6 +28,9 @@ void parse_landlock_access(struct setpriv_landlock_opts *opts, const char *str);
 void parse_landlock_rule(struct setpriv_landlock_opts *opts, const char *str);
 void init_landlock_opts(struct setpriv_landlock_opts *opts);
 void usage_landlock(FILE *out);
+void list_landlock_support(void);
+void list_landlock_access(void);
+void list_landlock_rights(const char *access);
 
 #else
 
@@ -46,6 +49,15 @@ static inline void parse_landlock_access(
 #define parse_landlock_rule parse_landlock_access
 static inline void init_landlock_opts(void *opts __attribute__((unused))) {}
 static inline void usage_landlock(FILE *out __attribute__((unused))) {}
+static inline void list_landlock_support(void)
+{
+       errx(EXIT_FAILURE, _("no support for landlock"));
+}
+#define list_landlock_access list_landlock_support
+static inline void list_landlock_rights(const char *access __attribute__((unused)))
+{
+       errx(EXIT_FAILURE, _("no support for landlock"));
+}
 
 #endif /* HAVE_LANDLOCK */
 
index e67a23454ad679a397c32905503b094eaa67001e..5017eafcfbf0d45887b19a1e9cd922c97ddba933 100644 (file)
@@ -130,6 +130,17 @@ For example grant file read access to everything under */boot*:
 +
 *--landlock-rule path-beneath:read-file:/boot*
 
+*--landlock-support*::
+List the landlock ABI version supported by the running kernel, together with the access
+categories, rights, and rule types that *setpriv* understands. Must be specified alone.
+
+*--list-landlock-access*::
+List the landlock access categories supported by *--landlock-access* and *--landlock-rule*.
+
+*--list-landlock-rights* _access_::
+List the rights of the given landlock access category that are supported by the running
+kernel.
+
 *--seccomp-filter* _file_::
 
 Load raw BPF seccomp filter code from a file.
index 8ec571c505e32d66737700538e59ad995091e57b..25d6ca570c6f8a44a96cb9be6cc6fdcfc3a58251 100644 (file)
@@ -173,6 +173,10 @@ static void __attribute__((__noreturn__)) usage(void)
        fputs(_(" --apparmor-profile <pr>     set AppArmor profile\n"), out);
        fputs(_(" --landlock-access <access>  add Landlock access\n"), out);
        fputs(_(" --landlock-rule <rule>      add Landlock rule\n"), out);
+       fputs(_(" --landlock-support          list supported Landlock ABI, access, rights, and rules\n"), out);
+       fputs(_(" --list-landlock-access      list Landlock access categories\n"), out);
+       fputs(_(" --list-landlock-rights <access>\n"
+               "                             list an access category's rights\n"), out);
        fputs(_(" --seccomp-filter <file>     load seccomp filter from file\n"), out);
        fputs(_(" --reset-env                 clear all environment and initialize\n"
                "                               HOME, SHELL, USER, LOGNAME and PATH\n"), out);
@@ -874,6 +878,9 @@ int main(int argc, char **argv)
                APPARMOR_PROFILE,
                LANDLOCK_ACCESS,
                LANDLOCK_RULE,
+               LANDLOCK_SUPPORT,
+               LIST_LANDLOCK_ACCESS,
+               LIST_LANDLOCK_RIGHTS,
                SECCOMP_FILTER,
                RESET_ENV
        };
@@ -903,6 +910,9 @@ int main(int argc, char **argv)
                { "apparmor-profile", required_argument, NULL, APPARMOR_PROFILE },
                { "landlock-access",  required_argument, NULL, LANDLOCK_ACCESS  },
                { "landlock-rule",    required_argument, NULL, LANDLOCK_RULE    },
+               { "landlock-support", no_argument,       NULL, LANDLOCK_SUPPORT },
+               { "list-landlock-access", no_argument,       NULL, LIST_LANDLOCK_ACCESS },
+               { "list-landlock-rights", required_argument, NULL, LIST_LANDLOCK_RIGHTS },
                { "seccomp-filter",   required_argument, NULL, SECCOMP_FILTER   },
                { "help",             no_argument,       NULL, 'h'              },
                { "reset-env",        no_argument,       NULL, RESET_ENV,       },
@@ -923,6 +933,9 @@ int main(int argc, char **argv)
        int dumplevel = 0;
        int total_opts = 0;
        int list_caps = 0;
+       int landlock_support = 0;
+       int landlock_list_access = 0;
+       const char *landlock_list_rights_access = NULL;
 
        setlocale(LC_ALL, "");
        bindtextdomain(PACKAGE, LOCALEDIR);
@@ -1072,6 +1085,15 @@ int main(int argc, char **argv)
                case LANDLOCK_RULE:
                        parse_landlock_rule(&opts.landlock, optarg);
                        break;
+               case LANDLOCK_SUPPORT:
+                       landlock_support = 1;
+                       break;
+               case LIST_LANDLOCK_ACCESS:
+                       landlock_list_access = 1;
+                       break;
+               case LIST_LANDLOCK_RIGHTS:
+                       landlock_list_rights_access = optarg;
+                       break;
                case SECCOMP_FILTER:
                        if (opts.seccomp_filter)
                                errx(EXIT_FAILURE,
@@ -1107,6 +1129,30 @@ int main(int argc, char **argv)
                return EXIT_SUCCESS;
        }
 
+       if (landlock_support) {
+               if (total_opts != 1 || optind < argc)
+                       errx(EXIT_FAILURE,
+                            _("--landlock-support must be specified alone"));
+               list_landlock_support();
+               return EXIT_SUCCESS;
+       }
+
+       if (landlock_list_access) {
+               if (total_opts != 1 || optind < argc)
+                       errx(EXIT_FAILURE,
+                            _("--list-landlock-access must be specified alone"));
+               list_landlock_access();
+               return EXIT_SUCCESS;
+       }
+
+       if (landlock_list_rights_access) {
+               if (total_opts != 1 || optind < argc)
+                       errx(EXIT_FAILURE,
+                            _("--list-landlock-rights must be specified alone"));
+               list_landlock_rights(landlock_list_rights_access);
+               return EXIT_SUCCESS;
+       }
+
        if (argc <= optind)
                errx(EXIT_FAILURE, _("No program specified"));