summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortrociny <trociny@FreeBSD.org>2012-01-15 18:47:24 +0000
committertrociny <trociny@FreeBSD.org>2012-01-15 18:47:24 +0000
commitd4e71152bd70ed6531fa416c2cb7a63d7fa160d7 (patch)
treec6208ceb07555117d0288575ddab2dc2d79446cd
parent4371f8aebb7e829b24e1c2298abd87259f35148d (diff)
downloadFreeBSD-src-d4e71152bd70ed6531fa416c2cb7a63d7fa160d7.zip
FreeBSD-src-d4e71152bd70ed6531fa416c2cb7a63d7fa160d7.tar.gz
Abrogate nchr argument in proc_getargv() and proc_getenvv(): we always want
to read strings completely to know the actual size. As a side effect it fixes the issue with kern.proc.args and kern.proc.env sysctls, which didn't return the size of available data when calling sysctl(3) with the NULL argument for oldp. Note, in get_ps_strings(), which does actual work for proc_getargv() and proc_getenvv(), we still have a safety limit on the size of data read in case of a corrupted procces stack. Suggested by: kib MFC after: 3 days
-rw-r--r--sys/compat/linprocfs/linprocfs.c4
-rw-r--r--sys/fs/procfs/procfs_status.c2
-rw-r--r--sys/kern/kern_proc.c25
-rw-r--r--sys/sys/proc.h6
4 files changed, 17 insertions, 20 deletions
diff --git a/sys/compat/linprocfs/linprocfs.c b/sys/compat/linprocfs/linprocfs.c
index 2549ecc..8129fe8 100644
--- a/sys/compat/linprocfs/linprocfs.c
+++ b/sys/compat/linprocfs/linprocfs.c
@@ -954,7 +954,7 @@ linprocfs_doproccmdline(PFS_FILL_ARGS)
PROC_UNLOCK(p);
- ret = proc_getargv(td, p, sb, ARG_MAX);
+ ret = proc_getargv(td, p, sb);
return (ret);
}
@@ -988,7 +988,7 @@ linprocfs_doprocenviron(PFS_FILL_ARGS)
PROC_UNLOCK(p);
- ret = proc_getenvv(td, p, sb, ARG_MAX);
+ ret = proc_getenvv(td, p, sb);
return (ret);
}
diff --git a/sys/fs/procfs/procfs_status.c b/sys/fs/procfs/procfs_status.c
index d981e5e..a97e0a9 100644
--- a/sys/fs/procfs/procfs_status.c
+++ b/sys/fs/procfs/procfs_status.c
@@ -193,5 +193,5 @@ procfs_doproccmdline(PFS_FILL_ARGS)
PROC_UNLOCK(p);
- return (proc_getargv(td, p, sb, ARG_MAX));
+ return (proc_getargv(td, p, sb));
}
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index bd83b59..38bc438 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -1631,20 +1631,19 @@ get_proc_vector(struct thread *td, struct proc *p, char ***proc_vectorp,
static int
get_ps_strings(struct thread *td, struct proc *p, struct sbuf *sb,
- enum proc_vector_type type, size_t nchr)
+ enum proc_vector_type type)
{
- size_t done, len, vsize;
+ size_t done, len, nchr, vsize;
int error, i;
char **proc_vector, *sptr;
char pss_string[GET_PS_STRINGS_CHUNK_SZ];
PROC_ASSERT_HELD(p);
- /*
- * We are not going to read more than 2 * (PATH_MAX + ARG_MAX) bytes.
- */
- if (nchr > 2 * (PATH_MAX + ARG_MAX))
- nchr = 2 * (PATH_MAX + ARG_MAX);
+ /*
+ * We are not going to read more than 2 * (PATH_MAX + ARG_MAX) bytes.
+ */
+ nchr = 2 * (PATH_MAX + ARG_MAX);
error = get_proc_vector(td, p, &proc_vector, &vsize, type);
if (error != 0)
@@ -1679,17 +1678,17 @@ done:
}
int
-proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb, size_t nchr)
+proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb)
{
- return (get_ps_strings(curthread, p, sb, PROC_ARG, nchr));
+ return (get_ps_strings(curthread, p, sb, PROC_ARG));
}
int
-proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb, size_t nchr)
+proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb)
{
- return (get_ps_strings(curthread, p, sb, PROC_ENV, nchr));
+ return (get_ps_strings(curthread, p, sb, PROC_ENV));
}
/*
@@ -1728,7 +1727,7 @@ sysctl_kern_proc_args(SYSCTL_HANDLER_ARGS)
_PHOLD(p);
PROC_UNLOCK(p);
sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req);
- error = proc_getargv(curthread, p, &sb, req->oldlen);
+ error = proc_getargv(curthread, p, &sb);
error2 = sbuf_finish(&sb);
PRELE(p);
sbuf_delete(&sb);
@@ -1780,7 +1779,7 @@ sysctl_kern_proc_env(SYSCTL_HANDLER_ARGS)
}
sbuf_new_for_sysctl(&sb, NULL, GET_PS_STRINGS_CHUNK_SZ, req);
- error = proc_getenvv(curthread, p, &sb, req->oldlen);
+ error = proc_getenvv(curthread, p, &sb);
error2 = sbuf_finish(&sb);
PRELE(p);
sbuf_delete(&sb);
diff --git a/sys/sys/proc.h b/sys/sys/proc.h
index a0d942c..ba00a88 100644
--- a/sys/sys/proc.h
+++ b/sys/sys/proc.h
@@ -859,10 +859,8 @@ int p_canwait(struct thread *td, struct proc *p);
struct pargs *pargs_alloc(int len);
void pargs_drop(struct pargs *pa);
void pargs_hold(struct pargs *pa);
-int proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb,
- size_t nchr);
-int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb,
- size_t nchr);
+int proc_getargv(struct thread *td, struct proc *p, struct sbuf *sb);
+int proc_getenvv(struct thread *td, struct proc *p, struct sbuf *sb);
void procinit(void);
void proc_linkup0(struct proc *p, struct thread *td);
void proc_linkup(struct proc *p, struct thread *td);
OpenPOWER on IntegriCloud