Apply patch from Robert Elz in PR kern/10113. This fixes two problems
with procfs's cmdline - from the PR: The cmdline implementation in procfs is bogus. It's possible that part of the fix is a workaround of a UVM problem - that is, when (internally) accessing the top of the process VM (the end of the args) a request for I/0 of a PAGE_SIZE'd block starting at less than a PAGE_SIZE from the end of the mem space returns EINVAL rather than the data that is available. Whether this is a bug in UVM or not depends upon how it is defined to work, and I was unable to determine that. (Simon Burge found that problem, and provided the basis of the workaround/fix). Then, the cmdline function is unable to read more than one page of args, and a good thing too, as the way it is written attempting to get more than that would reference into lala land. And, on an attempt to read a lot of data when the above is fixed, most of the data won't be returned, only the final block of any read. Tested on alpha, pmax, i386 and sparc.
This commit is contained in:
parent
f26609f174
commit
0c59b3c325
@ -1,4 +1,4 @@
|
||||
/* $NetBSD: procfs_cmdline.c,v 1.6 1999/07/22 18:13:38 thorpej Exp $ */
|
||||
/* $NetBSD: procfs_cmdline.c,v 1.7 2000/05/16 13:45:25 simonb Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1999 Jaromir Dolecek <dolecek@ics.muni.cz>
|
||||
@ -62,8 +62,8 @@ procfs_docmdline(curp, p, pfs, uio)
|
||||
struct uio *uio;
|
||||
{
|
||||
struct ps_strings pss;
|
||||
int xlen, count, error, i;
|
||||
size_t len, upper_bound;
|
||||
int count, error, i;
|
||||
size_t len, xlen, upper_bound;
|
||||
struct uio auio;
|
||||
struct iovec aiov;
|
||||
vaddr_t argv;
|
||||
@ -85,7 +85,14 @@ procfs_docmdline(curp, p, pfs, uio)
|
||||
*/
|
||||
if (P_ZOMBIE(p) || (p->p_flag & P_SYSTEM) != 0) {
|
||||
len = snprintf(arg, PAGE_SIZE, "(%s)", p->p_comm);
|
||||
goto doio;
|
||||
xlen = len - uio->uio_offset;
|
||||
if (xlen <= 0)
|
||||
error = 0;
|
||||
else
|
||||
error = uiomove(arg, xlen, uio);
|
||||
|
||||
free(arg, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -142,14 +149,15 @@ procfs_docmdline(curp, p, pfs, uio)
|
||||
*/
|
||||
len = 0;
|
||||
count = pss.ps_nargvstr;
|
||||
upper_bound = round_page(uio->uio_offset + 1);
|
||||
for (; count && len < upper_bound; len += PAGE_SIZE) {
|
||||
upper_bound = round_page(uio->uio_offset + uio->uio_resid);
|
||||
for (; count && len < upper_bound; len += xlen) {
|
||||
aiov.iov_base = arg;
|
||||
aiov.iov_len = PAGE_SIZE;
|
||||
auio.uio_iov = &aiov;
|
||||
auio.uio_iovcnt = 1;
|
||||
auio.uio_offset = argv + len;
|
||||
auio.uio_resid = PAGE_SIZE;
|
||||
xlen = PAGE_SIZE - ((argv + len) & PAGE_MASK);
|
||||
auio.uio_resid = xlen;
|
||||
auio.uio_segflg = UIO_SYSSPACE;
|
||||
auio.uio_rw = UIO_READ;
|
||||
auio.uio_procp = NULL;
|
||||
@ -157,39 +165,30 @@ procfs_docmdline(curp, p, pfs, uio)
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
for (i = len; i < (len + PAGE_SIZE) && count != 0; i++) {
|
||||
for (i = 0; i < xlen && count != 0; i++) {
|
||||
if (arg[i] == '\0')
|
||||
count--; /* one full string */
|
||||
}
|
||||
|
||||
if (count == 0) {
|
||||
/* No more argv strings, set up len and break. */
|
||||
len = i;
|
||||
break;
|
||||
if (count == 0)
|
||||
i--; /* exclude the final NUL */
|
||||
|
||||
if (len + i > uio->uio_offset) {
|
||||
/* Have data in this page, copy it out */
|
||||
error = uiomove(arg + uio->uio_offset - len,
|
||||
i + len - uio->uio_offset, uio);
|
||||
if (error || uio->uio_resid <= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (len > 0)
|
||||
len--; /* exclude last NUL */
|
||||
|
||||
bad:
|
||||
/*
|
||||
* Release the process.
|
||||
*/
|
||||
PRELE(p);
|
||||
uvmspace_free(p->p_vmspace);
|
||||
|
||||
doio:
|
||||
xlen = len - uio->uio_offset;
|
||||
if (xlen <= 0)
|
||||
error = 0;
|
||||
else
|
||||
error = uiomove(arg + trunc_page(len), xlen, uio);
|
||||
|
||||
free(arg, M_TEMP);
|
||||
return (error);
|
||||
|
||||
bad:
|
||||
PRELE(p);
|
||||
uvmspace_free(p->p_vmspace);
|
||||
free(arg, M_TEMP);
|
||||
return (error);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user