[LTP] [PATCH v3 1/4] shell: Add tst_sudo.c helper

Li Wang liwang@redhat.com
Thu Nov 27 12:57:10 CET 2025


Hi Petr,

I feel that the filename tst_sudo.c is a bit misleading. The helper doesn’t
replicate sudo behavior (authentication, privilege escalation), it simply
drops from root to a fixed UID/GID before executing a command.

So readers may expect a “sudo-like” elevation wrapper when, however
it’s a privilege-dropping trampoline.

What about renaming it to:
  tst_runas.c,
  tst_runas_nobody.c, or
  tst_drop_privs.c?


On Thu, Nov 27, 2025 at 4:26 PM Petr Vorel <pvorel@suse.cz> wrote:

> It will be used in LTP IMA tests. Not only it removes external
> dependency, but also fixes problem when 'nobody' user is not possible to
> use due using /usr/sbin/nologin shell.
>
> Suggested-by: Jan Stancek <jstancek@redhat.com>
> Signed-off-by: Petr Vorel <pvorel@suse.cz>
> ---
>  doc/users/setup_tests.rst |  4 ++++
>  testcases/lib/.gitignore  |  1 +
>  testcases/lib/Makefile    |  2 +-
>  testcases/lib/tst_sudo.c  | 50 +++++++++++++++++++++++++++++++++++++++
>  4 files changed, 56 insertions(+), 1 deletion(-)
>  create mode 100644 testcases/lib/tst_sudo.c
>
> diff --git a/doc/users/setup_tests.rst b/doc/users/setup_tests.rst
> index 38976f3b0a..9c49852830 100644
> --- a/doc/users/setup_tests.rst
> +++ b/doc/users/setup_tests.rst
> @@ -71,6 +71,10 @@ users.
>     * - LTP_IMA_LOAD_POLICY
>       - Load IMA example policy, see
> :master:`testcases/kernel/security/integrity/ima/README.md`.
>
> +   * - LTP_USR_UID, LTP_USR_GID
> +     - Set UID and GID of ``nobody`` user for
> :doc:`../developers/api_shell_tests`,
> +       see :master:`testcases/lib/tst_sudo.c`.
> +
>     * - LTP_VIRT_OVERRIDE
>       - Overrides virtual machine detection in the test library. Setting
> it to
>         empty string, tells the library that system is not a virtual
> machine.
> diff --git a/testcases/lib/.gitignore b/testcases/lib/.gitignore
> index 19d7c67bbe..785d638cba 100644
> --- a/testcases/lib/.gitignore
> +++ b/testcases/lib/.gitignore
> @@ -26,3 +26,4 @@
>  /tst_res_
>  /tst_run_shell
>  /tst_remaining_runtime
> +/tst_sudo
> diff --git a/testcases/lib/Makefile b/testcases/lib/Makefile
> index 2309a42a3d..9be9946057 100644
> --- a/testcases/lib/Makefile
> +++ b/testcases/lib/Makefile
> @@ -17,6 +17,6 @@ MAKE_TARGETS          := tst_sleep tst_random
> tst_checkpoint tst_rod tst_kvcmp\
>                            tst_get_median tst_hexdump tst_get_free_pids
> tst_timeout_kill\
>                            tst_check_kconfigs tst_cgctl tst_fsfreeze
> tst_ns_create tst_ns_exec\
>                            tst_ns_ifmove tst_lockdown_enabled
> tst_secureboot_enabled tst_res_\
> -                          tst_run_shell tst_remaining_runtime
> +                          tst_run_shell tst_remaining_runtime tst_sudo
>
>  include $(top_srcdir)/include/mk/generic_trunk_target.mk
> diff --git a/testcases/lib/tst_sudo.c b/testcases/lib/tst_sudo.c
> new file mode 100644
> index 0000000000..e8d5d8dd9d
> --- /dev/null
> +++ b/testcases/lib/tst_sudo.c
> @@ -0,0 +1,50 @@
> +// SPDX-License-Identifier: GPL-2.0-or-later
> +/*
> + * Copyright (c) 2025 Petr Vorel <pvorel@suse.cz>
> + */
> +
> +#define LTP_USR_UID 65534
> +#define LTP_USR_GID 65534
> +
> +#define TST_NO_DEFAULT_MAIN
> +#include "tst_test.h"
> +
> +static void print_help(void)
> +{
> +       fprintf(stderr, "Usage: %s cmd [args] ...\n", __FILE__);
> +       fprintf(stderr, "Usage: %s cmd [-h] print help\n\n", __FILE__);
> +
> +       fprintf(stderr, "Environment Variables\n");
> +       fprintf(stderr, "LTP_USR_UID: UID of 'nobody' user, defaults %d\n",
> +                       LTP_USR_UID);
> +       fprintf(stderr, "LTP_USR_GID: GID of 'nobody' user, defaults %d\n",
> +                       LTP_USR_GID);
> +}
> +
> +int main(int argc, char *argv[])
> +{
> +       if (argc < 2 || !strcmp(argv[1], "-h")) {
> +               print_help();
> +               return 1;
> +       }
> +
> +       unsigned uid = LTP_USR_UID, gid = LTP_USR_GID;
> +
>


> +       char *uid_env = getenv(TST_TO_STR_(LTP_USR_UID));
> +       char *gid_env = getenv(TST_TO_STR_(LTP_USR_GID));
>

I guess you probably want:

-       char *uid_env = getenv(TST_TO_STR_(LTP_USR_UID));
-       char *gid_env = getenv(TST_TO_STR_(LTP_USR_GID));
+       char *uid_env = getenv("LTP_USR_UID");
+       char *gid_env = getenv("LTP_USR_GID");




> +
> +       if (uid_env)
> +               uid = SAFE_STRTOL(uid_env, 1, INT_MAX);
> +
> +       if (gid_env)
> +               gid = SAFE_STRTOL(gid_env, 1, INT_MAX);
>

If you want to support root privilege here we need to accept 0.



> +
> +       tst_res(TINFO, "UID: %d, GID: %d", uid, gid);
> +       SAFE_SETGROUPS(0, NULL);
> +       SAFE_SETRESGID(gid, gid, gid);
> +       SAFE_SETRESUID(uid, uid, uid);
> +
> +       SAFE_CMD((const char * const *)&argv[1], NULL, NULL);
> +
> +       return 0;
> +}
> --
> 2.51.0
>
>

-- 
Regards,
Li Wang


More information about the ltp mailing list