rpms/ncpfs/devel ncpfs-2.2.6-mount-issue.patch, NONE, 1.1 ncpfs.spec, 1.37, 1.38
vcrhonek
vcrhonek at fedoraproject.org
Tue Jan 26 14:56:12 UTC 2010
Author: vcrhonek
Update of /cvs/pkgs/rpms/ncpfs/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv26760
Modified Files:
ncpfs.spec
Added Files:
ncpfs-2.2.6-mount-issue.patch
Log Message:
Fix race condition by ncpmount/ncpumount operations
ncpfs-2.2.6-mount-issue.patch:
ncpm_common.c | 22 +++++-
ncpmount.c | 10 ++
ncpumount.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
3 files changed, 214 insertions(+), 12 deletions(-)
--- NEW FILE ncpfs-2.2.6-mount-issue.patch ---
diff -up ncpfs-2.2.6/sutil/ncpm_common.c.mount-issue ncpfs-2.2.6/sutil/ncpm_common.c
--- ncpfs-2.2.6/sutil/ncpm_common.c.mount-issue 2010-01-19 11:59:02.000000000 +0100
+++ ncpfs-2.2.6/sutil/ncpm_common.c 2010-01-19 16:05:33.633889445 +0100
@@ -445,7 +445,7 @@ static int ncp_mount_v2(const char* moun
}
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;
@@ -509,7 +509,7 @@ static int ncp_mount_v3(const char* moun
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 */
@@ -560,7 +560,7 @@ static int ncp_mount_v4(const char* moun
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;
}
@@ -578,7 +578,7 @@ static int ncp_mount_v4(const char* moun
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 */
@@ -1396,6 +1396,17 @@ process_connection (const struct ncp_mou
}
#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;
@@ -1417,6 +1428,9 @@ void add_mnt_entry(char* mount_name, cha
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 -up ncpfs-2.2.6/sutil/ncpmount.c.mount-issue ncpfs-2.2.6/sutil/ncpmount.c
--- ncpfs-2.2.6/sutil/ncpmount.c.mount-issue 2005-01-27 18:35:59.000000000 +0100
+++ ncpfs-2.2.6/sutil/ncpmount.c 2010-01-19 15:46:28.585889018 +0100
@@ -359,11 +359,17 @@ main(int argc, char *argv[])
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)
diff -up ncpfs-2.2.6/sutil/ncpumount.c.mount-issue ncpfs-2.2.6/sutil/ncpumount.c
--- ncpfs-2.2.6/sutil/ncpumount.c.mount-issue 2005-01-27 18:35:59.000000000 +0100
+++ ncpfs-2.2.6/sutil/ncpumount.c 2010-01-19 11:59:02.841941156 +0100
@@ -70,10 +70,19 @@
#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;
@@ -229,11 +238,188 @@ static int clearMtab (const char* mount_
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"),
@@ -253,12 +439,8 @@ do_umount(const char *mount_point)
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;
}
Index: ncpfs.spec
===================================================================
RCS file: /cvs/pkgs/rpms/ncpfs/devel/ncpfs.spec,v
retrieving revision 1.37
retrieving revision 1.38
diff -u -p -r1.37 -r1.38
--- ncpfs.spec 25 Jul 2009 15:52:52 -0000 1.37
+++ ncpfs.spec 26 Jan 2010 14:56:12 -0000 1.38
@@ -1,7 +1,7 @@
Summary: Utilities for the ncpfs filesystem, a NetWare client for Linux
Name: ncpfs
Version: 2.2.6
-Release: 12%{?dist}
+Release: 13%{?dist}
License: GPL+
URL: ftp://platan.vc.cvut.cz/pub/linux/ncpfs/
Source: http://ftp.cvut.cz/ncpfs/ncpfs-%{version}.tar.gz
@@ -12,6 +12,7 @@ Patch3: ncpfs-2.2.4-gcc4.patch
Patch4: ncpfs-2.2.6-ldconfig.patch
Patch5: ncpfs-2.2.6-align.patch
Patch6: ncpfs-2.2.6-offsetof.patch
+Patch7: ncpfs-2.2.6-mount-issue.patch
Group: Applications/System
Requires: ipxutils
Buildroot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
@@ -58,6 +59,7 @@ network.
%patch4 -p1 -b .ld
%patch5 -p1 -b .align
%patch6 -p1 -b .offsetof
+%patch7 -p1 -b .mount-issue
%build
%ifarch s390 s390x
@@ -120,6 +122,9 @@ rm -rf $RPM_BUILD_ROOT
%{_mandir}/man8/ipx*
%changelog
+* Tue Jan 26 2010 Vitezslav Crhonek <vcrhonek at redhat.com> - 2.2.6-13
+- Fix race condition by ncpmount/ncpumount operations (CVE-2009-3297)
+
* Sat Jul 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 2.2.6-12
- Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
More information about the scm-commits
mailing list