Index: kern/kern_exec.c =================================================================== --- kern/kern_exec.c +++ kern/kern_exec.c @@ -1194,7 +1194,7 @@ args->begin_argv = args->buf + length; args->endp = args->begin_argv; - args->stringspace = ARG_MAX; + args->stringspace = argmax; /* * extract arguments first @@ -1264,14 +1264,14 @@ memset(args, '\0', sizeof(*args)); ofdp = td->td_proc->p_fd; - if (datalen >= ARG_MAX || fdslen > ofdp->fd_lastfile + 1) + if (datalen >= argmax || fdslen > ofdp->fd_lastfile + 1) return (E2BIG); error = exec_alloc_args(args); if (error != 0) return (error); args->begin_argv = args->buf; - args->stringspace = ARG_MAX; + args->stringspace = argmax; if (datalen > 0) { /* @@ -1484,7 +1484,7 @@ copyout(pagesizes, (void *)destp, szps); imgp->pagesizeslen = szps; - destp -= ARG_MAX - imgp->args->stringspace; + destp -= argmax - imgp->args->stringspace; destp = rounddown2(destp, sizeof(void *)); /* @@ -1527,7 +1527,7 @@ /* * Copy out strings - arguments and environment. */ - copyout(stringp, (void *)destp, ARG_MAX - imgp->args->stringspace); + copyout(stringp, (void *)destp, argmax - imgp->args->stringspace); /* * Fill in "ps_strings" struct for ps, w, etc. Index: kern/kern_mib.c =================================================================== --- kern/kern_mib.c +++ kern/kern_mib.c @@ -112,8 +112,8 @@ SYSCTL_INT(_kern, OID_AUTO, maxusers, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &maxusers, 0, "Hint for kernel tuning"); -SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RD|CTLFLAG_CAPRD, - SYSCTL_NULL_INT_PTR, ARG_MAX, "Maximum bytes of argument to execve(2)"); +SYSCTL_INT(_kern, KERN_ARGMAX, argmax, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, + &argmax, ARG_MAX, "Maximum bytes of argument to execve(2)"); SYSCTL_INT(_kern, KERN_POSIX1, posix1version, CTLFLAG_RD|CTLFLAG_CAPRD, SYSCTL_NULL_INT_PTR, _POSIX_VERSION, "Version of POSIX attempting to comply to"); Index: kern/subr_param.c =================================================================== --- kern/subr_param.c +++ kern/subr_param.c @@ -78,6 +78,12 @@ #ifndef MAXFILES #define MAXFILES (40 + 32 * maxusers) #endif +#ifndef ARG_MAX +#define ARG_MAX 262144 +#endif +#ifndef _POSIX_ARG_MAX +#define _POSIX_ARG_MAX 4096 +#endif static int sysctl_kern_vm_guest(SYSCTL_HANDLER_ARGS); @@ -106,6 +112,7 @@ u_long dflssiz; /* initial stack size limit */ u_long maxssiz; /* max stack size */ u_long sgrowsiz; /* amount to grow stack */ +int argmax; /* max bytes of argument to exec */ SYSCTL_INT(_kern, OID_AUTO, hz, CTLFLAG_RDTUN | CTLFLAG_NOFETCH, &hz, 0, "Number of clock ticks per second"); @@ -294,6 +301,11 @@ if (maxpipekva > (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 64) maxpipekva = (VM_MAX_KERNEL_ADDRESS - VM_MIN_KERNEL_ADDRESS) / 64; + + argmax = ARG_MAX; + TUNABLE_INT_FETCH("kern.argmax", &argmax); + if (argmax < _POSIX_ARG_MAX) + argmax = _POSIX_ARG_MAX; } /* Index: sys/proc.h =================================================================== --- sys/proc.h +++ sys/proc.h @@ -929,6 +929,7 @@ extern int lastpid; extern int nprocs, maxproc; /* Current and max number of procs. */ extern int maxprocperuid; /* Max procs per uid. */ +extern int argmax; /* Max bytes of argument to exec. */ extern u_long ps_arg_cache_limit; LIST_HEAD(proclist, proc); Index: vm/vm_init.c =================================================================== --- vm/vm_init.c +++ vm/vm_init.c @@ -277,7 +277,7 @@ #else exec_map_entries = 2 * mp_ncpus + 4; #endif - exec_map_entry_size = round_page(PATH_MAX + ARG_MAX); + exec_map_entry_size = round_page(PATH_MAX + argmax); exec_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, exec_map_entries * exec_map_entry_size + 64 * PAGE_SIZE, FALSE); pipe_map = kmem_suballoc(kernel_map, &minaddr, &maxaddr, maxpipekva,