[PATCH 10/22] shell: Do chroot() after successful login

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Nov 18 14:37:16 UTC 2014


---
 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 9d853f8..a1af07c 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 babac72..14edf52 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 248988b..bbfa36e 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 1c6c88c..4dd00ed 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",
-- 
1.8.4.5




More information about the devel mailing list