Skip to content

Commit 24e456a

Browse files
committed
added selinu support
Commit adds SELinux support to dropbear by: - adding a new '--enable-selinux' option to configure; by default, it is disabled. This option defines an ENABLE_SELINUX preprocessor macro. - mapping the unix username to the SELinux user which is stored in a new 'user_sid' attribute in the AuthState object - relabeling the controlling pty - setting the context for the next execve() call to the user_sid Operations above will not be done when SELinux is disabled. Failures will generate LOG_ERR messages and in enforcing SELinux mode, dropbear_exit() will be called. Signed-off-by: Enrico Scholz <[email protected]>
1 parent 7e03e4d commit 24e456a

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

svr-chansession.c

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
#include "runopts.h"
3939
#include "auth.h"
4040

41+
#ifdef ENABLE_SELINUX
42+
# include <selinux/selinux.h>
43+
#endif
44+
4145
/* Handles sessions (either shells or programs) requested by the client */
4246

4347
static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
@@ -556,6 +560,48 @@ static void get_termmodes(const struct ChanSess *chansess) {
556560
TRACE(("leave get_termmodes"))
557561
}
558562

563+
static void relabelpty(const char *tty)
564+
{
565+
#ifdef ENABLE_SELINUX
566+
char *old_sid = NULL;
567+
char *new_sid = NULL;
568+
security_class_t class;
569+
int rc;
570+
571+
if (!is_selinux_enabled())
572+
return;
573+
574+
rc = getfilecon(tty, &old_sid);
575+
if (rc < 0) {
576+
dropbear_log(LOG_ERR, "failed to get context of tty '%s'", tty);
577+
goto out;
578+
}
579+
580+
class = string_to_security_class("chr_file");
581+
582+
rc = security_compute_relabel(ses.authstate.user_sid, old_sid, class, &new_sid);
583+
if (rc < 0) {
584+
dropbear_log(LOG_ERR, "failed to compute tty relabel");
585+
goto out;
586+
}
587+
588+
rc = setfilecon(tty, new_sid);
589+
if (rc < 0) {
590+
dropbear_log(LOG_ERR, "failed to set file context for '%s'", tty);
591+
goto out;
592+
}
593+
594+
rc = 0;
595+
596+
out:
597+
freecon(new_sid);
598+
freecon(old_sid);
599+
600+
if (rc < 0 && security_getenforce() > 0)
601+
dropbear_exit("SELinux: failed to relabel PTY");
602+
#endif
603+
}
604+
559605
/* Set up a session pty which will be used to execute the shell or program.
560606
* The pty is allocated now, and kept for when the shell/program executes.
561607
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
@@ -604,6 +650,8 @@ static int sessionpty(struct ChanSess * chansess) {
604650
/* Read the terminal modes */
605651
get_termmodes(chansess);
606652

653+
relabelpty(chansess->tty);
654+
607655
TRACE(("leave sessionpty"))
608656
return DROPBEAR_SUCCESS;
609657
}
@@ -726,6 +774,31 @@ static int sessioncommand(struct Channel *channel, struct ChanSess *chansess,
726774
return ret;
727775
}
728776

777+
static void init_selinux_session(void)
778+
{
779+
#ifdef ENABLE_SELINUX
780+
char *ctx = ses.authstate.user_sid;
781+
int rc;
782+
unsigned int i;
783+
security_class_t class;
784+
785+
if (!is_selinux_enabled())
786+
return;
787+
788+
rc = setexeccon(ctx);
789+
if (rc < 0) {
790+
dropbear_log(LOG_ERR, "setexeccon() failed");
791+
goto out;
792+
}
793+
794+
rc = 0;
795+
796+
out:
797+
if (rc < 0 && security_getenforce() > 0)
798+
dropbear_exit("SELinux: failed to initialize session");
799+
#endif
800+
}
801+
729802
/* Execute a command and set up redirection of stdin/stdout/stderr without a
730803
* pty.
731804
* Returns DROPBEAR_SUCCESS or DROPBEAR_FAILURE */
@@ -932,6 +1005,8 @@ static void execchild(const void *user_data) {
9321005
#endif /* HAVE_CLEARENV */
9331006
#endif /* DEBUG_VALGRIND */
9341007

1008+
init_selinux_session();
1009+
9351010
/* We can only change uid/gid as root ... */
9361011
if (getuid() == 0) {
9371012

0 commit comments

Comments
 (0)