mirror of git://git.suckless.org/ubase
mount: fix mount helper fs option handling
If a mount helper is used, only argopts (given on commandline) are passed to the helper via -o parameter. Option strings from fstab are ignored. This patch replaces global argopts pointer with a character array fsopts. A maximum length for filesytem options is #defined (used by fsopts and data), and argument/mntent options are length-checked to fit. A filesystem with too long an option string will print an error, cause mount to exit with an error status, and not attempt to mount the filesystem. This obviates the need for overflow checking of data in parseopts(), though it hasn't been removed.
This commit is contained in:
parent
4ece17d605
commit
4dbd00fc94
32
mount.c
32
mount.c
|
@ -15,6 +15,8 @@
|
||||||
#include "text.h"
|
#include "text.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
|
||||||
|
#define FSOPTS_MAXLEN 512
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
const char *opt;
|
const char *opt;
|
||||||
const char *notopt;
|
const char *notopt;
|
||||||
|
@ -37,7 +39,7 @@ struct {
|
||||||
};
|
};
|
||||||
|
|
||||||
static unsigned long argflags = 0;
|
static unsigned long argflags = 0;
|
||||||
static char *argopts = NULL;
|
static char fsopts[FSOPTS_MAXLEN] = "";
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
findtype(const char *types, const char *t)
|
findtype(const char *types, const char *t)
|
||||||
|
@ -121,9 +123,9 @@ mounthelper(const char *fsname, const char *dir, const char *fstype)
|
||||||
if (argflags & MS_REC)
|
if (argflags & MS_REC)
|
||||||
eargv[i++] = "-R";
|
eargv[i++] = "-R";
|
||||||
|
|
||||||
if (argopts) {
|
if (fsopts[0]) {
|
||||||
eargv[i++] = "-o";
|
eargv[i++] = "-o";
|
||||||
eargv[i++] = argopts;
|
eargv[i++] = fsopts;
|
||||||
}
|
}
|
||||||
eargv[i++] = fsname;
|
eargv[i++] = fsname;
|
||||||
eargv[i++] = dir;
|
eargv[i++] = dir;
|
||||||
|
@ -188,11 +190,11 @@ usage(void)
|
||||||
int
|
int
|
||||||
main(int argc, char *argv[])
|
main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
char *types = NULL, data[512] = "", *resolvpath = NULL;
|
char *types = NULL, data[FSOPTS_MAXLEN] = "", *resolvpath = NULL;
|
||||||
char *files[] = { "/proc/mounts", "/etc/fstab", NULL };
|
char *files[] = { "/proc/mounts", "/etc/fstab", NULL };
|
||||||
const char *source, *target;
|
const char *source, *target;
|
||||||
struct mntent *me = NULL;
|
struct mntent *me = NULL;
|
||||||
int aflag = 0, oflag = 0, status = 0, i, r;
|
int aflag = 0, status = 0, i, r;
|
||||||
unsigned long flags = 0;
|
unsigned long flags = 0;
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
|
|
||||||
|
@ -210,9 +212,9 @@ main(int argc, char *argv[])
|
||||||
aflag = 1;
|
aflag = 1;
|
||||||
break;
|
break;
|
||||||
case 'o':
|
case 'o':
|
||||||
oflag = 1;
|
if (strlcat(fsopts, EARGF(usage()), sizeof(fsopts)) >= sizeof(fsopts))
|
||||||
argopts = EARGF(usage());
|
eprintf("option string too long\n");
|
||||||
parseopts(argopts, &flags, data, sizeof(data));
|
parseopts(fsopts, &flags, data, sizeof(data));
|
||||||
break;
|
break;
|
||||||
case 't':
|
case 't':
|
||||||
types = EARGF(usage());
|
types = EARGF(usage());
|
||||||
|
@ -260,8 +262,10 @@ main(int argc, char *argv[])
|
||||||
target = me->mnt_dir;
|
target = me->mnt_dir;
|
||||||
source = me->mnt_fsname;
|
source = me->mnt_fsname;
|
||||||
}
|
}
|
||||||
if (!oflag)
|
if (!fsopts[0])
|
||||||
parseopts(me->mnt_opts, &flags, data, sizeof(data));
|
if (strlcat(fsopts, me->mnt_opts, sizeof(fsopts)) >= sizeof(fsopts))
|
||||||
|
eprintf("%s: option string too long\n", target);
|
||||||
|
parseopts(fsopts, &flags, data, sizeof(data));
|
||||||
if (!types)
|
if (!types)
|
||||||
types = me->mnt_type;
|
types = me->mnt_type;
|
||||||
goto mountsingle;
|
goto mountsingle;
|
||||||
|
@ -294,7 +298,13 @@ mountall:
|
||||||
if (hasmntopt(me, MNTOPT_NOAUTO) || mounted(me->mnt_dir))
|
if (hasmntopt(me, MNTOPT_NOAUTO) || mounted(me->mnt_dir))
|
||||||
continue;
|
continue;
|
||||||
flags = 0;
|
flags = 0;
|
||||||
parseopts(me->mnt_opts, &flags, data, sizeof(data));
|
fsopts[0] = '\0';
|
||||||
|
if (strlcat(fsopts, me->mnt_opts, sizeof(fsopts)) >= sizeof(fsopts)) {
|
||||||
|
weprintf("%s: option string too long\n", me->mnt_dir);
|
||||||
|
status = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
parseopts(fsopts, &flags, data, sizeof(data));
|
||||||
/* if -t types specified:
|
/* if -t types specified:
|
||||||
* if non-match, skip
|
* if non-match, skip
|
||||||
* if match and prefixed with "no", skip */
|
* if match and prefixed with "no", skip */
|
||||||
|
|
Loading…
Reference in New Issue