Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/miscfs/procfs Apply patch from Robert Elz in PR kern/101...
details: https://anonhg.NetBSD.org/src/rev/42e13c3a0afc
branches: trunk
changeset: 486235:42e13c3a0afc
user: simonb <simonb%NetBSD.org@localhost>
date: Tue May 16 13:45:25 2000 +0000
description:
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.
diffstat:
sys/miscfs/procfs/procfs_cmdline.c | 53 ++++++++++++++++++-------------------
1 files changed, 26 insertions(+), 27 deletions(-)
diffs (106 lines):
diff -r ab787a0be11c -r 42e13c3a0afc sys/miscfs/procfs/procfs_cmdline.c
--- a/sys/miscfs/procfs/procfs_cmdline.c Tue May 16 11:27:37 2000 +0000
+++ b/sys/miscfs/procfs/procfs_cmdline.c Tue May 16 13:45:25 2000 +0000
@@ -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@localhost>
@@ -62,8 +62,8 @@
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 @@
*/
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 @@
*/
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 @@
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);
}
Home |
Main Index |
Thread Index |
Old Index