From fa028bb2ef1e3cd9a8dfdd8b557e5acda3e11505 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Mon, 17 Nov 2014 11:55:27 +0100 Subject: shell: Do chroot() after successful login --- cpukit/libmisc/shell/login_check.c | 4 ++ cpukit/libmisc/shell/shell.c | 75 +++++++++++++++++++------------------- testsuites/libtests/shell01/init.c | 38 ++++++++++++++++++- testsuites/samples/fileio/init.c | 8 +++- 4 files changed, 85 insertions(+), 40 deletions(-) diff --git a/cpukit/libmisc/shell/login_check.c b/cpukit/libmisc/shell/login_check.c index 9d853f8d1f..a1af07ce1d 100644 --- a/cpukit/libmisc/shell/login_check.c +++ b/cpukit/libmisc/shell/login_check.c @@ -66,6 +66,10 @@ bool rtems_shell_login_check( ok = false; } + if (ok && strcmp(pw.pw_dir, "") != 0) { + ok = chroot(pw.pw_dir) == 0; + } + if (ok) { rtems_shell_env_t *env = rtems_shell_get_current_env(); diff --git a/cpukit/libmisc/shell/shell.c b/cpukit/libmisc/shell/shell.c index babac72750..14edf52a29 100644 --- a/cpukit/libmisc/shell/shell.c +++ b/cpukit/libmisc/shell/shell.c @@ -522,26 +522,12 @@ static int rtems_shell_line_editor( return -2; } -/* ----------------------------------------------- * - * - The shell TASK - * Poor but enough.. - * TODO: Redirection. Tty Signals. ENVVARs. Shell language. - * ----------------------------------------------- */ - -static bool rtems_shell_login(FILE * in,FILE * out) { - rtems_shell_env_t *env; +static bool rtems_shell_login(rtems_shell_env_t *env, FILE * in,FILE * out) +{ FILE *fd; int c; time_t t; - env = rtems_shell_get_current_env(); - assert(env != NULL); - - setuid(0); - setgid(0); - rtems_current_user_env->euid = - rtems_current_user_env->egid =0; - if (out) { if ((env->devname[5]!='p')|| (env->devname[6]!='t')|| @@ -675,6 +661,24 @@ static rtems_task rtems_shell_task(rtems_task_argument task_argument) rtems_task_delete( RTEMS_SELF ); } +static bool rtems_shell_init_user_env(void) +{ + rtems_status_code sc; + + /* Make sure we have a private user environment */ + sc = rtems_libio_set_private_env(); + if (sc != RTEMS_SUCCESSFUL) { + rtems_error(sc, "rtems_libio_set_private_env():"); + return false; + } + + /* Make an effective root user */ + seteuid(0); + setegid(0); + + return chroot("/") == 0; +} + #define RTEMS_SHELL_MAXIMUM_ARGUMENTS (128) #define RTEMS_SHELL_CMD_SIZE (128) #define RTEMS_SHELL_CMD_COUNT (32) @@ -686,7 +690,6 @@ bool rtems_shell_main_loop( { rtems_shell_env_t *shell_env; rtems_shell_cmd_t *shell_cmd; - rtems_status_code sc; int eno; struct termios term; struct termios previous_term; @@ -720,10 +723,10 @@ bool rtems_shell_main_loop( return false; } - setuid(0); - setgid(0); - - rtems_current_user_env->euid = rtems_current_user_env->egid = 0; + if (!rtems_shell_init_user_env()) { + rtems_error(0, "rtems_shell_init_user_env"); + return false; + } fileno(stdout); @@ -811,23 +814,19 @@ bool rtems_shell_main_loop( } do { - /* Set again root user and root filesystem, side effect of set_priv..*/ - sc = rtems_libio_set_private_env(); - if (sc != RTEMS_SUCCESSFUL) { - rtems_error(sc,"rtems_libio_set_private_env():"); - result = false; - break; - } - - /* - * By using result here, we can fall to the bottom of the - * loop when the connection is dropped during login and - * keep on trucking. - */ - if (shell_env->login_check != NULL) { - result = rtems_shell_login(stdin,stdout); - } else { - result = true; + result = rtems_shell_init_user_env(); + + if (result) { + /* + * By using result here, we can fall to the bottom of the + * loop when the connection is dropped during login and + * keep on trucking. + */ + if (shell_env->login_check != NULL) { + result = rtems_shell_login(shell_env, stdin,stdout); + } else { + result = true; + } } if (result) { diff --git a/testsuites/libtests/shell01/init.c b/testsuites/libtests/shell01/init.c index 248988b32b..bbfa36e6dd 100644 --- a/testsuites/libtests/shell01/init.c +++ b/testsuites/libtests/shell01/init.c @@ -49,18 +49,29 @@ static void create_file(const char *name, const char *content) static void test(void) { rtems_user_env_t *uenv; + rtems_status_code sc; + struct stat st_chroot; + struct stat st_workdir; bool ok; int rv; rv = mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); rtems_test_assert(rv == 0); + rv = mkdir("/chroot", S_IRWXU | S_IRWXG | S_IRWXO); + rtems_test_assert(rv == 0); + + rv = lstat("/chroot", &st_chroot); + rtems_test_assert(rv == 0); + create_file( "/etc/passwd", "moop:foo:1:3:blob:a::c\n" "no:*:2:4::::\n" "zero::3:5::::\n" "shadow:x:4:6::::\n" + "invchroot::5:7:::/inv:\n" + "chroot::6:8:::/chroot:\n" ); create_file( @@ -75,6 +86,9 @@ static void test(void) "F::8:s,moop,t\n" ); + sc = rtems_libio_set_private_env(); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + uenv = rtems_current_user_env_get(); rv = setuid(0); @@ -95,6 +109,9 @@ static void test(void) ok = rtems_shell_login_check("moop", "false"); rtems_test_assert(!ok); + ok = rtems_shell_login_check("invchroot", NULL); + rtems_test_assert(!ok); + rtems_test_assert(getuid() == 0); rtems_test_assert(geteuid() == 0); rtems_test_assert(getgid() == 0); @@ -122,6 +139,25 @@ static void test(void) rtems_test_assert(uenv->groups[2] == 4); rtems_test_assert(uenv->groups[3] == 5); rtems_test_assert(uenv->groups[4] == 8); + + rv = setuid(0); + rtems_test_assert(rv == 0); + + rv = seteuid(0); + rtems_test_assert(rv == 0); + + ok = rtems_shell_login_check("chroot", NULL); + rtems_test_assert(ok); + rtems_test_assert(getuid() == 6); + rtems_test_assert(geteuid() == 6); + rtems_test_assert(getgid() == 8); + rtems_test_assert(getegid() == 8); + + rv = lstat(".", &st_workdir); + rtems_test_assert(rv == 0); + rtems_test_assert(memcmp(&st_chroot, &st_workdir, sizeof(st_chroot)) == 0); + + rtems_libio_use_global_env(); } static void Init(rtems_task_argument arg) @@ -143,7 +179,7 @@ static void Init(rtems_task_argument arg) #define CONFIGURE_MAXIMUM_TASKS 1 #define CONFIGURE_MAXIMUM_POSIX_KEYS 1 -#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 1 +#define CONFIGURE_MAXIMUM_POSIX_KEY_VALUE_PAIRS 2 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION diff --git a/testsuites/samples/fileio/init.c b/testsuites/samples/fileio/init.c index 1c6c88c6a6..4dd00ed7a7 100644 --- a/testsuites/samples/fileio/init.c +++ b/testsuites/samples/fileio/init.c @@ -636,9 +636,14 @@ static void fileio_start_shell(void) printf( "mkdir /etc: %s:\n", strerror(errno) ); } + sc = mkdir("/chroot", 0777); + if ( sc ) { + printf( "mkdir /chroot: %s:\n", strerror(errno) ); + } + printf( "Creating /etc/passwd and group with three useable accounts\n" - "root/pwd , test/pwd, rtems/NO PASSWORD" + "root/pwd , test/pwd, rtems/NO PASSWORD, chroot/NO PASSWORD" ); writeFile( @@ -649,6 +654,7 @@ static void fileio_start_shell(void) "rtems::1:1:RTEMS Application::/:/bin/sh\n" "test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n" "tty:*:3:3:tty owner::/:/bin/false\n" + "chroot::4:2:chroot account::/chroot:/bin/sh\n" ); writeFile( "/etc/group", -- cgit v1.2.3