Hi,
The attached patch provides two features related to SELinux.
The one is to preserve the security context of password files
when these are modified.
The other is additional checks in userspace. It prevents
root user can modify other's password entry without appropriate
permissions.
Please apply this patch, or reply your comment.
Thanks,
--
OSS Platform Development Division, NEC
KaiGai Kohei <[EMAIL PROTECTED]>
Index: busybox/include/libbb.h
===================================================================
--- busybox/include/libbb.h (revision 20217)
+++ busybox/include/libbb.h (working copy)
@@ -44,6 +44,8 @@
#if ENABLE_SELINUX
#include <selinux/selinux.h>
#include <selinux/context.h>
+#include <selinux/flask.h>
+#include <selinux/av_permissions.h>
#endif
#if ENABLE_LOCALE_SUPPORT
@@ -806,6 +808,9 @@
extern context_t set_security_context_component(security_context_t cur_context,
char *user, char *role, char *type, char *range);
extern void setfscreatecon_or_die(security_context_t scontext);
+extern void selinux_preserve_fcontext(int fdesc);
+#else
+#define selinux_preserve_fcontext(fdesc)
#endif
extern void selinux_or_die(void);
extern int restricted_shell(const char *shell);
Index: busybox/libbb/selinux_common.c
===================================================================
--- busybox/libbb/selinux_common.c (revision 20217)
+++ busybox/libbb/selinux_common.c (working copy)
@@ -38,3 +38,17 @@
"file creation context to %s", scontext);
}
}
+
+void selinux_preserve_fcontext(int fdesc)
+{
+ security_context_t context;
+
+ if (fgetfilecon(fdesc, &context) < 0) {
+ if (errno == ENODATA || errno == ENOTSUP)
+ return;
+ bb_perror_msg_and_die("fgetfilecon failed");
+ }
+ setfscreatecon_or_die(context);
+ freecon(context);
+}
+
Index: busybox/libbb/update_passwd.c
===================================================================
--- busybox/libbb/update_passwd.c (revision 20217)
+++ busybox/libbb/update_passwd.c (working copy)
@@ -11,6 +11,31 @@
#include "libbb.h"
+#if ENABLE_SELINUX
+static void check_selinux_update_passwd(const char *username)
+{
+ security_context_t context;
+ char *seuser;
+
+ if (getuid() != (uid_t)0 || is_selinux_enabled() == 0)
+ return; /* No need to check*/
+
+ if (getprevcon_raw(&context) < 0)
+ bb_perror_msg_and_die("getprevcon() failed");
+ seuser = strtok(context, ":");
+ if (!seuser)
+ bb_error_msg_and_die("Invalid context (%s)", context);
+ if (strcmp(seuser, username) != 0) {
+ if (checkPasswdAccess(PASSWD__PASSWD) != 0)
+ bb_error_msg_and_die("SELinux: access denied");
+ }
+ if (ENABLE_FEATURE_CLEAN_UP)
+ freecon(context);
+}
+#else
+#define check_selinux_update_passwd(username)
+#endif
+
int update_passwd(const char *filename, const char *username,
const char *new_pw)
{
@@ -27,6 +52,8 @@
int cnt = 0;
int ret = -1; /* failure */
+ check_selinux_update_passwd(username);
+
/* New passwd file, "/etc/passwd+" for now */
fnamesfx = xasprintf("%s+", filename);
sfx_char = &fnamesfx[strlen(fnamesfx)-1];
@@ -38,6 +65,8 @@
goto free_mem;
old_fd = fileno(old_fp);
+ selinux_preserve_fcontext(old_fd);
+
/* Try to create "/etc/passwd+". Wait if it exists. */
i = 30;
do {
_______________________________________________
busybox mailing list
[email protected]
http://busybox.net/cgi-bin/mailman/listinfo/busybox