Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 18 Feb 2005 10:35:14 -0500
From:      David Schultz <das@FreeBSD.ORG>
To:        "David E. O'Brien" <obrien@FreeBSD.ORG>
Cc:        cvs-all@FreeBSD.ORG
Subject:   Re: cvs commit: src/sys/sys syslimits.h
Message-ID:  <20050218153513.GA3581@VARK.MIT.EDU>
In-Reply-To: <200502180801.j1I81xYJ085925@repoman.freebsd.org>
References:  <200502180801.j1I81xYJ085925@repoman.freebsd.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, Feb 18, 2005, David E. O'Brien wrote:
> obrien      2005-02-18 08:01:59 UTC
> 
>   FreeBSD src repository
> 
>   Modified files:
>     sys/sys              syslimits.h 
>   Log:
>   For non-embedded platforms, increase the size of the argument list.
>   Note that this results in more kernel virtual memory being reserved for
>   temporary storage of the args.  The args temporary space is allocated out
>   of exec_map (a submap of kernel_map).  This will use roughly 4MB of KVM.

Great!  FWIW, I've been running with ARG_MAX == 4MB for a while
now without incident.  256K is still slightly too small to do
things like (cd /usr/ports && grep foo */*/Makefile) without
having to rewrite them in more complicated ways involving find and
xargs.  With 4MB, the simple invocations like the above just work,
and I've never hit the limit.

The kernel buffer for exec is temporary, so it hasn't caused any
problems for my (relatively undemanding) workloads.  I would
suggest increasing it to at least 1MB unless you, dg or someone
else thinks that would cause problems.

By the way, there are a few components of the base system that
still don't use sysconf() to get the kernel's value of ARG_MAX.
Fortunately, AFAICT, none of them break in an insecure way as a
result of increasing the argument limit.  Here are the ones I
patched.

Index: lib/libc/gen/glob.c
===================================================================
RCS file: /cvs/src/lib/libc/gen/glob.c,v
retrieving revision 1.22
diff -u -r1.22 glob.c
--- lib/libc/gen/glob.c	29 Jul 2004 03:48:52 -0000	1.22
+++ lib/libc/gen/glob.c	18 Feb 2005 00:40:57 -0000
@@ -188,8 +188,11 @@
 	}
 	if (flags & GLOB_LIMIT) {
 		limit = pglob->gl_matchc;
-		if (limit == 0)
-			limit = ARG_MAX;
+		if (limit == 0) {
+			limit = sysconf(_SC_ARG_MAX);
+			if (limit <= 0)
+				return (GLOB_NOSPACE);
+		}
 	} else
 		limit = 0;
 	pglob->gl_flags = flags & ~GLOB_MAGCHAR;
Index: libexec/rexecd/rexecd.c
===================================================================
RCS file: /cvs/src/libexec/rexecd/rexecd.c,v
retrieving revision 1.32
diff -u -r1.32 rexecd.c
--- libexec/rexecd/rexecd.c	14 Feb 2005 17:42:57 -0000	1.32
+++ libexec/rexecd/rexecd.c	18 Feb 2005 00:48:14 -0000
@@ -130,7 +130,8 @@
 static void
 doit(struct sockaddr *fromp)
 {
-	char cmdbuf[NCARGS+1], *cp;
+	char *cmdbuf, *cp;
+	int maxcmdlen;
 	const char *namep;
 	char user[16], pass[16];
 	struct passwd *pwd;
@@ -142,6 +143,10 @@
 	int one = 1;
 	char **envlist, **env;
 
+	maxcmdlen = (int)sysconf(_SC_ARG_MAX);
+	if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL)
+		exit(1);
+
 	(void) signal(SIGINT, SIG_DFL);
 	(void) signal(SIGQUIT, SIG_DFL);
 	(void) signal(SIGTERM, SIG_DFL);
@@ -181,7 +186,7 @@
 	}
 	getstr(user, sizeof(user), "username");
 	getstr(pass, sizeof(pass), "password");
-	getstr(cmdbuf, sizeof(cmdbuf), "command");
+	getstr(cmdbuf, maxcmdlen, "command");
 	(void) alarm(0);
 
 	if ((pwd = getpwnam(user))  == NULL || (pwd->pw_uid = 0 && no_uid_0) ||
Index: libexec/rshd/rshd.c
===================================================================
RCS file: /cvs/src/libexec/rshd/rshd.c,v
retrieving revision 1.49
diff -u -r1.49 rshd.c
--- libexec/rshd/rshd.c	14 Feb 2005 17:42:58 -0000	1.49
+++ libexec/rshd/rshd.c	18 Feb 2005 00:48:56 -0000
@@ -195,12 +195,17 @@
 	int one = 1;
 	const char *cp, *errorstr;
 	char sig, buf[BUFSIZ];
-	char cmdbuf[NCARGS+1], luser[16], ruser[16];
+	char *cmdbuf, luser[16], ruser[16];
 	char rhost[2 * MAXHOSTNAMELEN + 1];
 	char numericname[INET6_ADDRSTRLEN];
 	int af, srcport;
+	int maxcmdlen;
 	login_cap_t *lc;
 
+	maxcmdlen = (int)sysconf(_SC_ARG_MAX);
+	if (maxcmdlen <= 0 || (cmdbuf = malloc(maxcmdlen)) == NULL)
+		exit(1);
+
 	(void) signal(SIGINT, SIG_DFL);
 	(void) signal(SIGQUIT, SIG_DFL);
 	(void) signal(SIGTERM, SIG_DFL);
@@ -301,7 +306,7 @@
 	(void) alarm(60);
 	getstr(ruser, sizeof(ruser), "ruser");
 	getstr(luser, sizeof(luser), "luser");
-	getstr(cmdbuf, sizeof(cmdbuf), "command");
+	getstr(cmdbuf, maxcmdlen, "command");
 	(void) alarm(0);
 
 	pam_err = pam_start("rsh", luser, &pamc, &pamh);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050218153513.GA3581>