diff options
Diffstat (limited to 'net-fs/ncpfs/files/ncpfs-2.2.6-multiple-vulns.patch')
-rw-r--r-- | net-fs/ncpfs/files/ncpfs-2.2.6-multiple-vulns.patch | 557 |
1 files changed, 0 insertions, 557 deletions
diff --git a/net-fs/ncpfs/files/ncpfs-2.2.6-multiple-vulns.patch b/net-fs/ncpfs/files/ncpfs-2.2.6-multiple-vulns.patch deleted file mode 100644 index def49a5fad65..000000000000 --- a/net-fs/ncpfs/files/ncpfs-2.2.6-multiple-vulns.patch +++ /dev/null @@ -1,557 +0,0 @@ -From: Dan Rosenberg <dan.j.rosenberg () gmail com> -Date: Fri, 5 Mar 2010 12:06:01 -0500 - -============================================ - ncpfs, Multiple Vulnerabilities - March 5, 2010 - CVE-2010-0788, CVE-2010-0790, CVE-2010-0791 -============================================ - -==Description== - -The ncpmount, ncpumount, and ncplogin utilities, installed as part of the ncpfs -package, contain several vulnerabilities. - -1. ncpmount, ncpumount, and ncplogin are vulnerable to race conditions that -allow a local attacker to unmount arbitrary mountpoints, causing -denial-of-service, or mount Netware shares to arbitrary directories, -potentially leading to root compromise. This issue was formerly assigned -CVE-2009-3297, but has since been re-assigned CVE-2010-0788 to avoid overlap -with related bugs in other packages. - -2. ncpumount is vulnerable to an information disclosure vulnerability that -allows a local attacker to verify the existence of arbitrary files, violating -directory permissions. This issue has been assigned CVE-2010-0790. - -3. ncpmount, ncpumount, and ncplogin create lockfiles insecurely, allowing a -local attacker to leave a stale lockfile at /etc/mtab~, causing other mount -utilities to fail and creating denial-of-service conditions. This issue has -been assigned CVE-2010-0791. - -==Workaround== - -If unprivileged users do not need the ability to mount and unmount Netware -shares, then the suid bit should be removed from these utilities. - -==Solution== - -A patch has been released that resolves these issues (attached to this -advisory). ncpfs-2.2.6.partial.patch is intended for ncpfs releases that have -already been patched against the first vulnerability in this report -(CVE-2010-0788, formerly CVE-2009-3297). It has been tested against the latest -ncpfs packages distributed by Fedora, Red Hat, and Mandriva. -ncpfs-2.2.6.full.patch is intended for ncpfs releases that have not been -patched against any of these vulnerabilities. It has been tested against the -latest ncpfs packages distributed by Debian, Ubuntu, and the upstream release -(ftp://platan.vc.cvut.cz/pub/linux/ncpfs/). - -Users are advised to recompile from source, or request updated packages from -downstream distributors. - -==Credits== - -These vulnerabilities were discovered by Dan Rosenberg -(dan.j.rosenberg () gmail com). -Thanks to Vitezslav Crhonek for the patch against the first issue. - -==References== - -CVE identifiers CVE-2010-0788, CVE-2010-0790, and CVE-2010-0791 have been -assigned to these issues. - -http://seclists.org/fulldisclosure/2010/Mar/122 - - -diff -ur ncpfs-2.2.6.orig/sutil/ncplogin.c ncpfs-2.2.6/sutil/ncplogin.c ---- a/sutil/ncplogin.c.orig 2010-03-03 16:18:59.000000000 -0500 -+++ b/sutil/ncplogin.c 2010-03-03 16:17:41.000000000 -0500 -@@ -934,7 +934,9 @@ - NWDSFreeContext(ctx); - /* ncpmap, ncplogin must write in /etc/mtab */ - { -+ block_sigs(); - add_mnt_entry(mount_name, mount_point, info.flags); -+ unblock_sigs(); - } - free(mount_name); - if (info.echo_mnt_pnt) { -diff -ur ncpfs-2.2.6.orig/sutil/ncpm_common.c ncpfs-2.2.6/sutil/ncpm_common.c ---- ncpfs-2.2.6.orig/sutil/ncpm_common.c 2010-03-03 16:18:59.000000000 -0500 -+++ ncpfs-2.2.6/sutil/ncpm_common.c 2010-03-03 16:17:41.000000000 -0500 -@@ -360,7 +360,7 @@ - #endif - - static inline int ncpm_suser(void) { -- return setreuid(-1, 0); -+ return setresuid(0, 0, myuid); - } - - static int ncpm_normal(void) { -@@ -368,11 +368,31 @@ - int v; - - e = errno; -- v = setreuid(-1, myuid); -+ v = setresuid(myuid, myuid, 0); - errno = e; - return v; - } - -+void block_sigs(void) { -+ -+ sigset_t mask, orig_mask; -+ sigfillset(&mask); -+ -+ if(sigprocmask(SIG_SETMASK, &mask, &orig_mask) < 0) { -+ errexit(-1, _("Blocking signals failed.\n")); -+ } -+} -+ -+void unblock_sigs(void) { -+ -+ sigset_t mask, orig_mask; -+ sigemptyset(&mask); -+ -+ if (sigprocmask(SIG_SETMASK, &mask, &orig_mask) < 0) { -+ errexit(-1, _("Un-blocking signals failed.\n")); -+ } -+} -+ - static int proc_ncpm_mount(const char* source, const char* target, const char* filesystem, unsigned long mountflags, const void* data) { - int v; - int e; -@@ -444,7 +464,7 @@ - } - datav2.file_mode = data->file_mode; - datav2.dir_mode = data->dir_mode; -- err = proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav2); -+ err = proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*) &datav2); - if (err) - return errno; - return 0; -@@ -508,7 +528,7 @@ - exit(0); /* Should not return from process_connection */ - } - close(pp[0]); -- err=proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*) &datav3); -+ err=proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*) &datav3); - if (err) { - err = errno; - /* Mount unsuccesful so we have to kill daemon */ -@@ -559,7 +579,7 @@ - sprintf(mountopts, "version=%u,flags=%u,owner=%u,uid=%u,gid=%u,mode=%u,dirmode=%u,timeout=%u,retry=%u,wdogpid=%u,ncpfd=%u,infofd=%u", - NCP_MOUNT_VERSION_V5, ncpflags, data->mounted_uid, data->uid, data->gid, data->file_mode, - data->dir_mode, data->time_out, data->retry_count, wdog_pid, data->ncp_fd, pp[1]); -- err=proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, mountopts); -+ err=proc_ncpm_mount(mount_name, ".", "ncpfs", flags, mountopts); - } else { - err=-1; - } -@@ -577,7 +597,7 @@ - datav4.file_mode = data->file_mode; - datav4.dir_mode = data->dir_mode; - datav4.wdog_pid = wdog_pid; -- err = proc_ncpm_mount(mount_name, data->mount_point, "ncpfs", flags, (void*)&datav4); -+ err = proc_ncpm_mount(mount_name, ".", "ncpfs", flags, (void*)&datav4); - if (err) { - err = errno; - /* Mount unsuccesful so we have to kill daemon */ -@@ -1395,6 +1415,17 @@ - } - #endif /* MOUNT3 */ - -+static int check_name(const char *name) -+{ -+ char *s; -+ for (s = "\n\t\\"; *s; s++) { -+ if (strchr(name, *s)) { -+ return -1; -+ } -+ } -+ return 0; -+} -+ - static const struct smntflags { - unsigned int flag; - const char* name; -@@ -1416,6 +1447,9 @@ - int fd; - FILE* mtab; - -+ if (check_name(mount_name) == -1 || check_name(mpnt) == -1) -+ errexit(107, _("Illegal character in mount entry\n")); -+ - ment.mnt_fsname = mount_name; - ment.mnt_dir = mpnt; - ment.mnt_type = (char*)"ncpfs"; -diff -ur ncpfs-2.2.6.orig/sutil/ncpm_common.h ncpfs-2.2.6/sutil/ncpm_common.h ---- ncpfs-2.2.6.orig/sutil/ncpm_common.h 2010-03-03 16:18:59.000000000 -0500 -+++ ncpfs-2.2.6/sutil/ncpm_common.h 2010-03-03 16:17:41.000000000 -0500 -@@ -121,6 +121,9 @@ - int proc_aftermount(const struct ncp_mount_info* info, NWCONN_HANDLE* conn); - int proc_ncpm_umount(const char* dir); - -+void block_sigs(void); -+void unblock_sigs(void); -+ - #define UNUSED(x) x __attribute__((unused)) - - #endif /* __NCPM_COMMON_H__ */ -diff -ur ncpfs-2.2.6.orig/sutil/ncpmount.c ncpfs-2.2.6/sutil/ncpmount.c ---- ncpfs-2.2.6.orig/sutil/ncpmount.c 2010-03-03 16:18:59.000000000 -0500 -+++ ncpfs-2.2.6/sutil/ncpmount.c 2010-03-03 16:17:41.000000000 -0500 -@@ -359,11 +359,17 @@ - usage(); - return -1; - } -+ - realpath(argv[optind], mount_point); - -- if (stat(mount_point, &st) == -1) -+ if (chdir(mount_point)) -+ { -+ errexit(31, _("Could not change directory into mount target %s: %s\n"), -+ mount_point, strerror(errno)); -+ } -+ if (stat(".", &st) == -1) - { -- errexit(31, _("Could not find mount point %s: %s\n"), -+ errexit(31, _("Mount point %s does not exist: %s\n"), - mount_point, strerror(errno)); - } - if (mount_ok(&st) != 0) -@@ -714,7 +720,9 @@ - ncp_close(conn); - - if (!opt_n) { -+ block_sigs(); - add_mnt_entry(mount_name, mount_point, info.flags); -+ unblock_sigs(); - } - return 0; - } -diff -ur ncpfs-2.2.6.orig/sutil/ncpumount.c ncpfs-2.2.6/sutil/ncpumount.c ---- ncpfs-2.2.6.orig/sutil/ncpumount.c 2010-03-03 16:18:59.000000000 -0500 -+++ ncpfs-2.2.6/sutil/ncpumount.c 2010-03-03 16:17:41.000000000 -0500 -@@ -70,13 +70,24 @@ - #include <mntent.h> - #include <pwd.h> - -+#include <sched.h> -+ - #include "private/libintl.h" - - #define _(X) X - -+#ifndef MS_REC -+#define MS_REC 16384 -+#endif -+#ifndef MS_SLAVE -+#define MS_SLAVE (1<<19) -+#endif -+ - static char *progname; - static int is_ncplogout = 0; - -+uid_t uid; -+ - static void - usage(void) - { -@@ -117,6 +128,40 @@ - va_end(ap); - } - -+/* Mostly copied from ncpm_common.c */ -+void block_sigs(void) { -+ -+ sigset_t mask, orig_mask; -+ sigfillset(&mask); -+ sigdelset(&mask, SIGALRM); /* Need SIGALRM for ncpumount */ -+ -+ if(setresuid(0, 0, uid) < 0) { -+ eprintf("Failed to raise privileges.\n"); -+ exit(-1); -+ } -+ -+ if(sigprocmask(SIG_SETMASK, &mask, &orig_mask) < 0) { -+ eprintf("Blocking signals failed.\n"); -+ exit(-1); -+ } -+} -+ -+void unblock_sigs(void) { -+ -+ sigset_t mask, orig_mask; -+ sigemptyset(&mask); -+ -+ if(setresuid(uid, uid, 0) < 0) { -+ eprintf("Failed to drop privileges.\n"); -+ exit(-1); -+ } -+ -+ if(sigprocmask(SIG_SETMASK, &mask, &orig_mask) < 0) { -+ eprintf("Un-blocking signals failed.\n"); -+ exit(-1); -+ } -+} -+ - static void alarmSignal(int sig) { - (void)sig; - } -@@ -192,10 +237,13 @@ - if (!numEntries) - return 0; /* don't waste time ! */ - -+ block_sigs(); -+ - while ((fd = open(MOUNTED "~", O_RDWR | O_CREAT | O_EXCL, 0600)) == -1) { - struct timespec tm; - - if (errno != EEXIST || retries == 0) { -+ unblock_sigs(); - eprintf(_("Can't get %s~ lock file: %s\n"), MOUNTED, strerror(errno)); - return 1; - } -@@ -206,6 +254,7 @@ - alarm(0); - close(fd); - if (err) { -+ unblock_sigs(); - eprintf(_("Can't lock lock file %s~: %s\n"), MOUNTED, _("Lock timed out")); - return 1; - } -@@ -223,26 +272,205 @@ - err = __clearMtab(mount_points, numEntries); - - if ((unlink(MOUNTED "~") == -1) && (err == 0)){ -+ unblock_sigs(); - eprintf(_("Can't remove %s~"), MOUNTED); - return 1; - } -+ unblock_sigs(); - return err; - } - -+ -+int ncp_mnt_umount(const char *abs_mnt, const char *rel_mnt) -+{ -+ if (umount(rel_mnt) != 0) { -+ eprintf(_("Could not umount %s: %s\n"), -+ abs_mnt, strerror(errno)); -+ return -1; -+ } -+ return 0; -+} -+ -+ -+static int check_is_mount_child(void *p) -+{ -+ const char **a = p; -+ const char *last = a[0]; -+ const char *mnt = a[1]; -+ int res; -+ const char *procmounts = "/proc/mounts"; -+ int found; -+ FILE *fp; -+ struct mntent *entp; -+ -+ res = mount("", "/", "", MS_SLAVE | MS_REC, NULL); -+ if (res == -1) { -+ eprintf(_("Failed to mark mounts slave: %s\n"), -+ strerror(errno)); -+ return 1; -+ } -+ -+ res = mount(".", "/tmp", "", MS_BIND | MS_REC, NULL); -+ if (res == -1) { -+ eprintf(_("Failed to bind parent to /tmp: %s\n"), -+ strerror(errno)); -+ return 1; -+ } -+ -+ fp = setmntent(procmounts, "r"); -+ if (fp == NULL) { -+ eprintf(_("Failed to open %s: %s\n"), -+ procmounts, strerror(errno)); -+ return 1; -+ } -+ -+ found = 0; -+ while ((entp = getmntent(fp)) != NULL) { -+ if (strncmp(entp->mnt_dir, "/tmp/", 5) == 0 && -+ strcmp(entp->mnt_dir + 5, last) == 0) { -+ found = 1; -+ break; -+ } -+ } -+ endmntent(fp); -+ -+ if (!found) { -+ eprintf(_("%s not mounted\n"), mnt); -+ return 1; -+ } -+ -+ return 0; -+} -+ -+ -+static int check_is_mount(const char *last, const char *mnt) -+{ -+ char buf[131072]; -+ pid_t pid, p; -+ int status; -+ const char *a[2] = { last, mnt }; -+ -+ pid = clone(check_is_mount_child, buf + 65536, CLONE_NEWNS, (void *) a); -+ if (pid == (pid_t) -1) { -+ eprintf(_("Failed to clone namespace: %s\n"), -+ strerror(errno)); -+ return -1; -+ } -+ p = waitpid(pid, &status, __WCLONE); -+ if (p == (pid_t) -1) { -+ eprintf(_("Waitpid failed: %s\n"), -+ strerror(errno)); -+ return -1; -+ } -+ if (!WIFEXITED(status)) { -+ eprintf(_("Child terminated abnormally (status %i)\n"), -+ status); -+ return -1; -+ } -+ if (WEXITSTATUS(status) != 0) -+ return -1; -+ -+ return 0; -+} -+ -+ -+static int chdir_to_parent(char *copy, const char **lastp, int *currdir_fd) -+{ -+ char *tmp; -+ const char *parent; -+ char buf[PATH_MAX]; -+ int res; -+ -+ tmp = strrchr(copy, '/'); -+ if (tmp == NULL || tmp[1] == '\0') { -+ eprintf(_("Internal error: invalid abs path: <%s>\n"), -+ copy); -+ return -1; -+ } -+ if (tmp != copy) { -+ *tmp = '\0'; -+ parent = copy; -+ *lastp = tmp + 1; -+ } else if (tmp[1] != '\0') { -+ *lastp = tmp + 1; -+ parent = "/"; -+ } else { -+ *lastp = "."; -+ parent = "/"; -+ } -+ *currdir_fd = open(".", O_RDONLY); -+ if (*currdir_fd == -1) { -+ eprintf(_("Failed to open current directory: %s\n"), -+ strerror(errno)); -+ return -1; -+ } -+ res = chdir(parent); -+ if (res == -1) { -+ eprintf(_("Failed to chdir to %s: %s\n"), -+ parent, strerror(errno)); -+ return -1; -+ } -+ if (getcwd(buf, sizeof(buf)) == NULL) { -+ eprintf(_("Failed to obtain current directory: %s\n"), -+ strerror(errno)); -+ return -1; -+ } -+ if (strcmp(buf, parent) != 0) { -+ eprintf(_("Mountpoint moved (%s -> %s)\n"), -+ parent, buf); -+ return -1; -+ -+ } -+ -+ return 0; -+} -+ -+ -+static int unmount_ncp(const char *mount_point) -+{ -+ int currdir_fd = -1; -+ char *copy; -+ const char *last; -+ int res; -+ -+ copy = strdup(mount_point); -+ if (copy == NULL) { -+ eprintf(_("Failed to allocate memory\n")); -+ return -1; -+ } -+ res = chdir_to_parent(copy, &last, &currdir_fd); -+ if (res == -1) -+ goto out; -+ res = check_is_mount(last, mount_point); -+ if (res == -1) -+ goto out; -+ res = ncp_mnt_umount(mount_point, last); -+ -+out: -+ free(copy); -+ if (currdir_fd != -1) { -+ fchdir(currdir_fd); -+ close(currdir_fd); -+ } -+ -+ return res; -+} -+ - static int - do_umount(const char *mount_point) - { - int fid = open(mount_point, O_RDONLY, 0); - uid_t mount_uid; -+ int res; - - if (fid == -1) { -- eprintf(_("Could not open %s: %s\n"), -- mount_point, strerror(errno)); -+ eprintf(_("Invalid or unauthorized mountpoint %s\n"), -+ mount_point); - return -1; - } - if (ncp_get_mount_uid(fid, &mount_uid) != 0) { - close(fid); -- eprintf(_("%s probably not ncp-filesystem\n"), -+ eprintf(_("Invalid or unauthorized mountpoint %s\n"), - mount_point); - return -1; - } -@@ -253,12 +481,8 @@ - return -1; - } - close(fid); -- if (umount(mount_point) != 0) { -- eprintf(_("Could not umount %s: %s\n"), -- mount_point, strerror(errno)); -- return -1; -- } -- return 0; -+ res = unmount_ncp(mount_point); -+ return res; - } - - -@@ -409,7 +633,8 @@ - int allConns = 0; - const char *serverName = NULL; - const char *treeName = NULL; -- uid_t uid = getuid(); -+ -+ uid = getuid(); - - progname = strrchr(argv[0], '/'); - if (progname) { |