summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
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.patch557
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) {