diff --git a/add-canonicalize_path_restricted.patch b/add-canonicalize_path_restricted.patch new file mode 100644 index 0000000..252c651 --- /dev/null +++ b/add-canonicalize_path_restricted.patch @@ -0,0 +1,78 @@ +From 33c5fd0c5a774458470c86f9d318d8c48a9c9ccb Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Mon, 26 Nov 2012 16:24:28 +0100 +Subject: [PATCH] lib/canonicalize: add canonicalize_path_restricted() to + canonicalize without suid permisssions + +Signed-off-by: Karel Zak +Signed-off-by: Petr Uzel +--- + include/canonicalize.h | 1 + + lib/canonicalize.c | 42 ++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 43 insertions(+) + +Index: util-linux-2.21.2/include/canonicalize.h +=================================================================== +--- util-linux-2.21.2.orig/include/canonicalize.h ++++ util-linux-2.21.2/include/canonicalize.h +@@ -4,6 +4,7 @@ + #include "c.h" /* for PATH_MAX */ + + extern char *canonicalize_path(const char *path); ++extern char *canonicalize_path_restricted(const char *path); + extern char *canonicalize_dm_name(const char *ptname); + + #endif /* CANONICALIZE_H */ +Index: util-linux-2.21.2/lib/canonicalize.c +=================================================================== +--- util-linux-2.21.2.orig/lib/canonicalize.c ++++ util-linux-2.21.2/lib/canonicalize.c +@@ -188,6 +188,48 @@ canonicalize_path(const char *path) + return strdup(canonical); + } + ++char * ++canonicalize_path_restricted(const char *path) ++{ ++ char canonical[PATH_MAX+2]; ++ char *p = NULL; ++ int errsv; ++ uid_t euid; ++ gid_t egid; ++ ++ if (path == NULL) ++ return NULL; ++ ++ euid = geteuid(); ++ egid = getegid(); ++ ++ /* drop permissions */ ++ if (setegid(getgid()) < 0 || seteuid(getuid()) < 0) ++ return NULL; ++ ++ errsv = errno = 0; ++ ++ if (myrealpath(path, canonical, PATH_MAX+1)) { ++ p = strrchr(canonical, '/'); ++ if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) ++ p = canonicalize_dm_name(p+1); ++ else ++ p = NULL; ++ if (!p) ++ p = strdup(canonical); ++ } else ++ errsv = errno; ++ ++ /* restore */ ++ if (setegid(egid) < 0 || seteuid(euid) < 0) { ++ free(p); ++ return NULL; ++ } ++ ++ errno = errsv; ++ return p; ++} ++ + + #ifdef TEST_PROGRAM_CANONICALIZE + int main(int argc, char **argv) diff --git a/mount-sanitize-paths-from-non-root-users.patch b/mount-sanitize-paths-from-non-root-users.patch new file mode 100644 index 0000000..fe0c1b7 --- /dev/null +++ b/mount-sanitize-paths-from-non-root-users.patch @@ -0,0 +1,102 @@ +From 5ebbc3865d1e53ef42e5f121c41faab23dd59075 Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Mon, 26 Nov 2012 14:30:22 +0100 +Subject: [PATCH] mount: sanitize paths from non-root users + + $ mount /root/.ssh/../../dev/sda2 + mount: only root can mount UUID=17bc65ec-4125-4e7c-8a7d-e2795064c736 on /boot + +this is too promiscuous. It seems better to ignore on command line +specified paths which are not resolve-able for non-root users. + +Fixed version: + + $ mount /root/.ssh/../../dev/sda2 + mount: /root/.ssh/../../dev/sda2: Permission denied + + $ mount /dev/sda2 + mount: only root can mount UUID=17bc65ec-4125-4e7c-8a7d-e2795064c736 on /boot + +Note that this bug has no relation to mount(2) permissions evaluation +in suid mode. The way how non-root user specifies paths on command +line is completely irrelevant for comparison with fstab entries. + +Signed-off-by: Karel Zak +Signed-off-by: Petr Uzel +--- + sys-utils/Makefile.am | 1 + + sys-utils/mount.c | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+) + +Index: util-linux-2.21.2/sys-utils/Makefile.am +=================================================================== +--- util-linux-2.21.2.orig/sys-utils/Makefile.am ++++ util-linux-2.21.2/sys-utils/Makefile.am +@@ -64,6 +64,7 @@ dist_man_MANS += mount.8 ../mount/fstab. + mount_SOURCES = mount.c \ + $(top_srcdir)/lib/env.c \ + $(top_srcdir)/lib/xgetpass.c \ ++ $(top_srcdir)/lib/canonicalize.c \ + $(top_srcdir)/lib/strutils.c + + mount_LDADD = $(ul_libmount_la) $(SELINUX_LIBS) +Index: util-linux-2.21.2/sys-utils/mount.c +=================================================================== +--- util-linux-2.21.2.orig/sys-utils/mount.c ++++ util-linux-2.21.2/sys-utils/mount.c +@@ -38,6 +38,7 @@ + #include "strutils.h" + #include "exitcodes.h" + #include "xalloc.h" ++#include "canonicalize.h" + + /*** TODO: DOCS: + * +@@ -572,6 +573,37 @@ static struct libmnt_table *append_fstab + return fstab; + } + ++/* ++ * Check source and target paths -- non-root user should not be able to ++ * resolve paths which are unreadable for him. ++ */ ++static void sanitize_paths(struct libmnt_context *cxt) ++{ ++ const char *p; ++ struct libmnt_fs *fs = mnt_context_get_fs(cxt); ++ ++ if (!fs) ++ return; ++ ++ p = mnt_fs_get_target(fs); ++ if (p) { ++ char *np = canonicalize_path_restricted(p); ++ if (!np) ++ err(MOUNT_EX_USAGE, "%s", p); ++ mnt_fs_set_target(fs, np); ++ free(np); ++ } ++ ++ p = mnt_fs_get_srcpath(fs); ++ if (p) { ++ char *np = canonicalize_path_restricted(p); ++ if (!np) ++ err(MOUNT_EX_USAGE, "%s", p); ++ mnt_fs_set_source(fs, np); ++ free(np); ++ } ++} ++ + static void __attribute__((__noreturn__)) usage(FILE *out) + { + fputs(USAGE_HEADER, out); +@@ -880,6 +912,9 @@ int main(int argc, char **argv) + } else + usage(stderr); + ++ if (mnt_context_is_restricted(cxt)) ++ sanitize_paths(cxt); ++ + if (oper) { + /* MS_PROPAGATION operations, let's set the mount flags */ + mnt_context_set_mflags(cxt, oper); diff --git a/umount-sanitize-paths-from-non-root-users.patch b/umount-sanitize-paths-from-non-root-users.patch new file mode 100644 index 0000000..0e20756 --- /dev/null +++ b/umount-sanitize-paths-from-non-root-users.patch @@ -0,0 +1,84 @@ +From cc8cc8f32c863f3ae6a8a88e97b47bcd6a21825f Mon Sep 17 00:00:00 2001 +From: Karel Zak +Date: Mon, 26 Nov 2012 16:25:46 +0100 +Subject: [PATCH] umount: sanitize paths from non-root users + +Signed-off-by: Karel Zak +Signed-off-by: Petr Uzel +--- + sys-utils/Makefile.am | 4 +++- + sys-utils/umount.c | 32 ++++++++++++++++++++++++++++++-- + 2 files changed, 33 insertions(+), 3 deletions(-) + +Index: util-linux-2.21.2/sys-utils/Makefile.am +=================================================================== +--- util-linux-2.21.2.orig/sys-utils/Makefile.am ++++ util-linux-2.21.2/sys-utils/Makefile.am +@@ -71,7 +71,9 @@ mount_LDADD = $(ul_libmount_la) $(SELINU + mount_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS) -I$(ul_libmount_incdir) + mount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS) + +-umount_SOURCES = umount.c $(top_srcdir)/lib/env.c ++umount_SOURCES = umount.c \ ++ $(top_srcdir)/lib/env.c \ ++ $(top_srcdir)/lib/canonicalize.c + umount_LDADD = $(ul_libmount_la) + umount_CFLAGS = $(AM_CFLAGS) $(SUID_CFLAGS) -I$(ul_libmount_incdir) + umount_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS) +Index: util-linux-2.21.2/sys-utils/umount.c +=================================================================== +--- util-linux-2.21.2.orig/sys-utils/umount.c ++++ util-linux-2.21.2/sys-utils/umount.c +@@ -34,6 +34,7 @@ + #include "env.h" + #include "optutils.h" + #include "exitcodes.h" ++#include "canonicalize.h" + + static int table_parser_errcb(struct libmnt_table *tb __attribute__((__unused__)), + const char *filename, int line) +@@ -277,6 +278,24 @@ static int umount_one(struct libmnt_cont + return rc; + } + ++/* ++ * Check path -- non-root user should not be able to resolve path which is ++ * unreadable for him. ++ */ ++static char *sanitize_path(const char *path) ++{ ++ char *p; ++ ++ if (!path) ++ return NULL; ++ ++ p = canonicalize_path_restricted(path); ++ if (!p) ++ err(MOUNT_EX_USAGE, "%s", path); ++ ++ return p; ++} ++ + int main(int argc, char **argv) + { + int c, rc = 0, all = 0; +@@ -388,8 +407,17 @@ int main(int argc, char **argv) + } else if (argc < 1) { + usage(stderr); + +- } else while (argc--) +- rc += umount_one(cxt, *argv++); ++ } else while (argc--) { ++ char *path = *argv++; ++ ++ if (mnt_context_is_restricted(cxt)) ++ path = sanitize_path(path); ++ ++ rc += umount_one(cxt, path); ++ ++ if (mnt_context_is_restricted(cxt)) ++ free(path); ++ } + + mnt_free_context(cxt); + return rc; diff --git a/util-linux.changes b/util-linux.changes index 6badc46..ea7d050 100644 --- a/util-linux.changes +++ b/util-linux.changes @@ -1,3 +1,12 @@ +------------------------------------------------------------------- +Mon Jan 7 13:26:15 UTC 2013 - puzel@suse.com + +- add-canonicalize_path_restricted.patch, + mount-sanitize-paths-from-non-root-users.patch, + umount-sanitize-paths-from-non-root-users.patch: + prevent leaking information about existence of folders + (bnc#797002, CVE-2013-0157) + ------------------------------------------------------------------- Fri Dec 28 04:30:58 UTC 2012 - crrodriguez@opensuse.org diff --git a/util-linux.spec b/util-linux.spec index ce79f9c..45fdddc 100644 --- a/util-linux.spec +++ b/util-linux.spec @@ -1,7 +1,7 @@ # # spec file for package util-linux # -# Copyright (c) 2012 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -106,6 +106,13 @@ Patch13: login-close-tty-before-vhangup.patch # hack for boot.localfs Patch20: util-linux-HACK-boot.localfs.diff + +Patch21: 0001-include-bitops.h-Use-the-operating-system-byteswappi.patch + +#bnc#797002 +Patch22: add-canonicalize_path_restricted.patch +Patch23: mount-sanitize-paths-from-non-root-users.patch +Patch24: umount-sanitize-paths-from-non-root-users.patch ##### ## @@ -121,8 +128,6 @@ Patch56: klogconsole.diff ## Patch60: time-1.7.dif -Patch61: 0001-include-bitops.h-Use-the-operating-system-byteswappi.patch - BuildRoot: %{_tmppath}/%{name}-%{version}-build PreReq: %insserv_prereq %fillup_prereq /bin/sed # @@ -223,7 +228,10 @@ Files to develop applications using the libmount library. %patch13 -p1 # %patch20 -p1 -%patch61 -p1 +%patch21 -p1 +%patch22 -p1 +%patch23 -p1 +%patch24 -p1 # cd adjtimex-* # adjtimex patches belongs here