Ping?
On Wed, Dec 16, 2015 at 9:55 PM, Maxim Pugachev <[email protected]> wrote:
> Ping?
>
> On Sat, Dec 12, 2015 at 8:38 PM, Maxim Pugachev <[email protected]> wrote:
>> Hi,
>>
>> This patch removes copypasted code that prepares args and env in exec
>> system call.
>>
>>
>> Index: sys/kern/kern_exec.c
>> ===================================================================
>> RCS file: /cvs/src/sys/kern/kern_exec.c,v
>> retrieving revision 1.173
>> diff -u -p -r1.173 kern_exec.c
>> --- sys/kern/kern_exec.c 5 Dec 2015 10:11:53 -0000 1.173
>> +++ sys/kern/kern_exec.c 12 Dec 2015 17:34:43 -0000
>> @@ -77,6 +77,12 @@ const struct kmem_va_mode kv_exec = {
>> .kv_map = &exec_map
>> };
>>
>> +struct argcontext
>> +{
>> + char *buffer;
>> + char *bptr;
>> +};
>> +
>> /*
>> * Map the shared signal code.
>> */
>> @@ -231,6 +237,58 @@ bad1:
>> return (error);
>> }
>>
>> +void
>> +copy_fake_args(struct exec_package *pack, struct argcontext *argctx,
>> + long *count)
>> +{
>> + char **fake_args_vec = pack->ep_fa;
>> +
>> + while (*fake_args_vec != NULL) {
>> + char *arg = *fake_args_vec;
>> +
>> + while (*arg)
>> + *argctx->bptr++ = *arg++;
>> +
>> + *argctx->bptr++ = '\0';
>> +
>> + free(*fake_args_vec, M_EXEC, 0);
>> +
>> + fake_args_vec++;
>> + (*count)++;
>> + }
>> +
>> + free(pack->ep_fa, M_EXEC, 0);
>> + pack->ep_flags &= ~EXEC_HASARGL;
>> +}
>> +
>> +int
>> +copy_strings(char * const *src, struct argcontext *argctx, long *count)
>> +{
>> + int error;
>> + size_t len;
>> + size_t maxlen = argctx->buffer + ARG_MAX - argctx->bptr;
>> + char *sp;
>> +
>> + while (1) {
>> + if ((error = copyin(src, &sp, sizeof(sp))) != 0)
>> + return error;
>> + if (!sp)
>> + break;
>> + if ((error = copyinstr(sp, argctx->bptr, maxlen, &len)) !=
>> 0) {
>> + if (error == ENAMETOOLONG)
>> + error = E2BIG;
>> + return error;
>> + }
>> +
>> + maxlen -= len;
>> + argctx->bptr += len;
>> + src++;
>> + (*count)++;
>> + }
>> +
>> + return 0;
>> +}
>> +
>> /*
>> * exec system call
>> */
>> @@ -242,13 +300,13 @@ sys_execve(struct proc *p, void *v, regi
>> syscallarg(char *const *) argp;
>> syscallarg(char *const *) envp;
>> } */ *uap = v;
>> + struct argcontext argctx;
>> int error;
>> struct exec_package pack;
>> struct nameidata nid;
>> struct vattr attr;
>> struct ucred *cred = p->p_ucred;
>> - char *argp;
>> - char * const *cpp, *dp, *sp;
>> + char * const *cpp;
>> #ifdef KTRACE
>> char *env_start;
>> #endif
>> @@ -261,7 +319,6 @@ sys_execve(struct proc *p, void *v, regi
>> char *stack;
>> struct ps_strings arginfo;
>> struct vmspace *vm = pr->ps_vmspace;
>> - char **tmpfap;
>> extern struct emul emul_native;
>> #if NSYSTRACE > 0
>> int wassugid = ISSET(pr->ps_flags, PS_SUGID | PS_SUGIDEXEC);
>> @@ -317,38 +374,23 @@ sys_execve(struct proc *p, void *v, regi
>> pack.ep_flags = 0;
>>
>> /* see if we can run it. */
>> - if ((error = check_exec(p, &pack)) != 0) {
>> + if ((error = check_exec(p, &pack)) != 0)
>> goto freehdr;
>> - }
>>
>> /* XXX -- THE FOLLOWING SECTION NEEDS MAJOR CLEANUP */
>> -
>> +
>> /* allocate an argument buffer */
>> - argp = km_alloc(NCARGS, &kv_exec, &kp_pageable, &kd_waitok);
>> + argctx.buffer = km_alloc(NCARGS, &kv_exec, &kp_pageable, &kd_waitok);
>> #ifdef DIAGNOSTIC
>> - if (argp == NULL)
>> - panic("execve: argp == NULL");
>> + if (argctx.buffer == NULL)
>> + panic("execve: argctx.buffer == NULL");
>> #endif
>> - dp = argp;
>> + argctx.bptr = argctx.buffer;
>> argc = 0;
>>
>> /* copy the fake args list, if there's one, freeing it as we go */
>> - if (pack.ep_flags & EXEC_HASARGL) {
>> - tmpfap = pack.ep_fa;
>> - while (*tmpfap != NULL) {
>> - char *cp;
>> -
>> - cp = *tmpfap;
>> - while (*cp)
>> - *dp++ = *cp++;
>> - *dp++ = '\0';
>> -
>> - free(*tmpfap, M_EXEC, 0);
>> - tmpfap++; argc++;
>> - }
>> - free(pack.ep_fa, M_EXEC, 0);
>> - pack.ep_flags &= ~EXEC_HASARGL;
>> - }
>> + if (pack.ep_flags & EXEC_HASARGL)
>> + copy_fake_args(&pack, &argctx, &argc);
>>
>> /* Now get argv & environment */
>> if (!(cpp = SCARG(uap, argp))) {
>> @@ -359,21 +401,9 @@ sys_execve(struct proc *p, void *v, regi
>> if (pack.ep_flags & EXEC_SKIPARG)
>> cpp++;
>>
>> - while (1) {
>> - len = argp + ARG_MAX - dp;
>> - if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
>> - goto bad;
>> - if (!sp)
>> - break;
>> - if ((error = copyinstr(sp, dp, len, &len)) != 0) {
>> - if (error == ENAMETOOLONG)
>> - error = E2BIG;
>> - goto bad;
>> - }
>> - dp += len;
>> - cpp++;
>> - argc++;
>> - }
>> + /* copy args */
>> + if (copy_strings(cpp, &argctx, &argc) != 0)
>> + goto bad;
>>
>> /* must have at least one argument */
>> if (argc == 0) {
>> @@ -382,39 +412,31 @@ sys_execve(struct proc *p, void *v, regi
>> }
>>
>> #ifdef KTRACE
>> - if (KTRPOINT(p, KTR_EXECARGS))
>> - ktrexec(p, KTR_EXECARGS, argp, dp - argp);
>> + if (KTRPOINT(p, KTR_EXECARGS)) {
>> + ktrexec(p, KTR_EXECARGS, argctx.buffer,
>> + argctx.bptr - argctx.buffer);
>> + }
>> #endif
>>
>> envc = 0;
>> /* environment does not need to be there */
>> if ((cpp = SCARG(uap, envp)) != NULL ) {
>> #ifdef KTRACE
>> - env_start = dp;
>> + env_start = argctx.bptr;
>> #endif
>> - while (1) {
>> - len = argp + ARG_MAX - dp;
>> - if ((error = copyin(cpp, &sp, sizeof(sp))) != 0)
>> - goto bad;
>> - if (!sp)
>> - break;
>> - if ((error = copyinstr(sp, dp, len, &len)) != 0) {
>> - if (error == ENAMETOOLONG)
>> - error = E2BIG;
>> - goto bad;
>> - }
>> - dp += len;
>> - cpp++;
>> - envc++;
>> - }
>> -
>> + if (copy_strings(cpp, &argctx, &envc) != 0)
>> + goto bad;
>> #ifdef KTRACE
>> - if (KTRPOINT(p, KTR_EXECENV))
>> - ktrexec(p, KTR_EXECENV, env_start, dp - env_start);
>> + if (KTRPOINT(p, KTR_EXECENV)) {
>> + ktrexec(p, KTR_EXECENV, env_start,
>> + argctx.bptr - env_start);
>> + }
>> #endif
>> }
>>
>> - dp = (char *)(((long)dp + _STACKALIGNBYTES) & ~_STACKALIGNBYTES);
>> + argctx.bptr =
>> + (char *)(((long)argctx.bptr + _STACKALIGNBYTES) &
>> + ~_STACKALIGNBYTES);
>>
>> sgap = STACKGAPLEN;
>>
>> @@ -430,7 +452,8 @@ sys_execve(struct proc *p, void *v, regi
>>
>> /* Now check if args & environ fit into new stack */
>> len = ((argc + envc + 2 + pack.ep_emul->e_arglen) * sizeof(char *) +
>> - sizeof(long) + dp + sgap + sizeof(struct ps_strings)) - argp;
>> + sizeof(long) + argctx.bptr + sgap + sizeof(struct ps_strings)) -
>> + argctx.buffer;
>>
>> len = (len + _STACKALIGNBYTES) &~ _STACKALIGNBYTES;
>>
>> @@ -505,7 +528,7 @@ sys_execve(struct proc *p, void *v, regi
>> stack = (char *)(vm->vm_minsaddr - len);
>> #endif
>> /* Now copy argc, args & environ to new stack */
>> - if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack, argp))
>> + if (!(*pack.ep_emul->e_copyargs)(&pack, &arginfo, stack,
>> argctx.buffer))
>> goto exec_abort;
>>
>> /* copy out the process's ps_strings structure */
>> @@ -672,7 +695,7 @@ sys_execve(struct proc *p, void *v, regi
>> timespecclear(&p->p_tu.tu_runtime);
>> p->p_tu.tu_uticks = p->p_tu.tu_sticks = p->p_tu.tu_iticks = 0;
>>
>> - km_free(argp, NCARGS, &kv_exec, &kp_pageable);
>> + km_free(argctx.buffer, NCARGS, &kv_exec, &kp_pageable);
>>
>> pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
>> vn_close(pack.ep_vp, FREAD, cred, p);
>> @@ -777,7 +800,7 @@ bad:
>> /* close and put the exec'd file */
>> vn_close(pack.ep_vp, FREAD, cred, p);
>> pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
>> - km_free(argp, NCARGS, &kv_exec, &kp_pageable);
>> + km_free(argctx.buffer, NCARGS, &kv_exec, &kp_pageable);
>>
>> freehdr:
>> free(pack.ep_hdr, M_EXEC, pack.ep_hdrlen);
>> @@ -806,7 +829,7 @@ exec_abort:
>> free(pack.ep_emul_arg, M_TEMP, pack.ep_emul_argsize);
>> pool_put(&namei_pool, nid.ni_cnd.cn_pnbuf);
>> vn_close(pack.ep_vp, FREAD, cred, p);
>> - km_free(argp, NCARGS, &kv_exec, &kp_pageable);
>> + km_free(argctx.buffer, NCARGS, &kv_exec, &kp_pageable);
>>
>> free_pack_abort:
>> free(pack.ep_hdr, M_EXEC, pack.ep_hdrlen);