Go to:
Gentoo Home
Documentation
Forums
Lists
Bugs
Planet
Store
Wiki
Get Gentoo!
Gentoo's Bugzilla – Attachment 162291 Details for
Bug 98403
patch to util-linux that makes mount write to /etc/mtab symlinks, as long as they don't point to /proc
Home
|
New
–
[Ex]
|
Browse
|
Search
|
Privacy Policy
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
New version of the patch to apply against 2.13.1.1
util-linux-2.13.1.1-symlink-mtab.patch (text/plain), 13.38 KB, created by
Allen Fuller
on 2008-08-05 19:16:28 UTC
(
hide
)
Description:
New version of the patch to apply against 2.13.1.1
Filename:
MIME Type:
Creator:
Allen Fuller
Created:
2008-08-05 19:16:28 UTC
Size:
13.38 KB
patch
obsolete
>diff -ur util-linux-ng-2.13.1.1/mount/fstab.c util-linux-ng-2.13.1.1-new/mount/fstab.c >--- util-linux-ng-2.13.1.1/mount/fstab.c 2008-08-05 09:55:06.000000000 -0700 >+++ util-linux-ng-2.13.1.1-new/mount/fstab.c 2008-08-05 09:30:51.000000000 -0700 >@@ -2,6 +2,8 @@ > * - added Native Language Support > * Sun Mar 21 1999 - Arnaldo Carvalho de Melo <acme@conectiva.com.br> > * - fixed strerr(errno) in gettext calls >+ * 2003-08-08 Thomas Hood <jdthood@yahoo.co.uk> with help from Patrick McLean >+ * - Write through a symlink at /etc/mtab if it doesn't point into /proc/ > */ > > #include <unistd.h> >@@ -13,59 +15,114 @@ > #include <time.h> > #include "mount_mntent.h" > #include "fstab.h" >+#include "realpath.h" > #include "sundries.h" > #include "xmalloc.h" > #include "fsprobe.h" > #include "mount_paths.h" > #include "nls.h" > >-#define streq(s, t) (strcmp ((s), (t)) == 0) >- >-#define PROC_MOUNTS "/proc/mounts" >- >+/* A 64 bit number can be displayed in 20 decimal digits */ >+#define LEN_LARGEST_PID 20 >+#define MTAB_PATH_MAX (PATH_MAX - (sizeof(MTAB_LOCK_SUFFIX) - 1) - LEN_LARGEST_PID) > > /* Information about mtab. ------------------------------------*/ >-static int have_mtab_info = 0; >-static int var_mtab_does_not_exist = 0; >-static int var_mtab_is_a_symlink = 0; >+static char mtab_path[MTAB_PATH_MAX]; >+static char mtab_lock_path[PATH_MAX]; >+static char mtab_lock_targ[PATH_MAX]; >+static char mtab_temp_path[PATH_MAX]; > >-static void >+/* >+ * Set mtab_path to the real path of the mtab file >+ * or to the null string if that path is inaccessible >+ * >+ * Run this early >+ */ >+void > get_mtab_info(void) { > struct stat mtab_stat; > >- if (!have_mtab_info) { >- if (lstat(MOUNTED, &mtab_stat)) >- var_mtab_does_not_exist = 1; >- else if (S_ISLNK(mtab_stat.st_mode)) >- var_mtab_is_a_symlink = 1; >- have_mtab_info = 1; >+ if (lstat(MOUNTED, &mtab_stat)) { >+ /* Assume that the lstat error means that the file does not exist */ >+ /* (Maybe we should check errno here) */ >+ strcpy(mtab_path, MOUNTED); >+ } else if (S_ISLNK(mtab_stat.st_mode)) { >+ /* Is a symlink */ >+ int len; >+ char *r = myrealpath(MOUNTED, mtab_path, MTAB_PATH_MAX); >+ mtab_path[MTAB_PATH_MAX - 1] = 0; /* Just to be sure */ >+ len = strlen(mtab_path); >+ if ( >+ r == NULL >+ || len == 0 >+ || len >= (MTAB_PATH_MAX - 1) >+ || streqn(mtab_path, PATH_PROC, sizeof(PATH_PROC) - 1) >+ ) { >+ /* Real path invalid or inaccessible */ >+ mtab_path[0] = '\0'; >+ return; >+ } >+ /* mtab_path now contains mtab's real path */ >+ } else { >+ /* Exists and is not a symlink */ >+ strcpy(mtab_path, MOUNTED); > } >+ >+ sprintf(mtab_lock_path, "%s%s", mtab_path, MTAB_LOCK_SUFFIX); >+ sprintf(mtab_lock_targ, "%s%s%d", mtab_path, MTAB_LOCK_SUFFIX, getpid()); >+ sprintf(mtab_temp_path, "%s%s", mtab_path, MTAB_TEMP_SUFFIX); > } > >+ >+/* >+ * Tell whether or not the mtab real path is accessible >+ * >+ * get_mtab_info() must have been run >+ */ >+static int >+mtab_is_accessible(void) { >+ return (mtab_path[0] != '\0'); >+} >+ >+/* >+ * Tell whether or not the mtab file currently exists >+ * >+ * Note that the answer here is independent of whether or >+ * not the file is writable, so if you are planning to create >+ * the mtab file then check mtab_is_writable() too. >+ * >+ * get_mtab_info() must have been run >+ */ > int > mtab_does_not_exist(void) { >- get_mtab_info(); >- return var_mtab_does_not_exist; >-} >+ struct stat mtab_stat; > >-static int >-mtab_is_a_symlink(void) { >- get_mtab_info(); >- return var_mtab_is_a_symlink; >+ if (!mtab_is_accessible()) >+ return 1; >+ >+ if (lstat(mtab_path, &mtab_stat)) >+ return 1; >+ >+ return 0; > } > >+/* >+ * Tell whether or not mtab is writable (whether or not it currently exists) >+ * >+ * This depends on whether or not the real path is accessible and, >+ * if so, whether or not the file can be opened. This function >+ * has the side effect of creating the file if it is writable. >+ * >+ * get_mtab_info() must have been run >+ */ > int > mtab_is_writable() { > int fd; > >- /* Should we write to /etc/mtab upon an update? >- Probably not if it is a symlink to /proc/mounts, since that >- would create a file /proc/mounts in case the proc filesystem >- is not mounted. */ >- if (mtab_is_a_symlink()) >+ if (!mtab_is_accessible()) > return 0; > >- fd = open(MOUNTED, O_RDWR | O_CREAT, 0644); >+ fd = open(mtab_path, O_RDWR | O_CREAT, 0644); > if (fd >= 0) { > close(fd); > return 1; >@@ -161,21 +218,21 @@ > got_mtab = 1; > mc->nxt = mc->prev = NULL; > >- fnam = MOUNTED; >+ fnam = mtab_path; > mfp = my_setmntent (fnam, "r"); > if (mfp == NULL || mfp->mntent_fp == NULL) { > int errsv = errno; >- fnam = PROC_MOUNTS; >+ fnam = PATH_PROC_MOUNTS; > mfp = my_setmntent (fnam, "r"); > if (mfp == NULL || mfp->mntent_fp == NULL) { > error(_("warning: can't open %s: %s"), >- MOUNTED, strerror (errsv)); >+ mtab_path, strerror (errsv)); > return; > } > if (verbose) > printf (_("mount: could not open %s - " > "using %s instead\n"), >- MOUNTED, PROC_MOUNTS); >+ mtab_path, PATH_PROC_MOUNTS); > } > read_mntentchn(mfp, fnam, mc); > } >@@ -482,7 +539,7 @@ > if (we_created_lockfile) { > close(lockfile_fd); > lockfile_fd = -1; >- unlink (MOUNTED_LOCK); >+ unlink (mtab_lock_path); > we_created_lockfile = 0; > } > } >@@ -501,12 +558,6 @@ > to delete the lock afterwards. Now the use of flock() is in principle > superfluous, but avoids an arbitrary sleep(). */ > >-/* Where does the link point to? Obvious choices are mtab and mtab~~. >- HJLu points out that the latter leads to races. Right now we use >- mtab~.<pid> instead. Use 20 as upper bound for the length of %d. */ >-#define MOUNTLOCK_LINKTARGET MOUNTED_LOCK "%d" >-#define MOUNTLOCK_LINKTARGET_LTH (sizeof(MOUNTED_LOCK)+20) >- > /* > * The original mount locking code has used sleep(1) between attempts and > * maximal number of attemps has been 5. >@@ -533,7 +584,6 @@ > int i; > struct timespec waittime; > struct timeval maxtime; >- char linktargetfile[MOUNTLOCK_LINKTARGET_LTH]; > > at_die = unlock_mtab; > >@@ -556,18 +606,16 @@ > signals_have_been_setup = 1; > } > >- sprintf(linktargetfile, MOUNTLOCK_LINKTARGET, getpid ()); >- >- i = open (linktargetfile, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); >+ i = open (mtab_lock_targ, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); > if (i < 0) { > int errsv = errno; >- /* linktargetfile does not exist (as a file) >+ /* mtab_lock_targ does not exist (as a file) > and we cannot create it. Read-only filesystem? > Too many files open in the system? > Filesystem full? */ > die (EX_FILEIO, _("can't create lock file %s: %s " > "(use -n flag to override)"), >- linktargetfile, strerror (errsv)); >+ mtab_lock_targ, strerror (errsv)); > } > close(i); > >@@ -583,20 +631,20 @@ > struct flock flock; > int errsv, j; > >- j = link(linktargetfile, MOUNTED_LOCK); >+ j = link(mtab_lock_targ, mtab_lock_path); > errsv = errno; > > if (j == 0) > we_created_lockfile = 1; > > if (j < 0 && errsv != EEXIST) { >- (void) unlink(linktargetfile); >+ (void) unlink(mtab_lock_targ); > die (EX_FILEIO, _("can't link lock file %s: %s " > "(use -n flag to override)"), >- MOUNTED_LOCK, strerror (errsv)); >+ mtab_lock_path, strerror (errsv)); > } > >- lockfile_fd = open (MOUNTED_LOCK, O_WRONLY); >+ lockfile_fd = open (mtab_lock_path, O_WRONLY); > > if (lockfile_fd < 0) { > /* Strange... Maybe the file was just deleted? */ >@@ -606,10 +654,10 @@ > we_created_lockfile = 0; > continue; > } >- (void) unlink(linktargetfile); >+ (void) unlink(mtab_lock_targ); > die (EX_FILEIO, _("can't open lock file %s: %s " > "(use -n flag to override)"), >- MOUNTED_LOCK, strerror (errsv)); >+ mtab_lock_path, strerror (errsv)); > } > > flock.l_type = F_WRLCK; >@@ -623,11 +671,11 @@ > if (verbose) { > int errsv = errno; > printf(_("Can't lock lock file %s: %s\n"), >- MOUNTED_LOCK, strerror (errsv)); >+ mtab_lock_path, strerror (errsv)); > } > /* proceed, since it was us who created the lockfile anyway */ > } >- (void) unlink(linktargetfile); >+ (void) unlink(mtab_lock_targ); > } else { > /* Someone else made the link. Wait. */ > gettimeofday(&now, NULL); >@@ -635,19 +683,19 @@ > alarm(maxtime.tv_sec - now.tv_sec); > if (fcntl (lockfile_fd, F_SETLKW, &flock) == -1) { > int errsv = errno; >- (void) unlink(linktargetfile); >+ (void) unlink(mtab_lock_targ); > die (EX_FILEIO, _("can't lock lock file %s: %s"), >- MOUNTED_LOCK, (errno == EINTR) ? >+ mtab_lock_path, (errno == EINTR) ? > _("timed out") : strerror (errsv)); > } > alarm(0); > > nanosleep(&waittime, NULL); > } else { >- (void) unlink(linktargetfile); >+ (void) unlink(mtab_lock_targ); > die (EX_FILEIO, _("Cannot create link %s\n" > "Perhaps there is a stale lock file?\n"), >- MOUNTED_LOCK); >+ mtab_lock_path); > } > close(lockfile_fd); > } >@@ -667,16 +715,16 @@ > void > update_mtab (const char *dir, struct my_mntent *instead) { > mntFILE *mfp, *mftmp; >- const char *fnam = MOUNTED; >+ const char *fnam = mtab_path; > struct mntentchn mtabhead; /* dummy */ > struct mntentchn *mc, *mc0, *absent = NULL; > >- if (mtab_does_not_exist() || !mtab_is_writable()) >+ if (mtab_does_not_exist()) > return; > > lock_mtab(); > >- /* having locked mtab, read it again */ >+ /* having gotten the lock, we read mtab again */ > mc0 = mc = &mtabhead; > mc->nxt = mc->prev = NULL; > >@@ -733,11 +781,11 @@ > } > > /* write chain to mtemp */ >- mftmp = my_setmntent (MOUNTED_TEMP, "w"); >+ mftmp = my_setmntent (mtab_temp_path, "w"); > if (mftmp == NULL || mftmp->mntent_fp == NULL) { > int errsv = errno; > error (_("cannot open %s (%s) - mtab not updated"), >- MOUNTED_TEMP, strerror (errsv)); >+ mtab_temp_path, strerror (errsv)); > discard_mntentchn(mc0); > goto leave; > } >@@ -746,7 +794,7 @@ > if (my_addmntent(mftmp, &(mc->m)) == 1) { > int errsv = errno; > die (EX_FILEIO, _("error writing %s: %s"), >- MOUNTED_TEMP, strerror (errsv)); >+ mtab_temp_path, strerror (errsv)); > } > } > >@@ -756,25 +804,25 @@ > S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) < 0) { > int errsv = errno; > fprintf(stderr, _("error changing mode of %s: %s\n"), >- MOUNTED_TEMP, strerror (errsv)); >+ mtab_temp_path, strerror (errsv)); > } > my_endmntent (mftmp); > > { /* > * If mount is setuid and some non-root user mounts sth, >- * then mtab.tmp might get the group of this user. Copy uid/gid >- * from the present mtab before renaming. >+ * then the temp file might get the group of this user. >+ * Copy uid/gid from the present mtab before renaming. > */ > struct stat sbuf; >- if (stat (MOUNTED, &sbuf) == 0) >- chown (MOUNTED_TEMP, sbuf.st_uid, sbuf.st_gid); >+ if (stat (mtab_path, &sbuf) == 0) >+ chown (mtab_temp_path, sbuf.st_uid, sbuf.st_gid); > } > > /* rename mtemp to mtab */ >- if (rename (MOUNTED_TEMP, MOUNTED) < 0) { >+ if (rename (mtab_temp_path, mtab_path) < 0) { > int errsv = errno; > fprintf(stderr, _("can't rename %s to %s: %s\n"), >- MOUNTED_TEMP, MOUNTED, strerror(errsv)); >+ mtab_temp_path, mtab_path, strerror(errsv)); > } > > leave: >diff -ur util-linux-ng-2.13.1.1/mount/mount.c util-linux-ng-2.13.1.1-new/mount/mount.c >--- util-linux-ng-2.13.1.1/mount/mount.c 2008-08-05 09:55:06.000000000 -0700 >+++ util-linux-ng-2.13.1.1-new/mount/mount.c 2008-08-05 09:43:24.000000000 -0700 >@@ -519,7 +519,11 @@ > return ret; > } > >-/* Create mtab with a root entry. */ >+/* >+ * Create mtab with a root entry. >+ * >+ * Caller should check that mtab is writable first >+ */ > static void > create_mtab (void) { > struct mntentchn *fstab; >@@ -1813,6 +1817,9 @@ > initproctitle(argc, argv); > #endif > >+ get_mtab_info(); >+ /* Keep in mind that /etc/mtab may be a symlink */ >+ > while ((c = getopt_long (argc, argv, "afFhilL:no:O:p:rsU:vVwt:", > longopts, NULL)) != -1) { > switch (c) { >@@ -1970,7 +1977,7 @@ > die (EX_USAGE, _("mount: only root can do that")); > } > >- if (!nomtab && mtab_does_not_exist()) { >+ if (!nomtab && mtab_does_not_exist() && mtab_is_writable()) { > if (verbose > 1) > printf(_("mount: no %s found - creating it..\n"), > MOUNTED); >diff -ur util-linux-ng-2.13.1.1/mount/mount_paths.h util-linux-ng-2.13.1.1-new/mount/mount_paths.h >--- util-linux-ng-2.13.1.1/mount/mount_paths.h 2008-08-05 09:55:06.000000000 -0700 >+++ util-linux-ng-2.13.1.1-new/mount/mount_paths.h 2008-08-05 09:49:51.000000000 -0700 >@@ -4,7 +4,12 @@ > #include <mntent.h> > > #define _PATH_FSTAB "/etc/fstab" >-#define PROC_SWAPS "/proc/swaps" >+#define PATH_PROC "/proc/" >+#define PROC_SWAPS PATH_PROC "swaps" >+#define PATH_PROC_MOUNTS PATH_PROC "mounts" >+ >+#define MTAB_LOCK_SUFFIX "~" >+#define MTAB_TEMP_SUFFIX ".tmp" > > #ifdef _PATH_MOUNTED > # define MOUNTED_LOCK _PATH_MOUNTED "~" >diff -ur util-linux-ng-2.13.1.1/mount/sundries.h util-linux-ng-2.13.1.1-new/mount/sundries.h >--- util-linux-ng-2.13.1.1/mount/sundries.h 2008-08-05 09:55:06.000000000 -0700 >+++ util-linux-ng-2.13.1.1-new/mount/sundries.h 2008-08-05 09:12:19.000000000 -0700 >@@ -21,6 +21,7 @@ > extern int sloppy; > > #define streq(s, t) (strcmp ((s), (t)) == 0) >+#define streqn(s, t, n) (strncmp((s), (t), (n)) == 0) > > /* Functions in sundries.c that are used in mount.c and umount.c */ > void block_signals (int how); >diff -ur util-linux-ng-2.13.1.1/mount/umount.c util-linux-ng-2.13.1.1-new/mount/umount.c >--- util-linux-ng-2.13.1.1/mount/umount.c 2008-08-05 09:55:06.000000000 -0700 >+++ util-linux-ng-2.13.1.1-new/mount/umount.c 2008-08-05 09:13:39.000000000 -0700 >@@ -574,6 +574,8 @@ > > umask(022); > >+ get_mtab_info(); >+ > while ((c = getopt_long (argc, argv, "adfhlnrit:O:vV", > longopts, NULL)) != -1) > switch (c) {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 98403
:
62963
|
62964
|
63637
|
63980
|
68807
| 162291