Fix error message in seunshare, check for tmpdir existance before unlink.

This commit is contained in:
Dan Walsh 2011-03-03 15:51:42 -05:00
parent aae6082678
commit 4d63979d6d
2 changed files with 86 additions and 56 deletions

View File

@ -2147,7 +2147,7 @@ index 0000000..6063d6a
+and
+.I Thomas Liu <tliu@fedoraproject.org>
diff --git a/policycoreutils/sandbox/seunshare.c b/policycoreutils/sandbox/seunshare.c
index ec692e7..995f78a 100644
index ec692e7..a273d3f 100644
--- a/policycoreutils/sandbox/seunshare.c
+++ b/policycoreutils/sandbox/seunshare.c
@@ -1,28 +1,34 @@
@ -2190,7 +2190,7 @@ index ec692e7..995f78a 100644
#ifdef USE_NLS
#include <locale.h> /* for setlocale() */
#include <libintl.h> /* for gettext() */
@@ -39,6 +45,12 @@
@@ -39,6 +45,13 @@
#define MS_PRIVATE 1<<18
#endif
@ -2199,11 +2199,12 @@ index ec692e7..995f78a 100644
+#endif
+
+#define BUF_SIZE 1024
+static char template[] = "/tmp/.sandboxXXXXXX";
+
/**
* This function will drop all capabilities
* Returns zero on success, non-zero otherwise
@@ -46,9 +58,9 @@
@@ -46,9 +59,9 @@
static int drop_capabilities(uid_t uid)
{
capng_clear(CAPNG_SELECT_BOTH);
@ -2214,7 +2215,7 @@ index ec692e7..995f78a 100644
/* Change uid */
if (setresuid(uid, uid, uid)) {
fprintf(stderr, _("Error changing uid, aborting.\n"));
@@ -90,18 +102,37 @@ static int set_signal_handles(void)
@@ -90,18 +103,37 @@ static int set_signal_handles(void)
* If so, it returns 0. If it can not figure this out or they are different, it returns -1.
*/
static int verify_mount(const char *mntdir, struct passwd *pwd) {
@ -2259,7 +2260,7 @@ index ec692e7..995f78a 100644
}
/**
@@ -131,45 +162,330 @@ static int verify_shell(const char *shell_name)
@@ -131,45 +163,356 @@ static int verify_shell(const char *shell_name)
return rc;
}
@ -2294,8 +2295,9 @@ index ec692e7..995f78a 100644
return -1;
+
+ return 0;
+}
+
}
-#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -t tmpdir ] [ -h homedir ] -- CONTEXT executable [args] ")
+static int set_label(char *srcdir) {
+ int rc = -1;
+ security_context_t filecon = NULL;
@ -2306,22 +2308,21 @@ index ec692e7..995f78a 100644
+ rc =setfilecon("/tmp", filecon);
+ if (rc < 0) {
+ fprintf(stderr, _("Failed to set context %s on /tmp: %s\n"), filecon, strerror(errno));
+ freecon(filecon);
+ goto err;
+ }
+ rc = 0;
+err:
+ freecon(filecon);
+ return rc;
}
+}
-#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -t tmpdir ] [ -h homedir ] -- CONTEXT executable [args] ")
+static char *seunshare_mount_tmp(void) {
-int main(int argc, char **argv) {
- int rc;
+static int seunshare_mount_tmp(const char *tmpdir) {
+
+ char * tmpdir = NULL;
+ int rc = -1;
+ if (verbose)
+ printf("Mount tmpfs on /tmp\n");
+ printf("Mount %s on /tmp\n", tmpdir);
+
+ int flags = MS_REC | MS_NODEV | MS_NOSUID | MS_NOEXEC;
+ if (mount("/tmp", "/tmp", NULL, MS_BIND | flags, NULL) < 0) {
@ -2340,23 +2341,7 @@ index ec692e7..995f78a 100644
+ }
+
+ if (mount("/var/tmp", "/var/tmp", NULL, MS_PRIVATE | flags, NULL) < 0) {
+ fprintf(stderr, _("Failed to make /tmp private: %s\n"), strerror(errno));
+ goto err;
+ }
+
+ if (seteuid(0)) {
+ fprintf(stderr, _("Error changing uid, aborting.\n"));
+ goto err;
+ }
+/* if (setegid(0)) {
+ fprintf(stderr, _("Error changing gid, aborting.\n"));
+ goto err;
+ }
+*/
+ char template[] = "/tmp/.sandboxXXXXXX";
+ tmpdir = mkdtemp(template);
+ if (! tmpdir) {
+ fprintf(stderr, _("Failed to make temporary directory: %s\n"), strerror(errno));
+ fprintf(stderr, _("Failed to make /var/tmp private: %s\n"), strerror(errno));
+ goto err;
+ }
+
@ -2370,18 +2355,9 @@ index ec692e7..995f78a 100644
+ goto err;
+ }
+
+ if (chmod("/tmp", strtol("1770",0,8))) {
+ fprintf(stderr, _("Unable to change mode on /tmp: %s\n"), strerror(errno));
+ goto err;
+ }
+
+ rc = 0;
+err:
+ if (rc < 0) {
+ unlink(tmpdir);
+ return NULL;
+ }
+ return tmpdir;
+ return rc;
+}
+
+#define USAGE_STRING _("USAGE: seunshare [ -v ] [ -c ] -h homedir [-Z CONTEXT] -- executable [args] ")
@ -2574,13 +2550,64 @@ index ec692e7..995f78a 100644
+ free(cpus);
+ return rc;
+}
int main(int argc, char **argv) {
- int rc;
+ int rc = -1;
+
+/*
+ seunshare will create a tmpdi in /tmp, with root ownership
+ Then the process forks and waits for it child to exit to attempt to
+ remove the directory. If it fails to remove the directory we will need to
+ rely on tmpreaper/tmpwatch to clean it up.
+*/
+
+static char *gen_tmpdir() {
+
+ char * tmpdir = NULL;
int status = -1;
-
+ int rootchild = 0;
+
+ if (seteuid(0)) {
+ fprintf(stderr, _("Error changing uid, aborting.\n"));
+ goto err;
+ }
+
+ tmpdir = mkdtemp(template);
+ if (! tmpdir) {
+ fprintf(stderr, _("Failed to make temporary directory: %s\n"), strerror(errno));
+ goto err;
+ }
- security_context_t scontext;
+ if (chmod(tmpdir, 01770)) {
+ fprintf(stderr, _("Unable to change mode on /tmp: %s\n"), strerror(errno));
+ rmdir(tmpdir);
+ tmpdir=NULL;
+ goto err;
+ }
+
+ rootchild = fork();
+ if (rootchild == -1) {
+ perror(_("Unable to fork"));
+ goto err;
+ }
+
+ if (rootchild) {
+ capng_clear(CAPNG_SELECT_BOTH);
+ if ((capng_lock() != 0) ||
+ capng_apply(CAPNG_SELECT_BOTH)) {
+ perror(_("Failed to drop all capabilities"));
+ exit(-1);
+ }
+ waitpid(rootchild, &status, 0);
+ if(rmdir(tmpdir) < 0)
+ fprintf(stderr, _("Unlinking %s: %s\n"), tmpdir, strerror(errno));
+ exit(0);
+ }
+err:
+ return tmpdir;
+}
+
+int main(int argc, char **argv) {
+ int rc = -1;
+ int status = -1;
+ security_context_t execcon = NULL;
+ char *tmpdir = NULL;
+ char *cpbuf=NULL;
@ -2600,7 +2627,7 @@ index ec692e7..995f78a 100644
{NULL, 0, 0, 0}
};
@@ -180,6 +496,12 @@ int main(int argc, char **argv) {
@@ -180,6 +523,12 @@ int main(int argc, char **argv) {
return -1;
}
@ -2613,7 +2640,7 @@ index ec692e7..995f78a 100644
struct passwd *pwd=getpwuid(uid);
if (!pwd) {
perror(_("getpwduid failed"));
@@ -192,80 +514,99 @@ int main(int argc, char **argv) {
@@ -192,80 +541,99 @@ int main(int argc, char **argv) {
}
while (1) {
@ -2689,6 +2716,8 @@ index ec692e7..995f78a 100644
+
+ if (verify_mount(pwd->pw_dir, pwd) < 0) return -1;
+ if (verify_mount(homedir_s, pwd) < 0) return -1;
+
+ if (! (tmpdir = gen_tmpdir())) return -1;
+
if (unshare(CLONE_NEWNS) < 0) {
perror(_("Failed to unshare"));
@ -2706,10 +2735,8 @@ index ec692e7..995f78a 100644
-
- if (tmpdir_s && seunshare_mount(tmpdir_s, "/tmp", pwd) < 0)
- return -1;
+ if ((tmpdir = seunshare_mount_tmp()) == NULL) return -1;
+ if (seunshare_mount_tmp(tmpdir) < 0) return -1;
+
+ /* you must mount the homedir first, since the tmpdir will use
+ the file context from the homedir to set its label*/
+ if (seunshare_mount_home(homedir_s, pwd) < 0) return -1;
+
+ if (asprintf(&tmpdir_s, "%s/.sandboxtmp", pwd->pw_dir) < 0) {
@ -2728,7 +2755,7 @@ index ec692e7..995f78a 100644
+
+ /* Since we have dropped capabilities and we have reset the UID,
+ the system call below should be safe */
+ if (asprintf(&cpbuf, "/usr/bin/rsync -r %s/ /tmp", tmpdir_s) < 0) {
+ if (asprintf(&cpbuf, "/usr/bin/rsync -tr %s/ /tmp 2>/dev/null", tmpdir_s) < 0) {
+ fprintf(stderr, _("Failed to allocate copy command: %s\n"), strerror(errno));
+ goto err;
+ }
@ -2748,7 +2775,7 @@ index ec692e7..995f78a 100644
}
if (!child) {
@@ -286,11 +627,15 @@ int main(int argc, char **argv) {
@@ -286,11 +654,15 @@ int main(int argc, char **argv) {
exit(-1);
}
@ -2769,7 +2796,7 @@ index ec692e7..995f78a 100644
}
if (display)
@@ -305,17 +650,26 @@ int main(int argc, char **argv) {
@@ -305,17 +677,26 @@ int main(int argc, char **argv) {
perror(_("Failed to change dir to homedir"));
exit(-1);
}
@ -2780,7 +2807,7 @@ index ec692e7..995f78a 100644
exit(-1);
} else {
waitpid(child, &status, 0);
+ if (asprintf(&cpbuf, "/usr/bin/rsync --delete -ur /tmp/ %s 2>/dev/null", tmpdir_s) < 0) {
+ if (asprintf(&cpbuf, "/usr/bin/rsync --delete --exclude=.X11-unix -utr /tmp/ %s 2>/dev/null", tmpdir_s) < 0) {
+ fprintf(stderr, _("Failed to allocate copy command: %s\n"), strerror(errno));
+ } else {
+ rc = system(cpbuf);

View File

@ -7,7 +7,7 @@
Summary: SELinux policy core utilities
Name: policycoreutils
Version: 2.0.85
Release: 13%{?dist}
Release: 14%{?dist}
License: GPLv2
Group: System Environment/Base
# Based on git repository with tag 20101221
@ -168,7 +168,7 @@ The policycoreutils-python package contains the scripts to create graphical sand
%defattr(-,root,root,-)
%{_datadir}/sandbox/sandboxX.sh
%{_datadir}/sandbox/start
%attr(0755,root,root) %caps(cap_setpcap,cap_setuid,cap_setgid,cap_fowner,cap_dac_override,cap_sys_admin,cap_sys_nice=pe) %{_sbindir}/seunshare
%attr(0755,root,root) %caps(cap_setpcap,cap_setuid,cap_fowner,cap_dac_override,cap_sys_admin,cap_sys_nice=pe) %{_sbindir}/seunshare
%{_mandir}/man8/seunshare.8*
%{_mandir}/man5/sandbox.conf.5*
@ -329,6 +329,9 @@ fi
exit 0
%changelog
* Thu Mar 3 2011 Dan Walsh <dwalsh@redhat.com> 2.0.85-14
- Fix error message in seunshare, check for tmpdir existance before unlink.
* Fri Feb 25 2011 Dan Walsh <dwalsh@redhat.com> 2.0.85-13
- Rewrite seunshare to make sure /tmp is mounted stickybit owned by root
- Only allow names in polgengui that contain letters and numbers