doc/share/security/patches/SA-03:17/procfs51.patch
Bjoern A. Zeeb 3571e53040 Import FreeBSD Security Advisories and Errata Notices, as well as their
patches for easier mirroring, to eliminate a special copy, to make
www.freebsd.org/security a full copy of security.freebsd.org and be
eventually be the same.

For now files are just sitting there.   The symlinks are missing.

Discussed on:	www (repository location)
Discussed with:	simon (so)
2012-08-15 06:19:40 +00:00

374 lines
9.4 KiB
Diff

Index: sys/fs/procfs/procfs_dbregs.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_dbregs.c,v
retrieving revision 1.22
diff -p -c -r1.22 procfs_dbregs.c
*** sys/fs/procfs/procfs_dbregs.c 5 May 2003 15:12:51 -0000 1.22
--- sys/fs/procfs/procfs_dbregs.c 3 Oct 2003 12:52:17 -0000
*************** procfs_doprocdbregs(PFS_FILL_ARGS)
*** 65,95 ****
{
int error;
struct dbreg r;
- char *kv;
- int kl;
PROC_LOCK(p);
if (p_candebug(td, p) != 0) {
PROC_UNLOCK(p);
return (EPERM);
}
- kl = sizeof(r);
- kv = (char *) &r;
-
- kv += uio->uio_offset;
- kl -= uio->uio_offset;
- if (kl > uio->uio_resid)
- kl = uio->uio_resid;
_PHOLD(p);
! if (kl < 0)
! error = EINVAL;
! else
! /* XXXKSE: */
! error = proc_read_dbregs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove(kv, kl, uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
--- 65,83 ----
{
int error;
struct dbreg r;
PROC_LOCK(p);
if (p_candebug(td, p) != 0) {
PROC_UNLOCK(p);
return (EPERM);
}
_PHOLD(p);
! /* XXXKSE: */
! error = proc_read_dbregs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove_frombuf(&r, sizeof(r), uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
Index: sys/fs/procfs/procfs_fpregs.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_fpregs.c,v
retrieving revision 1.28
diff -p -c -r1.28 procfs_fpregs.c
*** sys/fs/procfs/procfs_fpregs.c 5 May 2003 15:12:51 -0000 1.28
--- sys/fs/procfs/procfs_fpregs.c 3 Oct 2003 12:52:18 -0000
*************** procfs_doprocfpregs(PFS_FILL_ARGS)
*** 59,89 ****
{
int error;
struct fpreg r;
- char *kv;
- int kl;
PROC_LOCK(p);
if (p_candebug(td, p)) {
PROC_UNLOCK(p);
return (EPERM);
}
- kl = sizeof(r);
- kv = (char *) &r;
-
- kv += uio->uio_offset;
- kl -= uio->uio_offset;
- if (kl > uio->uio_resid)
- kl = uio->uio_resid;
_PHOLD(p);
! if (kl < 0)
! error = EINVAL;
! else
! /* XXXKSE: */
! error = proc_read_fpregs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove(kv, kl, uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
--- 59,77 ----
{
int error;
struct fpreg r;
PROC_LOCK(p);
if (p_candebug(td, p)) {
PROC_UNLOCK(p);
return (EPERM);
}
_PHOLD(p);
! /* XXXKSE: */
! error = proc_read_fpregs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove_frombuf(&r, sizeof(r), uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
Index: sys/fs/procfs/procfs_regs.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/procfs/procfs_regs.c,v
retrieving revision 1.27
diff -p -c -r1.27 procfs_regs.c
*** sys/fs/procfs/procfs_regs.c 5 May 2003 15:12:51 -0000 1.27
--- sys/fs/procfs/procfs_regs.c 3 Oct 2003 12:52:18 -0000
*************** procfs_doprocregs(PFS_FILL_ARGS)
*** 59,89 ****
{
int error;
struct reg r;
- char *kv;
- int kl;
PROC_LOCK(p);
if (p_candebug(td, p)) {
PROC_UNLOCK(p);
return (EPERM);
}
- kl = sizeof(r);
- kv = (char *) &r;
-
- kv += uio->uio_offset;
- kl -= uio->uio_offset;
- if (kl > uio->uio_resid)
- kl = uio->uio_resid;
_PHOLD(p);
! if (kl < 0)
! error = EINVAL;
! else
! /* XXXKSE: */
! error = proc_read_regs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove(kv, kl, uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
--- 59,77 ----
{
int error;
struct reg r;
PROC_LOCK(p);
if (p_candebug(td, p)) {
PROC_UNLOCK(p);
return (EPERM);
}
_PHOLD(p);
! /* XXXKSE: */
! error = proc_read_regs(FIRST_THREAD_IN_PROC(p), &r);
if (error == 0) {
PROC_UNLOCK(p);
! error = uiomove_frombuf(&r, sizeof(r), uio);
PROC_LOCK(p);
}
if (error == 0 && uio->uio_rw == UIO_WRITE) {
Index: sys/fs/pseudofs/pseudofs_vnops.c
===================================================================
RCS file: /home/ncvs/src/sys/fs/pseudofs/pseudofs_vnops.c,v
retrieving revision 1.35
diff -p -c -r1.35 pseudofs_vnops.c
*** sys/fs/pseudofs/pseudofs_vnops.c 2 Mar 2003 22:23:45 -0000 1.35
--- sys/fs/pseudofs/pseudofs_vnops.c 3 Oct 2003 12:52:18 -0000
***************
*** 34,39 ****
--- 34,40 ----
#include <sys/ctype.h>
#include <sys/dirent.h>
#include <sys/fcntl.h>
+ #include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mount.h>
#include <sys/mutex.h>
*************** pfs_read(struct vop_read_args *va)
*** 472,479 ****
struct uio *uio = va->a_uio;
struct proc *proc = NULL;
struct sbuf *sb = NULL;
! char *ps;
! int error, xlen;
PFS_TRACE((pn->pn_name));
--- 473,480 ----
struct uio *uio = va->a_uio;
struct proc *proc = NULL;
struct sbuf *sb = NULL;
! int error;
! unsigned int buflen, offset, resid;
PFS_TRACE((pn->pn_name));
*************** pfs_read(struct vop_read_args *va)
*** 508,514 ****
PFS_RETURN (error);
}
! sb = sbuf_new(sb, NULL, uio->uio_offset + uio->uio_resid, 0);
if (sb == NULL) {
if (proc != NULL)
PRELE(proc);
--- 509,524 ----
PFS_RETURN (error);
}
! /* Beaucoup sanity checks so we don't ask for bogus allocation. */
! if (uio->uio_offset < 0 || uio->uio_resid < 0 ||
! (offset = uio->uio_offset) != uio->uio_offset ||
! (resid = uio->uio_resid) != uio->uio_resid ||
! (buflen = offset + resid) < offset || buflen > INT_MAX) {
! if (proc != NULL)
! PRELE(proc);
! PFS_RETURN (EINVAL);
! }
! sb = sbuf_new(sb, NULL, buflen, 0);
if (sb == NULL) {
if (proc != NULL)
PRELE(proc);
*************** pfs_read(struct vop_read_args *va)
*** 525,536 ****
PFS_RETURN (error);
}
- /* XXX we should possibly detect and handle overflows */
sbuf_finish(sb);
! ps = sbuf_data(sb) + uio->uio_offset;
! xlen = sbuf_len(sb) - uio->uio_offset;
! xlen = imin(xlen, uio->uio_resid);
! error = (xlen <= 0 ? 0 : uiomove(ps, xlen, uio));
sbuf_delete(sb);
PFS_RETURN (error);
}
--- 535,542 ----
PFS_RETURN (error);
}
sbuf_finish(sb);
! error = uiomove_frombuf(sbuf_data(sb), sbuf_len(sb), uio);
sbuf_delete(sb);
PFS_RETURN (error);
}
*************** pfs_readlink(struct vop_readlink_args *v
*** 676,684 ****
struct pfs_node *pn = pvd->pvd_pn;
struct uio *uio = va->a_uio;
struct proc *proc = NULL;
! char buf[MAXPATHLEN], *ps;
struct sbuf sb;
! int error, xlen;
PFS_TRACE((pn->pn_name));
--- 682,690 ----
struct pfs_node *pn = pvd->pvd_pn;
struct uio *uio = va->a_uio;
struct proc *proc = NULL;
! char buf[MAXPATHLEN];
struct sbuf sb;
! int error;
PFS_TRACE((pn->pn_name));
*************** pfs_readlink(struct vop_readlink_args *v
*** 708,719 ****
PFS_RETURN (error);
}
- /* XXX we should detect and handle overflows */
sbuf_finish(&sb);
! ps = sbuf_data(&sb) + uio->uio_offset;
! xlen = sbuf_len(&sb) - uio->uio_offset;
! xlen = imin(xlen, uio->uio_resid);
! error = (xlen <= 0 ? 0 : uiomove(ps, xlen, uio));
sbuf_delete(&sb);
PFS_RETURN (error);
}
--- 714,721 ----
PFS_RETURN (error);
}
sbuf_finish(&sb);
! error = uiomove_frombuf(sbuf_data(&sb), sbuf_len(&sb), uio);
sbuf_delete(&sb);
PFS_RETURN (error);
}
Index: sys/kern/kern_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/kern/kern_subr.c,v
retrieving revision 1.74
diff -p -c -r1.74 kern_subr.c
*** sys/kern/kern_subr.c 5 May 2003 21:27:29 -0000 1.74
--- sys/kern/kern_subr.c 3 Oct 2003 12:52:18 -0000
***************
*** 45,50 ****
--- 45,51 ----
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/ktr.h>
+ #include <sys/limits.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/proc.h>
*************** out:
*** 191,196 ****
--- 192,219 ----
mtx_unlock_spin(&sched_lock);
}
return (error);
+ }
+
+ /*
+ * Wrapper for uiomove() that validates the arguments against a known-good
+ * kernel buffer. Currently, uiomove accepts a signed (n) argument, which
+ * is almost definitely a bad thing, so we catch that here as well. We
+ * return a runtime failure, but it might be desirable to generate a runtime
+ * assertion failure instead.
+ */
+ int
+ uiomove_frombuf(void *buf, int buflen, struct uio *uio)
+ {
+ unsigned int offset, n;
+
+ if (uio->uio_offset < 0 || uio->uio_resid < 0 ||
+ (offset = uio->uio_offset) != uio->uio_offset)
+ return (EINVAL);
+ if (buflen <= 0 || offset >= buflen)
+ return (0);
+ if ((n = buflen - offset) > INT_MAX)
+ return (EINVAL);
+ return (uiomove((char *)buf + offset, n, uio));
}
#ifdef ZERO_COPY_SOCKETS
Index: sys/sys/uio.h
===================================================================
RCS file: /home/ncvs/src/sys/sys/uio.h,v
retrieving revision 1.27
diff -p -c -r1.27 uio.h
*** sys/sys/uio.h 6 Mar 2003 03:41:01 -0000 1.27
--- sys/sys/uio.h 3 Oct 2003 12:52:18 -0000
*************** struct vm_object;
*** 87,92 ****
--- 87,93 ----
void uio_yield(void);
int uiomove(void *, int, struct uio *);
+ int uiomove_frombuf(void *buf, int buflen, struct uio *uio);
int uiomoveco(void *, int, struct uio *, struct vm_object *, int);
int copyinfrom(const void *src, void *dst, size_t len, int seg);
int copyinstrfrom(const void *src, void *dst, size_t len,