doc/share/security/patches/SA-02:23/stdio.patch.v1.2
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

109 lines
3.6 KiB
Groff

--- sys/kern/kern_descrip.c Fri Dec 14 13:26:24 2001
+++ sys/kern/kern_descrip.c Mon Apr 22 16:38:20 2002
@@ -50,6 +50,7 @@
#include <sys/sysctl.h>
#include <sys/vnode.h>
#include <sys/proc.h>
+#include <sys/namei.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/filio.h>
@@ -1183,6 +1184,63 @@
}
while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
fdp->fd_lastfile--;
+}
+
+/*
+ * It is unsafe for set[ug]id processes to be started with file
+ * descriptors 0..2 closed, as these descriptors are given implicit
+ * significance in the Standard C library. fdcheckstd() will create a
+ * descriptor referencing /dev/null for each of stdin, stdout, and
+ * stderr that is not already open.
+ */
+int
+fdcheckstd(p)
+ struct proc *p;
+{
+ struct nameidata nd;
+ struct filedesc *fdp;
+ struct file *fp;
+ register_t retval;
+ int fd, i, error, flags, devnull;
+
+ fdp = p->p_fd;
+ if (fdp == NULL)
+ return (0);
+ devnull = -1;
+ error = 0;
+ for (i = 0; i < 3; i++) {
+ if (fdp->fd_ofiles[i] != NULL)
+ continue;
+ if (devnull < 0) {
+ error = falloc(p, &fp, &fd);
+ if (error != 0)
+ break;
+ NDINIT(&nd, LOOKUP, FOLLOW, UIO_SYSSPACE, "/dev/null",
+ p);
+ flags = FREAD | FWRITE;
+ error = vn_open(&nd, flags, 0);
+ if (error != 0) {
+ fdp->fd_ofiles[i] = NULL;
+ fdrop(fp, p);
+ break;
+ }
+ NDFREE(&nd, NDF_ONLY_PNBUF);
+ fp->f_data = (caddr_t)nd.ni_vp;
+ fp->f_flag = flags;
+ fp->f_ops = &vnops;
+ fp->f_type = DTYPE_VNODE;
+ VOP_UNLOCK(nd.ni_vp, 0, p);
+ devnull = fd;
+ } else {
+ error = fdalloc(p, 0, &fd);
+ if (error != 0)
+ break;
+ error = do_dup(fdp, devnull, fd, &retval, p);
+ if (error != 0)
+ break;
+ }
+ }
+ return (error);
}
/*
diff --exclude=CVS -ruN sys/kern/kern_exec.c sys/kern/kern_exec.c
--- sys/kern/kern_exec.c Tue Jan 22 11:22:59 2002
+++ sys/kern/kern_exec.c Mon Jul 29 22:21:49 2002
@@ -328,6 +328,12 @@
vrele(vtmp);
}
}
+ /* Close any file descriptors 0..2 that reference procfs */
+ setugidsafety(p);
+ /* Make sure file descriptors 0..2 are in use. */
+ error = fdcheckstd(p);
+ if (error != 0)
+ goto exec_fail_dealloc;
/*
* Set the new credentials.
*/
@@ -336,7 +342,6 @@
change_euid(p, attr.va_uid);
if (attr.va_mode & VSGID)
p->p_ucred->cr_gid = attr.va_gid;
- setugidsafety(p);
} else {
if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
p->p_ucred->cr_gid == p->p_cred->p_rgid)
diff --exclude=CVS -ruN sys/sys/filedesc.h sys/sys/filedesc.h
--- sys/sys/filedesc.h Sat Nov 25 20:30:08 2000
+++ sys/sys/filedesc.h Sun Apr 21 08:08:57 2002
@@ -142,6 +142,7 @@
void fdfree __P((struct proc *p));
int closef __P((struct file *fp,struct proc *p));
void fdcloseexec __P((struct proc *p));
+int fdcheckstd __P((struct proc *p));
struct file *holdfp __P((struct filedesc* fdp, int fd, int flag));
int getvnode __P((struct filedesc *fdp, int fd, struct file **fpp));
int fdissequential __P((struct file *));