From 7a837e17bae84f4f09a0eb00eb02d2c1f67f7bdd Mon Sep 17 00:00:00 2001 From: Mikolaj Golub Date: Tue, 22 Nov 2011 20:45:11 +0000 Subject: [PATCH] Retire linprocfs_doargv(). Instead use new functions, proc_getargv() and proc_getenvv(), which were implemented using linprocfs_doargv() as a reference. Suggested by: kib Reviewed by: kib Approved by: des (linprocfs maintainer) MFC after: 2 weeks --- sys/compat/linprocfs/linprocfs.c | 160 +++---------------------------- 1 file changed, 14 insertions(+), 146 deletions(-) diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c index 8832d3d79370..12e7664fad38 100644 --- a/sys/compat/linprocfs/linprocfs.c +++ b/sys/compat/linprocfs/linprocfs.c @@ -919,150 +919,6 @@ linprocfs_doprocroot(PFS_FILL_ARGS) return (0); } -#define MAX_ARGV_STR 512 /* Max number of argv-like strings */ -#define UIO_CHUNK_SZ 256 /* Max chunk size (bytes) for uiomove */ - -static int -linprocfs_doargv(struct thread *td, struct proc *p, struct sbuf *sb, - void (*resolver)(const struct ps_strings, u_long *, int *)) -{ - struct iovec iov; - struct uio tmp_uio; - struct ps_strings pss; - int ret, i, n_elements, elm_len; - u_long addr, pbegin; - char **env_vector, *envp; - char env_string[UIO_CHUNK_SZ]; -#ifdef COMPAT_FREEBSD32 - struct freebsd32_ps_strings pss32; - uint32_t *env_vector32; -#endif - -#define UIO_HELPER(uio, iov, base, len, cnt, offset, sz, flg, rw, td) \ -do { \ - iov.iov_base = (caddr_t)(base); \ - iov.iov_len = (len); \ - uio.uio_iov = &(iov); \ - uio.uio_iovcnt = (cnt); \ - uio.uio_offset = (off_t)(offset); \ - uio.uio_resid = (sz); \ - uio.uio_segflg = (flg); \ - uio.uio_rw = (rw); \ - uio.uio_td = (td); \ -} while (0) - - env_vector = malloc(sizeof(char *) * MAX_ARGV_STR, M_TEMP, M_WAITOK); - -#ifdef COMPAT_FREEBSD32 - env_vector32 = NULL; - if (SV_PROC_FLAG(p, SV_ILP32) != 0) { - env_vector32 = malloc(sizeof(*env_vector32) * MAX_ARGV_STR, - M_TEMP, M_WAITOK); - elm_len = sizeof(int32_t); - envp = (char *)env_vector32; - - UIO_HELPER(tmp_uio, iov, &pss32, sizeof(pss32), 1, - (off_t)(p->p_sysent->sv_psstrings), - sizeof(pss32), UIO_SYSSPACE, UIO_READ, td); - ret = proc_rwmem(p, &tmp_uio); - if (ret != 0) - goto done; - pss.ps_argvstr = PTRIN(pss32.ps_argvstr); - pss.ps_nargvstr = pss32.ps_nargvstr; - pss.ps_envstr = PTRIN(pss32.ps_envstr); - pss.ps_nenvstr = pss32.ps_nenvstr; - } else { -#endif - elm_len = sizeof(char *); - envp = (char *)env_vector; - - UIO_HELPER(tmp_uio, iov, &pss, sizeof(pss), 1, - (off_t)(p->p_sysent->sv_psstrings), - sizeof(pss), UIO_SYSSPACE, UIO_READ, td); - ret = proc_rwmem(p, &tmp_uio); - if (ret != 0) - goto done; -#ifdef COMPAT_FREEBSD32 - } -#endif - - /* Get the array address and the number of elements */ - resolver(pss, &addr, &n_elements); - - /* Consistent with lib/libkvm/kvm_proc.c */ - if (n_elements > MAX_ARGV_STR) { - ret = E2BIG; - goto done; - } - - UIO_HELPER(tmp_uio, iov, envp, n_elements * elm_len, 1, - (vm_offset_t)(addr), iov.iov_len, UIO_SYSSPACE, UIO_READ, td); - ret = proc_rwmem(p, &tmp_uio); - if (ret != 0) - goto done; -#ifdef COMPAT_FREEBSD32 - if (env_vector32 != NULL) { - for (i = 0; i < n_elements; i++) - env_vector[i] = PTRIN(env_vector32[i]); - } -#endif - - /* Now we can iterate through the list of strings */ - for (i = 0; i < n_elements; i++) { - pbegin = (vm_offset_t)env_vector[i]; - for (;;) { - UIO_HELPER(tmp_uio, iov, env_string, sizeof(env_string), - 1, pbegin, iov.iov_len, UIO_SYSSPACE, UIO_READ, td); - ret = proc_rwmem(p, &tmp_uio); - if (ret != 0) - goto done; - - if (!strvalid(env_string, UIO_CHUNK_SZ)) { - /* - * We didn't find the end of the string. - * Add the string to the buffer and move - * the pointer. But do not allow strings - * of unlimited length. - */ - sbuf_bcat(sb, env_string, UIO_CHUNK_SZ); - if (sbuf_len(sb) >= ARG_MAX) { - ret = E2BIG; - goto done; - } - pbegin += UIO_CHUNK_SZ; - } else { - sbuf_cat(sb, env_string); - break; - } - } - sbuf_bcat(sb, "", 1); - } -#undef UIO_HELPER - -done: - free(env_vector, M_TEMP); -#ifdef COMPAT_FREEBSD32 - free(env_vector32, M_TEMP); -#endif - return (ret); -} - -static void -ps_string_argv(const struct ps_strings ps, u_long *addr, int *n) -{ - - *addr = (u_long) ps.ps_argvstr; - *n = ps.ps_nargvstr; -} - -static void -ps_string_env(const struct ps_strings ps, u_long *addr, int *n) -{ - - *addr = (u_long) ps.ps_envstr; - *n = ps.ps_nenvstr; -} - /* * Filler function for proc/pid/cmdline */ @@ -1090,9 +946,15 @@ linprocfs_doproccmdline(PFS_FILL_ARGS) PROC_UNLOCK(p); return (0); } + + if ((p->p_flag & P_SYSTEM) != 0) { + PROC_UNLOCK(p); + return (0); + } + PROC_UNLOCK(p); - ret = linprocfs_doargv(td, p, sb, ps_string_argv); + ret = proc_getargv(td, p, sb, ARG_MAX); return (ret); } @@ -1118,9 +980,15 @@ linprocfs_doprocenviron(PFS_FILL_ARGS) PROC_UNLOCK(p); return (0); } + + if ((p->p_flag & P_SYSTEM) != 0) { + PROC_UNLOCK(p); + return (0); + } + PROC_UNLOCK(p); - ret = linprocfs_doargv(td, p, sb, ps_string_env); + ret = proc_getenvv(td, p, sb, ARG_MAX); return (ret); }