shell: Do chroot() after successful login

This commit is contained in:
Sebastian Huber
2014-11-17 11:55:27 +01:00
parent 373ccbb938
commit fa028bb2ef
4 changed files with 84 additions and 39 deletions

View File

@@ -66,6 +66,10 @@ bool rtems_shell_login_check(
ok = false; ok = false;
} }
if (ok && strcmp(pw.pw_dir, "") != 0) {
ok = chroot(pw.pw_dir) == 0;
}
if (ok) { if (ok) {
rtems_shell_env_t *env = rtems_shell_get_current_env(); rtems_shell_env_t *env = rtems_shell_get_current_env();

View File

@@ -522,26 +522,12 @@ static int rtems_shell_line_editor(
return -2; return -2;
} }
/* ----------------------------------------------- * static bool rtems_shell_login(rtems_shell_env_t *env, FILE * in,FILE * out)
* - 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;
FILE *fd; FILE *fd;
int c; int c;
time_t t; 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 (out) {
if ((env->devname[5]!='p')|| if ((env->devname[5]!='p')||
(env->devname[6]!='t')|| (env->devname[6]!='t')||
@@ -675,6 +661,24 @@ static rtems_task rtems_shell_task(rtems_task_argument task_argument)
rtems_task_delete( RTEMS_SELF ); 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_MAXIMUM_ARGUMENTS (128)
#define RTEMS_SHELL_CMD_SIZE (128) #define RTEMS_SHELL_CMD_SIZE (128)
#define RTEMS_SHELL_CMD_COUNT (32) #define RTEMS_SHELL_CMD_COUNT (32)
@@ -686,7 +690,6 @@ bool rtems_shell_main_loop(
{ {
rtems_shell_env_t *shell_env; rtems_shell_env_t *shell_env;
rtems_shell_cmd_t *shell_cmd; rtems_shell_cmd_t *shell_cmd;
rtems_status_code sc;
int eno; int eno;
struct termios term; struct termios term;
struct termios previous_term; struct termios previous_term;
@@ -720,10 +723,10 @@ bool rtems_shell_main_loop(
return false; return false;
} }
setuid(0); if (!rtems_shell_init_user_env()) {
setgid(0); rtems_error(0, "rtems_shell_init_user_env");
return false;
rtems_current_user_env->euid = rtems_current_user_env->egid = 0; }
fileno(stdout); fileno(stdout);
@@ -811,23 +814,19 @@ bool rtems_shell_main_loop(
} }
do { do {
/* Set again root user and root filesystem, side effect of set_priv..*/ result = rtems_shell_init_user_env();
sc = rtems_libio_set_private_env();
if (sc != RTEMS_SUCCESSFUL) {
rtems_error(sc,"rtems_libio_set_private_env():");
result = false;
break;
}
/* if (result) {
* By using result here, we can fall to the bottom of the /*
* loop when the connection is dropped during login and * By using result here, we can fall to the bottom of the
* keep on trucking. * loop when the connection is dropped during login and
*/ * keep on trucking.
if (shell_env->login_check != NULL) { */
result = rtems_shell_login(stdin,stdout); if (shell_env->login_check != NULL) {
} else { result = rtems_shell_login(shell_env, stdin,stdout);
result = true; } else {
result = true;
}
} }
if (result) { if (result) {

View File

@@ -49,18 +49,29 @@ static void create_file(const char *name, const char *content)
static void test(void) static void test(void)
{ {
rtems_user_env_t *uenv; rtems_user_env_t *uenv;
rtems_status_code sc;
struct stat st_chroot;
struct stat st_workdir;
bool ok; bool ok;
int rv; int rv;
rv = mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH); rv = mkdir("/etc", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
rtems_test_assert(rv == 0); 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( create_file(
"/etc/passwd", "/etc/passwd",
"moop:foo:1:3:blob:a::c\n" "moop:foo:1:3:blob:a::c\n"
"no:*:2:4::::\n" "no:*:2:4::::\n"
"zero::3:5::::\n" "zero::3:5::::\n"
"shadow:x:4:6::::\n" "shadow:x:4:6::::\n"
"invchroot::5:7:::/inv:\n"
"chroot::6:8:::/chroot:\n"
); );
create_file( create_file(
@@ -75,6 +86,9 @@ static void test(void)
"F::8:s,moop,t\n" "F::8:s,moop,t\n"
); );
sc = rtems_libio_set_private_env();
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
uenv = rtems_current_user_env_get(); uenv = rtems_current_user_env_get();
rv = setuid(0); rv = setuid(0);
@@ -95,6 +109,9 @@ static void test(void)
ok = rtems_shell_login_check("moop", "false"); ok = rtems_shell_login_check("moop", "false");
rtems_test_assert(!ok); rtems_test_assert(!ok);
ok = rtems_shell_login_check("invchroot", NULL);
rtems_test_assert(!ok);
rtems_test_assert(getuid() == 0); rtems_test_assert(getuid() == 0);
rtems_test_assert(geteuid() == 0); rtems_test_assert(geteuid() == 0);
rtems_test_assert(getgid() == 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[2] == 4);
rtems_test_assert(uenv->groups[3] == 5); rtems_test_assert(uenv->groups[3] == 5);
rtems_test_assert(uenv->groups[4] == 8); 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) 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_TASKS 1
#define CONFIGURE_MAXIMUM_POSIX_KEYS 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 #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION

View File

@@ -636,9 +636,14 @@ static void fileio_start_shell(void)
printf( "mkdir /etc: %s:\n", strerror(errno) ); printf( "mkdir /etc: %s:\n", strerror(errno) );
} }
sc = mkdir("/chroot", 0777);
if ( sc ) {
printf( "mkdir /chroot: %s:\n", strerror(errno) );
}
printf( printf(
"Creating /etc/passwd and group with three useable accounts\n" "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( writeFile(
@@ -649,6 +654,7 @@ static void fileio_start_shell(void)
"rtems::1:1:RTEMS Application::/:/bin/sh\n" "rtems::1:1:RTEMS Application::/:/bin/sh\n"
"test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n" "test:$1$$oPu1Xt2Pw0ngIc7LyDHqu1:2:2:test account::/:/bin/sh\n"
"tty:*:3:3:tty owner::/:/bin/false\n" "tty:*:3:3:tty owner::/:/bin/false\n"
"chroot::4:2:chroot account::/chroot:/bin/sh\n"
); );
writeFile( writeFile(
"/etc/group", "/etc/group",