From 60158cb93eb0b3207dd1084cdf5bdd9226bd9e89 Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Tue, 3 May 2005 06:25:50 +0000 Subject: [PATCH] A patch from Takeharu KATO to update/fix SE-Linux support. --- Makefile | 3 +- coreutils/id.c | 29 ++++++++------- coreutils/ls.c | 48 ++++++++++++------------- include/libbb.h | 14 +++----- libbb/find_pid_by_name.c | 7 ++-- libbb/procps.c | 15 ++------ libbb/run_shell.c | 43 ++++++++++++++++------ loginutils/login.c | 78 ++++++++++++++++++++-------------------- loginutils/su.c | 5 ++- loginutils/sulogin.c | 6 ++++ procps/ps.c | 52 +++++++++++++++------------ procps/top.c | 4 --- 12 files changed, 161 insertions(+), 143 deletions(-) diff --git a/Makefile b/Makefile index b1e934754..f16c16948 100644 --- a/Makefile +++ b/Makefile @@ -47,8 +47,7 @@ DIRS:=applets archival archival/libunarchive coreutils console-tools \ SRC_DIRS:=$(patsubst %,$(top_srcdir)/%,$(DIRS)) ifeq ($(strip $(CONFIG_SELINUX)),y) -CFLAGS += -I/usr/include/selinux -LIBRARIES += -lsecure +LIBRARIES += -lselinux endif CONFIG_CONFIG_IN = $(top_srcdir)/sysdeps/$(TARGET_OS)/Config.in diff --git a/coreutils/id.c b/coreutils/id.c index d5182b953..541c3d16b 100644 --- a/coreutils/id.c +++ b/coreutils/id.c @@ -32,8 +32,7 @@ #include #ifdef CONFIG_SELINUX -#include -#include +#include /* for is_selinux_enabled() */ #endif #define PRINT_REAL 1 @@ -61,9 +60,6 @@ extern int id_main(int argc, char **argv) gid_t gid; unsigned long flags; short status; -#ifdef CONFIG_SELINUX - int is_flask_enabled_flag = is_flask_enabled(); -#endif bb_opt_complementaly = "u~g:g~u"; flags = bb_getopt_ulflags(argc, argv, "rnug"); @@ -109,17 +105,26 @@ extern int id_main(int argc, char **argv) putchar(' '); /* my_getgrgid doesn't exit on failure here */ status|=printf_full(gid, my_getgrgid(NULL, gid, 0), 'g'); + #ifdef CONFIG_SELINUX - if(is_flask_enabled_flag) { - security_id_t mysid = getsecsid(); - char context[80]; - int len = sizeof(context); - context[0] = '\0'; - if(security_sid_to_context(mysid, context, &len)) - strcpy(context, "unknown"); + if ( is_selinux_enabled() ) { + security_context_t mysid; + char context[80]; + int len = sizeof(context); + + getcon(&mysid); + context[0] = '\0'; + if (mysid) { + len = strlen(mysid)+1; + safe_strncpy(context, mysid, len); + freecon(mysid); + }else{ + safe_strncpy(context, "unknown",8); + } bb_printf(" context=%s", context); } #endif + putchar('\n'); bb_fflush_stdout_and_exit(status); } diff --git a/coreutils/ls.c b/coreutils/ls.c index 4e21454ce..92e150966 100644 --- a/coreutils/ls.c +++ b/coreutils/ls.c @@ -64,9 +64,7 @@ enum { #include /* major() and minor() */ #include "busybox.h" #ifdef CONFIG_SELINUX -#include -#include -#include +#include /* for is_selinux_enabled() */ #endif #ifdef CONFIG_FEATURE_LS_TIMESTAMPS @@ -182,7 +180,7 @@ struct dnode { /* the basic node */ char *fullname; /* the dir entry name */ struct stat dstat; /* the file stat info */ #ifdef CONFIG_SELINUX - security_id_t sid; + security_context_t sid; #endif struct dnode *next; /* point at the next node */ }; @@ -195,7 +193,7 @@ static int list_single(struct dnode *); static unsigned int all_fmt; #ifdef CONFIG_SELINUX -static int is_flask_enabled_flag; +static int selinux_enabled= 0; #endif #ifdef CONFIG_FEATURE_AUTOWIDTH @@ -213,18 +211,19 @@ static struct dnode *my_stat(char *fullname, char *name) struct stat dstat; struct dnode *cur; #ifdef CONFIG_SELINUX - security_id_t sid; + security_context_t sid=NULL; #endif int rc; #ifdef CONFIG_FEATURE_LS_FOLLOWLINKS if (all_fmt & FOLLOW_LINKS) { #ifdef CONFIG_SELINUX - if(is_flask_enabled_flag) - rc = stat_secure(fullname, &dstat, &sid); - else + if (is_selinux_enabled()) { + rc=0; /* Set the number which means success before hand. */ + rc = getfilecon(fullname,&sid); + } #endif - rc = stat(fullname, &dstat); + rc = stat(fullname, &dstat); if(rc) { bb_perror_msg("%s", fullname); @@ -235,11 +234,12 @@ static struct dnode *my_stat(char *fullname, char *name) #endif { #ifdef CONFIG_SELINUX - if(is_flask_enabled_flag) - rc = lstat_secure(fullname, &dstat, &sid); - else + if (is_selinux_enabled()) { + rc=0; /* Set the number which means success before hand. */ + rc = lgetfilecon(fullname,&sid); + } #endif - rc = lstat(fullname, &dstat); + rc = lstat(fullname, &dstat); if(rc) { bb_perror_msg("%s", fullname); @@ -736,12 +736,16 @@ static int list_single(struct dnode *dn) #ifdef CONFIG_SELINUX case LIST_CONTEXT: { - char context[64]; - int len = sizeof(context); - if(security_sid_to_context(dn->sid, context, &len)) - { - strcpy(context, "unknown"); - len = 7; + char context[80]; + int len; + + if (dn->sid) { + /* I assume sid initilized with NULL */ + len = strlen(dn->sid)+1; + safe_strncpy(context, dn->sid, len); + freecon(dn->sid); + }else { + safe_strncpy(context, "unknown",8); } printf("%-32s ", context); column += MAX(33, len); @@ -963,10 +967,6 @@ extern int ls_main(int argc, char **argv) char *terminal_width_str = NULL; #endif -#ifdef CONFIG_SELINUX - is_flask_enabled_flag = is_flask_enabled(); -#endif - all_fmt = LIST_SHORT | DISP_NORMAL | STYLE_AUTO #ifdef CONFIG_FEATURE_LS_TIMESTAMPS | TIME_MOD diff --git a/include/libbb.h b/include/libbb.h index 6ae5c4d64..ac60dd6c2 100644 --- a/include/libbb.h +++ b/include/libbb.h @@ -423,11 +423,11 @@ void bb_xasprintf(char **string_ptr, const char *format, ...) __attribute__ ((fo #define FAIL_DELAY 3 extern void change_identity ( const struct passwd *pw ); extern const char *change_identity_e2str ( const struct passwd *pw ); -extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args +extern void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args); #ifdef CONFIG_SELINUX - , security_context_t sid -#endif -); +extern void renew_current_security_context(void); +extern void set_current_security_context(security_context_t sid); +#endif extern int run_parts(char **args, const unsigned char test_mode, char **env); extern int restricted_shell ( const char *shell ); extern void setup_environment ( const char *shell, int loginshell, int changeenv, const struct passwd *pw ); @@ -458,11 +458,7 @@ typedef struct { char short_cmd[16]; } procps_status_t; -extern procps_status_t * procps_scan(int save_user_arg0 -#ifdef CONFIG_SELINUX - , int use_selinux, security_context_t *sid -#endif -); +extern procps_status_t * procps_scan(int save_user_arg0); extern unsigned short compare_string_array(const char *string_array[], const char *key); extern int my_query_module(const char *name, int which, void **buf, size_t *bufsize, size_t *ret); diff --git a/libbb/find_pid_by_name.c b/libbb/find_pid_by_name.c index 930710f32..570e7bd93 100644 --- a/libbb/find_pid_by_name.c +++ b/libbb/find_pid_by_name.c @@ -45,11 +45,8 @@ extern long* find_pid_by_name( const char* pidName) procps_status_t * p; pidList = xmalloc(sizeof(long)); -#ifdef CONFIG_SELINUX - while ((p = procps_scan(0, 0, NULL)) != 0) { -#else - while ((p = procps_scan(0)) != 0) { -#endif + while ((p = procps_scan(0)) != 0) + { if (strncmp(p->short_cmd, pidName, COMM_LEN-1) == 0) { pidList=xrealloc( pidList, sizeof(long) * (i+2)); pidList[i++]=p->pid; diff --git a/libbb/procps.c b/libbb/procps.c index e405fb7ef..72f627f15 100644 --- a/libbb/procps.c +++ b/libbb/procps.c @@ -16,11 +16,7 @@ #include "libbb.h" -extern procps_status_t * procps_scan(int save_user_arg0 -#ifdef CONFIG_SELINUX - , int use_selinux , security_id_t *sid -#endif - ) +extern procps_status_t * procps_scan(int save_user_arg0) { static DIR *dir; struct dirent *entry; @@ -60,16 +56,9 @@ extern procps_status_t * procps_scan(int save_user_arg0 my_getpwuid(curstatus.user, sb.st_uid, sizeof(curstatus.user)); sprintf(status, "/proc/%d/stat", pid); + if((fp = fopen(status, "r")) == NULL) continue; -#ifdef CONFIG_SELINUX - if(use_selinux) - { - if(fstat_secure(fileno(fp), &sb, sid)) - continue; - } - else -#endif name = fgets(buf, sizeof(buf), fp); fclose(fp); if(name == NULL) diff --git a/libbb/run_shell.c b/libbb/run_shell.c index 993b4e711..67ff2a5f8 100644 --- a/libbb/run_shell.c +++ b/libbb/run_shell.c @@ -37,7 +37,33 @@ #include #include "libbb.h" #ifdef CONFIG_SELINUX -#include +#include /* for setexeccon */ +#endif + +#ifdef CONFIG_SELINUX +static security_context_t current_sid=NULL; + +void +renew_current_security_context(void) +{ + if (current_sid) + freecon(current_sid); /* Release old context */ + + getcon(¤t_sid); /* update */ + + return; +} +void +set_current_security_context(security_context_t sid) +{ + if (current_sid) + freecon(current_sid); /* Release old context */ + + current_sid=sid; + + return; +} + #endif /* Run SHELL, or DEFAULT_SHELL if SHELL is empty. @@ -45,11 +71,7 @@ If ADDITIONAL_ARGS is nonzero, pass it to the shell as more arguments. */ -void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args -#ifdef CONFIG_SELINUX - , security_id_t sid -#endif -) +void run_shell ( const char *shell, int loginshell, const char *command, const char **additional_args) { const char **args; int argno = 1; @@ -78,10 +100,11 @@ void run_shell ( const char *shell, int loginshell, const char *command, const c } args [argno] = 0; #ifdef CONFIG_SELINUX - if(sid) - execve_secure(shell, (char **) args, environ, sid); - else + if ( (current_sid) && (!setexeccon(current_sid)) ) { + freecon(current_sid); + execve(shell, (char **) args, environ); + } else #endif - execv ( shell, (char **) args ); + execv ( shell, (char **) args ); bb_perror_msg_and_die ( "cannot run %s", shell ); } diff --git a/loginutils/login.c b/loginutils/login.c index 34095a6a7..5186e2369 100644 --- a/loginutils/login.c +++ b/loginutils/login.c @@ -17,10 +17,10 @@ #include "busybox.h" #ifdef CONFIG_SELINUX -#include -#include -#include -#include +#include /* for is_selinux_enabled() */ +#include /* for get_default_context() */ +#include /* for security class definitions */ +#include #endif #ifdef CONFIG_FEATURE_U_W_TMP @@ -79,8 +79,7 @@ extern int login_main(int argc, char **argv) char *opt_host = 0; int alarmstarted = 0; #ifdef CONFIG_SELINUX - int flask_enabled = is_flask_enabled(); - security_id_t sid = 0, old_tty_sid, new_tty_sid; + security_context_t stat_sid = NULL, sid = NULL, old_tty_sid=NULL, new_tty_sid=NULL; #endif username[0]=0; @@ -225,41 +224,45 @@ auth_ok: #ifdef CONFIG_FEATURE_U_W_TMP setutmp ( username, tty ); #endif -#ifdef CONFIG_SELINUX - if (flask_enabled) - { - struct stat st; - - if (get_default_sid(username, 0, &sid)) - { - fprintf(stderr, "Unable to get SID for %s\n", username); - exit(1); - } - if (stat_secure(tty, &st, &old_tty_sid)) - { - fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", tty, strerror(errno)); - return EXIT_FAILURE; - } - if (security_change_sid (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0) - { - fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", tty, strerror(errno)); - return EXIT_FAILURE; - } - if(chsid(tty, new_tty_sid) != 0) - { - fprintf(stderr, "chsid(%.100s, %d) failed: %.100s\n", tty, new_tty_sid, strerror(errno)); - return EXIT_FAILURE; - } - } - else - sid = 0; -#endif if ( *tty != '/' ) snprintf ( full_tty, sizeof( full_tty ) - 1, "/dev/%s", tty); else safe_strncpy ( full_tty, tty, sizeof( full_tty ) - 1 ); +#ifdef CONFIG_SELINUX + if (is_selinux_enabled()) + { + struct stat st; + int rc; + + if (get_default_context(username, NULL, &sid)) + { + fprintf(stderr, "Unable to get SID for %s\n", username); + exit(1); + } + rc = getfilecon(full_tty,&stat_sid); + freecon(stat_sid); + if ((rc<0) || (stat(full_tty, &st)<0)) + { + fprintf(stderr, "stat_secure(%.100s) failed: %.100s\n", full_tty, strerror(errno)); + return EXIT_FAILURE; + } + if (security_compute_relabel (sid, old_tty_sid, SECCLASS_CHR_FILE, &new_tty_sid) != 0) + { + fprintf(stderr, "security_change_sid(%.100s) failed: %.100s\n", full_tty, strerror(errno)); + return EXIT_FAILURE; + } + if(setfilecon(full_tty, new_tty_sid) != 0) + { + fprintf(stderr, "chsid(%.100s, %s) failed: %.100s\n", full_tty, new_tty_sid, strerror(errno)); + return EXIT_FAILURE; + } + freecon(sid); + freecon(old_tty_sid); + freecon(new_tty_sid); + } +#endif if ( !is_my_tty ( full_tty )) syslog ( LOG_ERR, "unable to determine TTY name, got %s\n", full_tty ); @@ -279,11 +282,10 @@ auth_ok: if ( pw-> pw_uid == 0 ) syslog ( LOG_INFO, "root login %s\n", fromhost ); - run_shell ( tmp, 1, 0, 0 #ifdef CONFIG_SELINUX - , sid + set_current_security_context(sid); #endif - ); /* exec the shell finally. */ + run_shell ( tmp, 1, 0, 0); /* exec the shell finally. */ return EXIT_FAILURE; } diff --git a/loginutils/su.c b/loginutils/su.c index ec0c16c7d..5f6140917 100644 --- a/loginutils/su.c +++ b/loginutils/su.c @@ -147,11 +147,10 @@ int su_main ( int argc, char **argv ) change_identity ( pw ); setup_environment ( opt_shell, opt_loginshell, !opt_preserve, pw ); - run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args #ifdef CONFIG_SELINUX - , 0 + set_current_security_context(NULL); #endif - ); + run_shell ( opt_shell, opt_loginshell, opt_command, (const char**)opt_args); return EXIT_FAILURE; } diff --git a/loginutils/sulogin.c b/loginutils/sulogin.c index f21b09571..a458b6ed7 100644 --- a/loginutils/sulogin.c +++ b/loginutils/sulogin.c @@ -153,6 +153,12 @@ extern int sulogin_main(int argc, char **argv) puts("Entering System Maintenance Mode\n"); fflush(stdout); syslog(LOG_INFO, "System Maintenance Mode\n"); + +#ifdef CONFIG_SELINUX + renew_current_security_context(); +#endif + run_shell(pwent.pw_shell, 1, 0, 0); + return (0); } diff --git a/procps/ps.c b/procps/ps.c index 0b603314d..18a6db36f 100644 --- a/procps/ps.c +++ b/procps/ps.c @@ -31,9 +31,7 @@ #include #include "busybox.h" #ifdef CONFIG_SELINUX -#include -#include -#include /* for is_flask_enabled() */ +#include /* for is_selinux_enabled() */ #endif static const int TERMINAL_WIDTH = 79; /* not 80 in case terminal has linefold bug */ @@ -48,8 +46,8 @@ extern int ps_main(int argc, char **argv) #ifdef CONFIG_SELINUX int use_selinux = 0; - security_id_t sid; - if(is_flask_enabled() && argv[1] && !strcmp(argv[1], "-c") ) + security_context_t sid=NULL; + if(is_selinux_enabled() && argv[1] && !strcmp(argv[1], "-c") ) use_selinux = 1; #endif @@ -58,34 +56,42 @@ extern int ps_main(int argc, char **argv) terminal_width--; #ifdef CONFIG_SELINUX - if(use_selinux) - printf(" PID Context Stat Command\n"); + if (use_selinux) + printf(" PID Context Stat Command\n"); else #endif - printf(" PID Uid VmSize Stat Command\n"); -#ifdef CONFIG_SELINUX - while ((p = procps_scan(1, use_selinux, &sid)) != 0) { -#else - while ((p = procps_scan(1)) != 0) { -#endif - char *namecmd = p->cmd; + printf(" PID Uid VmSize Stat Command\n"); + while ((p = procps_scan(1)) != 0) { + char *namecmd = p->cmd; #ifdef CONFIG_SELINUX - if(use_selinux) - { + if ( use_selinux ) + { char sbuf[128]; len = sizeof(sbuf); - if(security_sid_to_context(sid, (security_context_t)&sbuf, &len)) - strcpy(sbuf, "unknown"); + if (is_selinux_enabled()) { + if (getpidcon(p->pid,&sid)<0) + sid=NULL; + } + + if (sid) { + /* I assume sid initilized with NULL */ + len = strlen(sid)+1; + safe_strncpy(sbuf, sid, len); + freecon(sid); + sid=NULL; + }else { + safe_strncpy(sbuf, "unknown",7); + } len = printf("%5d %-32s %s ", p->pid, sbuf, p->state); - } + } else #endif - if(p->rss == 0) - len = printf("%5d %-8s %s ", p->pid, p->user, p->state); - else - len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state); + if(p->rss == 0) + len = printf("%5d %-8s %s ", p->pid, p->user, p->state); + else + len = printf("%5d %-8s %6ld %s ", p->pid, p->user, p->rss, p->state); i = terminal_width-len; if(namecmd != 0 && namecmd[0] != 0) { diff --git a/procps/top.c b/procps/top.c index c0f78f794..369a408d8 100644 --- a/procps/top.c +++ b/procps/top.c @@ -510,11 +510,7 @@ int top_main(int argc, char **argv) /* read process IDs & status for all the processes */ procps_status_t * p; -#ifdef CONFIG_SELINUX - while ((p = procps_scan(0, 0, NULL) ) != 0) { -#else while ((p = procps_scan(0)) != 0) { -#endif int n = ntop; top = xrealloc(top, (++ntop)*sizeof(procps_status_t));