From f7f6fcef18e9529e40dd383ffa64b43abab19128 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sun, 4 Feb 2024 14:09:02 +0100 Subject: [PATCH] src/klish-plugin-infix: new symbol shell@infix with user tracking This patch adds a new klish symbol, shell@infix, which performs proper droprivs before calling the configured shell. Fix #298: track user id so shell command gets correct user Signed-off-by: Joachim Wiberg --- .../klish-plugin-infix/klish-plugin-infix.mk | 6 +++ src/klish-plugin-infix/configure.ac | 41 +++++++++++++++- src/klish-plugin-infix/src/infix.c | 48 +++++++++++++++++++ src/klish-plugin-infix/xml/shell.xml | 2 +- 4 files changed, 95 insertions(+), 2 deletions(-) diff --git a/package/klish-plugin-infix/klish-plugin-infix.mk b/package/klish-plugin-infix/klish-plugin-infix.mk index 78374bb51..e42f15e42 100644 --- a/package/klish-plugin-infix/klish-plugin-infix.mk +++ b/package/klish-plugin-infix/klish-plugin-infix.mk @@ -25,6 +25,12 @@ else KLISH_PLUGIN_INFIX_CONF_OPTS += --disable-shell endif +ifeq ($(BR2_PACKAGE_BASH),y) +KLISH_PLUGIN_INFIX_CONF_OPTS += --with-shell=/bin/bash +else +KLISH_PLUGIN_INFIX_CONF_OPTS += --with-shell=/bin/sh +endif + define KLISH_PLUGIN_INFIX_INSTALL_DOC $(INSTALL) -t $(TARGET_DIR)/usr/share/infix/cli -D -m 0644 \ $(wildcard $(BR2_EXTERNAL_INFIX_PATH)/doc/cli/*.md) diff --git a/src/klish-plugin-infix/configure.ac b/src/klish-plugin-infix/configure.ac index 340d9fc99..fa8f2bc7f 100644 --- a/src/klish-plugin-infix/configure.ac +++ b/src/klish-plugin-infix/configure.ac @@ -2,7 +2,7 @@ AC_PREREQ(2.61) AC_INIT([klish-plugin-infix], [1.0.0], [https://github.com/kernelkit/infix/issues]) AM_INIT_AUTOMAKE(1.11 foreign subdir-objects) -AM_SILENT_RULES(yes) +AM_SILENT_RULES(no) LT_INIT @@ -26,6 +26,10 @@ AC_ARG_ENABLE(shell, AS_HELP_STRING([--enable-shell], [Enable shell access from CLI]),,[ enable_shell=no]) +AC_ARG_WITH(shell, + AS_HELP_STRING([--with-shell=shell], [Path to shell to use, default: /bin/sh]), + [shell=$withval], [shell=yes]) + # Check for pkg-config first, warn if it's not installed PKG_PROG_PKG_CONFIG @@ -37,6 +41,12 @@ AC_CHECK_LIB([klish], [kplugin_new],, AC_MSG_ERROR([Klish not found])) AM_CONDITIONAL(CONTAINERS, [test "x$enable_containers" != "xno"]) AM_CONDITIONAL(SHELL, [test "x$enable_shell" != "xno"]) +AS_IF([test "x$with_shell" != "xno"], [ + AS_IF([test "x$shell" = "xyes"], [shell=/bin/sh]) + with_shell=$shell + AC_DEFINE_UNQUOTED(SHELL, "$shell", [Default: /bin/sh])],[ + AC_DEFINE_UNQUOTED(SHELL, "/bin/sh")]) + test "x$prefix" = xNONE && prefix=$ac_default_prefix test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' @@ -47,3 +57,32 @@ KLISHCONFDIR=`eval echo $sysconfdir/klish` AC_SUBST(KLISHCONFDIR) AC_OUTPUT + +cat < #include #include +#include #include #include #include @@ -14,6 +15,7 @@ #include #include +#include #include #include @@ -527,6 +529,51 @@ int infix_commit(kcontext_t *ctx) return -1; } +int infix_shell(kcontext_t *ctx) +{ + const char *user = "root"; + ksession_t *session; + pid_t pid; + int rc; + + session = kcontext_session(ctx); + if (session) { + user = ksession_user(session); + if (!user) + user = "root"; + } + + pid = fork(); + if (pid == -1) + return -1; + + if (!pid) { + struct passwd *pw; + char *args[] = { + "env", "CLISH=yes", + SHELL, "-il", + NULL + }; + + pw = getpwnam(user); + if (setgid(pw->pw_gid) || setuid(pw->pw_uid)) + fprintf(stderr, "Failed dropping privileges to (UID:%d GID:%d): %s\n", + pw->pw_uid, pw->pw_gid, strerror(errno)); + + _exit(execvp(args[0], args)); + } + + while (waitpid(pid, &rc, 0) != pid) + ; + + if (WIFEXITED(rc)) + rc = WEXITSTATUS(rc); + else if (WIFSIGNALED(rc)) + rc = -2; + + return rc; +} + int infix_rpc(kcontext_t *ctx) { kpargv_pargs_node_t *iter; @@ -612,6 +659,7 @@ int kplugin_infix_init(kcontext_t *ctx) kplugin_add_syms(plugin, ksym_new("erase", infix_erase)); kplugin_add_syms(plugin, ksym_new("files", infix_files)); kplugin_add_syms(plugin, ksym_new("ifaces", infix_ifaces)); + kplugin_add_syms(plugin, ksym_new("shell", infix_shell)); kplugin_add_syms(plugin, ksym_new("rpc", infix_rpc)); return 0; diff --git a/src/klish-plugin-infix/xml/shell.xml b/src/klish-plugin-infix/xml/shell.xml index b750e436f..7bebbe43f 100644 --- a/src/klish-plugin-infix/xml/shell.xml +++ b/src/klish-plugin-infix/xml/shell.xml @@ -7,7 +7,7 @@ - /usr/bin/env CLISH=yes bash -l +