Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/netbsd-1-4]: src/sys/kern Pull up revisions 1.38-1.39 (via patch, reques...
details: https://anonhg.NetBSD.org/src/rev/cb0279ac3f55
branches: netbsd-1-4
changeset: 470529:cb0279ac3f55
user: he <he%NetBSD.org@localhost>
date: Sun Apr 30 12:08:33 2000 +0000
description:
Pull up revisions 1.38-1.39 (via patch, requested by sommerfeld):
Fix two bugs:
o A malicious or erroneous program can hog the CPU in uiomove()
o A ktrace of such a program can hog large amounts of kernel memory
This increses the size of struct proc, so kernel-grovellers need
rebuild after this.
diffstat:
sys/kern/kern_ktrace.c | 188 +++++++++++++++++++++++++++---------------------
1 files changed, 105 insertions(+), 83 deletions(-)
diffs (truncated from 380 to 300 lines):
diff -r 5041384825a3 -r cb0279ac3f55 sys/kern/kern_ktrace.c
--- a/sys/kern/kern_ktrace.c Sun Apr 30 12:08:06 2000 +0000
+++ b/sys/kern/kern_ktrace.c Sun Apr 30 12:08:33 2000 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: kern_ktrace.c,v 1.33 1998/09/11 12:50:10 mycroft Exp $ */
+/* $NetBSD: kern_ktrace.c,v 1.33.6.1 2000/04/30 12:08:33 he Exp $ */
/*
* Copyright (c) 1989, 1993
@@ -53,11 +53,14 @@
#include <sys/mount.h>
#include <sys/syscallargs.h>
-struct ktr_header *ktrgetheader __P((int));
-int ktrops __P((struct proc *, struct proc *, int, int, void *));
-int ktrsetchildren __P((struct proc *, struct proc *, int, int, void *));
-void ktrwrite __P((struct proc *, void *, struct ktr_header *));
-int ktrcanset __P((struct proc *, struct proc *));
+#include <vm/vm.h> /* XXX for uvmexp, needed by PAGE_SIZE */
+#include <uvm/uvm.h> /* XXX for uvmexp, needed by PAGE_SIZE */
+
+void ktrinitheader __P((struct ktr_header *, struct proc *, int));
+int ktrops __P((struct proc *, struct proc *, int, int, void *));
+int ktrsetchildren __P((struct proc *, struct proc *, int, int, void *));
+int ktrwrite __P((struct proc *, void *, struct ktr_header *));
+int ktrcanset __P((struct proc *, struct proc *));
void
ktrderef(p)
@@ -94,20 +97,18 @@
}
}
-struct ktr_header *
-ktrgetheader(type)
+void
+ktrinitheader(kth, p, type)
+ struct ktr_header *kth;
+ struct proc *p;
int type;
{
- struct ktr_header *kth;
- struct proc *p = curproc; /* XXX */
- MALLOC(kth, struct ktr_header *, sizeof(struct ktr_header),
- M_TEMP, M_WAITOK);
+ memset(kth, 0, sizeof(*kth));
kth->ktr_type = type;
microtime(&kth->ktr_time);
kth->ktr_pid = p->p_pid;
memcpy(kth->ktr_comm, p->p_comm, MAXCOMLEN);
- return (kth);
}
void
@@ -117,26 +118,25 @@
size_t argsize;
register_t args[];
{
- struct ktr_header *kth;
- struct ktr_syscall *ktp;
+ struct ktr_header kth;
+ struct ktr_syscall *ktp;
struct proc *p = curproc; /* XXX */
register_t *argp;
- int len = sizeof(struct ktr_syscall) + argsize;
+ size_t len = sizeof(struct ktr_syscall) + argsize;
int i;
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_SYSCALL);
- MALLOC(ktp, struct ktr_syscall *, len, M_TEMP, M_WAITOK);
+ ktrinitheader(&kth, p, KTR_SYSCALL);
+ ktp = malloc(len, M_TEMP, M_WAITOK);
ktp->ktr_code = code;
ktp->ktr_argsize = argsize;
argp = (register_t *)((char *)ktp + sizeof(struct ktr_syscall));
for (i = 0; i < (argsize / sizeof(*argp)); i++)
*argp++ = args[i];
- kth->ktr_buf = (caddr_t)ktp;
- kth->ktr_len = len;
- ktrwrite(p, v, kth);
- FREE(ktp, M_TEMP);
- FREE(kth, M_TEMP);
+ kth.ktr_buf = (caddr_t)ktp;
+ kth.ktr_len = len;
+ (void) ktrwrite(p, v, &kth);
+ free(ktp, M_TEMP);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -147,21 +147,20 @@
int error;
register_t retval;
{
- struct ktr_header *kth;
+ struct ktr_header kth;
struct ktr_sysret ktp;
struct proc *p = curproc; /* XXX */
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_SYSRET);
+ ktrinitheader(&kth, p, KTR_SYSRET);
ktp.ktr_code = code;
ktp.ktr_error = error;
ktp.ktr_retval = retval; /* what about val2 ? */
- kth->ktr_buf = (caddr_t)&ktp;
- kth->ktr_len = sizeof(struct ktr_sysret);
+ kth.ktr_buf = (caddr_t)&ktp;
+ kth.ktr_len = sizeof(struct ktr_sysret);
- ktrwrite(p, v, kth);
- FREE(kth, M_TEMP);
+ (void) ktrwrite(p, v, &kth);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -170,16 +169,15 @@
void *v;
char *path;
{
- struct ktr_header *kth;
+ struct ktr_header kth;
struct proc *p = curproc; /* XXX */
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_NAMEI);
- kth->ktr_len = strlen(path);
- kth->ktr_buf = path;
+ ktrinitheader(&kth, p, KTR_NAMEI);
+ kth.ktr_len = strlen(path);
+ kth.ktr_buf = path;
- ktrwrite(p, v, kth);
- FREE(kth, M_TEMP);
+ (void) ktrwrite(p, v, &kth);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -189,15 +187,14 @@
struct proc *p;
char *emul;
{
- struct ktr_header *kth;
+ struct ktr_header kth;
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_EMUL);
- kth->ktr_len = strlen(emul);
- kth->ktr_buf = emul;
+ ktrinitheader(&kth, p, KTR_EMUL);
+ kth.ktr_len = strlen(emul);
+ kth.ktr_buf = emul;
- ktrwrite(p, v, kth);
- FREE(kth, M_TEMP);
+ (void) ktrwrite(p, v, &kth);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -209,37 +206,55 @@
struct iovec *iov;
int len, error;
{
- struct ktr_header *kth;
+ struct ktr_header kth;
struct ktr_genio *ktp;
caddr_t cp;
int resid = len, cnt;
struct proc *p = curproc; /* XXX */
-
+ int buflen;
+
if (error)
return;
+
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_GENIO);
- MALLOC(ktp, struct ktr_genio *, sizeof(struct ktr_genio) + len,
- M_TEMP, M_WAITOK);
+
+ buflen = min(PAGE_SIZE, len + sizeof(struct ktr_genio));
+
+ ktrinitheader(&kth, p, KTR_GENIO);
+ ktp = malloc(buflen, M_TEMP, M_WAITOK);
ktp->ktr_fd = fd;
ktp->ktr_rw = rw;
+
+ kth.ktr_buf = (caddr_t)ktp;
+
cp = (caddr_t)((char *)ktp + sizeof(struct ktr_genio));
+ buflen -= sizeof(struct ktr_genio);
+
while (resid > 0) {
- if ((cnt = iov->iov_len) > resid)
+ if (p->p_schedflags & PSCHED_SHOULDYIELD)
+ preempt(NULL);
+
+ cnt = min(iov->iov_len, buflen);
+ if (cnt > resid)
cnt = resid;
- if (copyin(iov->iov_base, cp, (unsigned)cnt))
- goto done;
- cp += cnt;
+ if (copyin(iov->iov_base, cp, cnt))
+ break;
+
+ kth.ktr_len = cnt + sizeof(struct ktr_genio);
+
+ if (ktrwrite(p, v, &kth) != 0)
+ break;
+
+ iov->iov_base = (caddr_t)iov->iov_base + cnt;
+ iov->iov_len -= cnt;
+
+ if (iov->iov_len == 0)
+ iov++;
+
resid -= cnt;
- iov++;
}
- kth->ktr_buf = (caddr_t)ktp;
- kth->ktr_len = sizeof(struct ktr_genio) + len;
- ktrwrite(p, v, kth);
-done:
- FREE(kth, M_TEMP);
- FREE(ktp, M_TEMP);
+ free(ktp, M_TEMP);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -251,21 +266,20 @@
sigset_t *mask;
int code;
{
- struct ktr_header *kth;
+ struct ktr_header kth;
struct ktr_psig kp;
struct proc *p = curproc; /* XXX */
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_PSIG);
+ ktrinitheader(&kth, p, KTR_PSIG);
kp.signo = (char)sig;
kp.action = action;
kp.mask = *mask;
kp.code = code;
- kth->ktr_buf = (caddr_t)&kp;
- kth->ktr_len = sizeof(struct ktr_psig);
+ kth.ktr_buf = (caddr_t)&kp;
+ kth.ktr_len = sizeof(struct ktr_psig);
- ktrwrite(p, v, kth);
- FREE(kth, M_TEMP);
+ (void) ktrwrite(p, v, &kth);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -274,19 +288,18 @@
void *v;
int out, user;
{
- struct ktr_header *kth;
- struct ktr_csw kc;
+ struct ktr_header kth;
+ struct ktr_csw kc;
struct proc *p = curproc; /* XXX */
p->p_traceflag |= KTRFAC_ACTIVE;
- kth = ktrgetheader(KTR_CSW);
+ ktrinitheader(&kth, p, KTR_CSW);
kc.out = out;
kc.user = user;
- kth->ktr_buf = (caddr_t)&kc;
- kth->ktr_len = sizeof(struct ktr_csw);
+ kth.ktr_buf = (caddr_t)&kc;
+ kth.ktr_len = sizeof(struct ktr_csw);
- ktrwrite(p, v, kth);
- FREE(kth, M_TEMP);
+ (void) ktrwrite(p, v, &kth);
p->p_traceflag &= ~KTRFAC_ACTIVE;
}
@@ -361,11 +374,13 @@
error = ESRCH;
goto done;
}
- for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next)
+ for (p = LIST_FIRST(&pg->pg_members); p != NULL;
+ p = LIST_NEXT(p, p_pglist)) {
if (descend)
ret |= ktrsetchildren(curp, p, ops, facs, fp);
else
ret |= ktrops(curp, p, ops, facs, fp);
+ }
} else {
Home |
Main Index |
Thread Index |
Old Index