From owner-svn-src-head@FreeBSD.ORG Sun Jan 11 07:56:26 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 21A4F106564A for ; Sun, 11 Jan 2009 07:56:26 +0000 (UTC) (envelope-from christoph.mallon@gmx.de) Received: from mail.gmx.net (mail.gmx.net [213.165.64.20]) by mx1.freebsd.org (Postfix) with SMTP id 927288FC0C for ; Sun, 11 Jan 2009 07:56:25 +0000 (UTC) (envelope-from christoph.mallon@gmx.de) Received: (qmail invoked by alias); 11 Jan 2009 07:56:23 -0000 Received: from p54A3FBCD.dip.t-dialin.net (EHLO tron.homeunix.org) [84.163.251.205] by mail.gmx.net (mp071) with SMTP; 11 Jan 2009 08:56:23 +0100 X-Authenticated: #1673122 X-Provags-ID: V01U2FsdGVkX1/GSVM8ckXGxZdR0dnPLbBAi0FHlWTkyb5tUsmP4+ wf9gsaROxBX7SX Message-ID: <4969A626.6070908@gmx.de> Date: Sun, 11 Jan 2009 08:56:22 +0100 From: Christoph Mallon User-Agent: Thunderbird 2.0.0.19 (X11/20090103) MIME-Version: 1.0 To: obrien@freebsd.org References: <200812262254.mBQMsrbR052676@svn.freebsd.org> <4960FA9A.1090509@gmx.de> <20090111041543.GB17602@dragon.NUXI.org> In-Reply-To: <20090111041543.GB17602@dragon.NUXI.org> Content-Type: multipart/mixed; boundary="------------070304040904040408080004" X-Y-GMX-Trusted: 0 X-FuHaFi: 0.57,0.46 Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org Subject: Re: svn commit: r186504 - head/sbin/mount X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 11 Jan 2009 07:56:26 -0000 This is a multi-part message in MIME format. --------------070304040904040408080004 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit David O'Brien schrieb: > On Sun, Jan 04, 2009 at 07:06:18PM +0100, Christoph Mallon wrote: >> I'm pretty sure $SUPERNATURAL_BEING_OF_YOUR_CHOICE killed a kitten for the >> ugly hack you added to mount. The moment you overflow a buffer, you are in >> no man's land and there's no escape. I appended a patch, which solves this >> issue once and for all: The argv array gets dynamically expanded, when its >> limit is reached. >> Please - for all kittens out there - commit this patch. > > Hi Christoph, > Unfortunately your patch doesn't work. > > For a 'ufs' file system listed in /etc/fstab > $ umount /foo > $ mount /foo > > Does not work. Why haven't you told me earlier? It was a trivial glitch - just a missing "--mnt_argc;". I would've corrected it right away. I tested with a CD and this takes a different code path, which does not trigger the problem. Attached is the corrected patch. --------------070304040904040408080004 Content-Type: text/plain; name="mount.diff" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="mount.diff" Index: mount.c =================================================================== --- mount.c (Revision 187044) +++ mount.c (Arbeitskopie) @@ -69,20 +69,16 @@ #define MOUNT_META_OPTION_CURRENT "current" int debug, fstab_style, verbose; +static char **mnt_argv; +static int mnt_argv_size; +static int mnt_argc; -#define MAX_ARGS 100 -struct cpa { - char *a[MAX_ARGS]; - ssize_t m; - int c; -}; - char *catopt(char *, const char *); struct statfs *getmntpt(const char *); int hasopt(const char *, const char *); int ismounted(struct fstab *, struct statfs *, int); int isremountable(const char *); -void mangle(char *, struct cpa *); +static void mangle(char *); char *update_options(char *, char *, int); int mountfs(const char *, const char *, const char *, int, const char *, const char *); @@ -505,19 +501,21 @@ } static void -append_arg(struct cpa *sa, char *arg) +append_argv(char *arg) { - if (sa->c >= sa->m) - errx(1, "Cannot process more than %zd mount arguments", sa->m); - - sa->a[++sa->c] = arg; + if (mnt_argc == mnt_argv_size) { + mnt_argv_size = mnt_argv_size == 0 ? 16 : mnt_argv_size * 2; + mnt_argv = realloc(mnt_argv, sizeof(*mnt_argv) * mnt_argv_size); + if (mnt_argv == NULL) + errx(1, "realloc failed"); + } + mnt_argv[mnt_argc++] = arg; } int mountfs(const char *vfstype, const char *spec, const char *name, int flags, const char *options, const char *mntopts) { - struct cpa mnt_argv; struct statfs sf; int i, ret; char *optbuf, execname[PATH_MAX], mntpath[PATH_MAX]; @@ -555,29 +553,28 @@ /* Construct the name of the appropriate mount command */ (void)snprintf(execname, sizeof(execname), "mount_%s", vfstype); - mnt_argv.m = MAX_ARGS; - mnt_argv.c = -1; - append_arg(&mnt_argv, execname); - mangle(optbuf, &mnt_argv); - append_arg(&mnt_argv, strdup(spec)); - append_arg(&mnt_argv, strdup(name)); - append_arg(&mnt_argv, NULL); + append_argv(execname); + mangle(optbuf); + append_argv(strdup(spec)); + append_argv(strdup(name)); + append_argv(NULL); + --mnt_argc; /* Do not count the terminating null pointer */ if (debug) { if (use_mountprog(vfstype)) printf("exec: mount_%s", vfstype); else printf("mount -t %s", vfstype); - for (i = 1; i < mnt_argv.c; i++) - (void)printf(" %s", mnt_argv.a[i]); + for (i = 1; i < mnt_argc; i++) + (void)printf(" %s", mnt_argv[i]); (void)printf("\n"); return (0); } if (use_mountprog(vfstype)) { - ret = exec_mountprog(name, execname, mnt_argv.a); + ret = exec_mountprog(name, execname, mnt_argv); } else { - ret = mount_fs(vfstype, mnt_argv.c, mnt_argv.a); + ret = mount_fs(vfstype, mnt_argc, mnt_argv); } free(optbuf); @@ -679,8 +676,8 @@ return (cp); } -void -mangle(char *options, struct cpa *a) +static void +mangle(char *options) { char *p, *s; @@ -715,15 +712,15 @@ sizeof(groupquotaeq) - 1) == 0) { continue; } else if (*p == '-') { - append_arg(a, p); + append_argv(p); p = strchr(p, '='); if (p != NULL) { *p = '\0'; - append_arg(a, p + 1); + append_argv(p + 1); } } else { - append_arg(a, strdup("-o")); - append_arg(a, p); + append_argv(strdup("-o")); + append_argv(p); } } } --------------070304040904040408080004--