mirror of
https://github.com/freebsd/freebsd-src.git
synced 2024-12-03 19:08:58 +00:00
When we are execing a setugid program, and we have a procfs filesystem
file open in one of the special file descriptors (0, 1, or 2), close it before completing the exec. Submitted by: nergal@idea.avet.com.pl Constructive comments: deraadt@openbsd.org, sef, peter, jkh
This commit is contained in:
parent
1a601bedea
commit
5e2664428c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=56313
@ -40,6 +40,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "opt_compat.h"
|
#include "opt_compat.h"
|
||||||
|
#include "opt_dontuse.h"
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/systm.h>
|
#include <sys/systm.h>
|
||||||
#include <sys/sysproto.h>
|
#include <sys/sysproto.h>
|
||||||
@ -936,6 +937,64 @@ fdfree(p)
|
|||||||
FREE(fdp, M_FILEDESC);
|
FREE(fdp, M_FILEDESC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* For setuid/setgid programs we don't want to people to use that setuidness
|
||||||
|
* to generate error messages which write to a file which otherwise would
|
||||||
|
* otherwise be off limits to the proces.
|
||||||
|
*
|
||||||
|
* This is a gross hack to plug the hole. A better solution would involve
|
||||||
|
* a special vop or other form of generalized access control mechanism. We
|
||||||
|
* go ahead and just reject all procfs file systems accesses as dangerous.
|
||||||
|
*
|
||||||
|
* Since setugidsafety calls this only for fd 0, 1 and 2, this check is
|
||||||
|
* sufficient. We also don't for setugidness since we know we are.
|
||||||
|
*/
|
||||||
|
static int
|
||||||
|
is_unsafe(struct file *fp)
|
||||||
|
{
|
||||||
|
#if PROCFS
|
||||||
|
if (fp->f_type == DTYPE_VNODE &&
|
||||||
|
((struct vnode *)(fp->f_data))->v_tag == VT_PROCFS)
|
||||||
|
return (1);
|
||||||
|
#endif
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Make this setguid thing safe, if at all possible.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
setugidsafety(p)
|
||||||
|
struct proc *p;
|
||||||
|
{
|
||||||
|
struct filedesc *fdp = p->p_fd;
|
||||||
|
struct file **fpp;
|
||||||
|
char *fdfp;
|
||||||
|
register int i;
|
||||||
|
|
||||||
|
/* Certain daemons might not have file descriptors. */
|
||||||
|
if (fdp == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
fpp = fdp->fd_ofiles;
|
||||||
|
fdfp = fdp->fd_ofileflags;
|
||||||
|
for (i = 0; i <= fdp->fd_lastfile; i++, fpp++, fdfp++) {
|
||||||
|
if (i > 2)
|
||||||
|
break;
|
||||||
|
if (*fpp != NULL && is_unsafe(*fpp)) {
|
||||||
|
if (*fdfp & UF_MAPPED)
|
||||||
|
(void) munmapfd(p, i);
|
||||||
|
(void) closef(*fpp, p);
|
||||||
|
*fpp = NULL;
|
||||||
|
*fdfp = 0;
|
||||||
|
if (i < fdp->fd_freefile)
|
||||||
|
fdp->fd_freefile = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (fdp->fd_lastfile > 0 && fdp->fd_ofiles[fdp->fd_lastfile] == NULL)
|
||||||
|
fdp->fd_lastfile--;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close any files on exec?
|
* Close any files on exec?
|
||||||
*/
|
*/
|
||||||
|
@ -289,6 +289,7 @@ interpret:
|
|||||||
if (attr.va_mode & VSGID)
|
if (attr.va_mode & VSGID)
|
||||||
p->p_ucred->cr_gid = attr.va_gid;
|
p->p_ucred->cr_gid = attr.va_gid;
|
||||||
setsugid(p);
|
setsugid(p);
|
||||||
|
setugidsafety(p);
|
||||||
} else {
|
} else {
|
||||||
if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
|
if (p->p_ucred->cr_uid == p->p_cred->p_ruid &&
|
||||||
p->p_ucred->cr_gid == p->p_cred->p_rgid)
|
p->p_ucred->cr_gid == p->p_cred->p_rgid)
|
||||||
|
@ -140,6 +140,7 @@ pid_t fgetown __P((struct sigio *));
|
|||||||
int fsetown __P((pid_t, struct sigio **));
|
int fsetown __P((pid_t, struct sigio **));
|
||||||
void funsetown __P((struct sigio *));
|
void funsetown __P((struct sigio *));
|
||||||
void funsetownlst __P((struct sigiolst *));
|
void funsetownlst __P((struct sigiolst *));
|
||||||
|
void setugidsafety __P((struct proc *p));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user