Page MenuHomeFreeBSD

D30130.id88696.diff
No OneTemporary

D30130.id88696.diff

Index: sys/kern/kern_exec.c
===================================================================
--- sys/kern/kern_exec.c
+++ sys/kern/kern_exec.c
@@ -354,6 +354,17 @@
return (do_execve(td, args, mac_p, oldvmspace));
}
+static void
+execve_nosetid(struct image_params *imgp)
+{
+
+ imgp->credential_setid = false;
+ if (imgp->newcred != NULL) {
+ crfree(imgp->newcred);
+ imgp->newcred = NULL;
+ }
+}
+
/*
* In-kernel implementation of execve(). All arguments are assumed to be
* userspace pointers from the passed thread.
@@ -640,7 +651,7 @@
vput(newtextvp);
vm_object_deallocate(imgp->object);
imgp->object = NULL;
- imgp->credential_setid = false;
+ execve_nosetid(imgp);
if (imgp->newcred != NULL) {
crfree(imgp->newcred);
imgp->newcred = NULL;
@@ -769,6 +780,9 @@
signotify(td);
}
+ if (p->p_flag2 & P2_NO_NEW_PRIVS)
+ execve_nosetid(imgp);
+
/*
* Implement image setuid/setgid installation.
*/
Index: sys/kern/kern_fork.c
===================================================================
--- sys/kern/kern_fork.c
+++ sys/kern/kern_fork.c
@@ -487,7 +487,7 @@
p2->p_flag2 = p1->p_flag2 & (P2_ASLR_DISABLE | P2_ASLR_ENABLE |
P2_ASLR_IGNSTART | P2_NOTRACE | P2_NOTRACE_EXEC |
P2_PROTMAX_ENABLE | P2_PROTMAX_DISABLE | P2_TRAPCAP |
- P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC);
+ P2_STKGAP_DISABLE | P2_STKGAP_DISABLE_EXEC | P2_NO_NEW_PRIVS);
p2->p_swtick = ticks;
if (p1->p_flag & P_PROFIL)
startprofclock(p2);
Index: sys/kern/kern_procctl.c
===================================================================
--- sys/kern/kern_procctl.c
+++ sys/kern/kern_procctl.c
@@ -419,6 +419,14 @@
return (0);
}
+static int
+no_new_privs(struct thread *td, struct proc *p)
+{
+
+ p->p_flag2 |= P2_NO_NEW_PRIVS;
+ return (0);
+}
+
static int
protmax_ctl(struct thread *td, struct proc *p, int state)
{
@@ -607,6 +615,7 @@
break;
case PROC_REAP_ACQUIRE:
case PROC_REAP_RELEASE:
+ case PROC_NO_NEW_PRIVS:
if (uap->data != NULL)
return (EINVAL);
data = NULL;
@@ -710,6 +719,8 @@
return (trapcap_ctl(td, p, *(int *)data));
case PROC_TRAPCAP_STATUS:
return (trapcap_status(td, p, data));
+ case PROC_NO_NEW_PRIVS:
+ return (no_new_privs(td, p));
default:
return (EINVAL);
}
@@ -788,6 +799,7 @@
case PROC_STACKGAP_STATUS:
case PROC_TRACE_STATUS:
case PROC_TRAPCAP_STATUS:
+ case PROC_NO_NEW_PRIVS:
tree_locked = false;
break;
default:
Index: sys/kern/vfs_syscalls.c
===================================================================
--- sys/kern/vfs_syscalls.c
+++ sys/kern/vfs_syscalls.c
@@ -956,6 +956,10 @@
return (0);
}
+static int unprivileged_chroot = 0;
+SYSCTL_INT(_security_bsd, OID_AUTO, unprivileged_chroot, CTLFLAG_RW,
+ &unprivileged_chroot, 0,
+ "Unprivileged processes can use chroot(2)");
/*
* Change notion of root (``/'') directory.
*/
@@ -968,11 +972,20 @@
sys_chroot(struct thread *td, struct chroot_args *uap)
{
struct nameidata nd;
+ struct proc *p;
int error;
error = priv_check(td, PRIV_VFS_CHROOT);
- if (error != 0)
- return (error);
+ if (error != 0) {
+ p = td->td_proc;
+ PROC_LOCK(p);
+ if (unprivileged_chroot == 0 ||
+ (p->p_flag2 & P2_NO_NEW_PRIVS) == 0) {
+ PROC_UNLOCK(p);
+ return (error);
+ }
+ PROC_UNLOCK(p);
+ }
NDINIT(&nd, LOOKUP, FOLLOW | LOCKSHARED | LOCKLEAF | AUDITVNODE1,
UIO_USERSPACE, uap->path, td);
error = namei(&nd);
Index: sys/sys/proc.h
===================================================================
--- sys/sys/proc.h
+++ sys/sys/proc.h
@@ -833,6 +833,7 @@
after exec */
#define P2_ITSTOPPED 0x00002000
#define P2_PTRACEREQ 0x00004000 /* Active ptrace req */
+#define P2_NO_NEW_PRIVS 0x00008000 /* Ignore setuid */
/* Flags protected by proctree_lock, kept in p_treeflags. */
#define P_TREE_ORPHANED 0x00000001 /* Reparented, on orphan list */
Index: sys/sys/procctl.h
===================================================================
--- sys/sys/procctl.h
+++ sys/sys/procctl.h
@@ -63,6 +63,7 @@
#define PROC_PROTMAX_STATUS 16 /* query implicit PROT_MAX status */
#define PROC_STACKGAP_CTL 17 /* en/dis stack gap on MAP_STACK */
#define PROC_STACKGAP_STATUS 18 /* query stack gap */
+#define PROC_NO_NEW_PRIVS 19 /* XXX */
/* Operations for PROC_SPROTECT (passed in integer arg). */
#define PPROT_OP(x) ((x) & 0xf)
Index: usr.sbin/chroot/chroot.c
===================================================================
--- usr.sbin/chroot/chroot.c
+++ usr.sbin/chroot/chroot.c
@@ -44,6 +44,7 @@
__FBSDID("$FreeBSD$");
#include <sys/types.h>
+#include <sys/procctl.h>
#include <ctype.h>
#include <err.h>
@@ -51,6 +52,7 @@
#include <limits.h>
#include <paths.h>
#include <pwd.h>
+#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -69,11 +71,13 @@
uid_t uid;
int ch, gids;
long ngroups_max;
+ bool nonpriviledged;
gid = 0;
uid = 0;
user = group = grouplist = NULL;
- while ((ch = getopt(argc, argv, "G:g:u:")) != -1) {
+ nonpriviledged = false;
+ while ((ch = getopt(argc, argv, "G:g:u:n")) != -1) {
switch(ch) {
case 'u':
user = optarg;
@@ -90,6 +94,9 @@
if (*grouplist == '\0')
usage();
break;
+ case 'n':
+ nonpriviledged = true;
+ break;
case '?':
default:
usage();
@@ -153,6 +160,10 @@
}
}
+ if (nonpriviledged &&
+ procctl(P_PID, getpid(), PROC_NO_NEW_PRIVS, NULL) == -1)
+ err(1, "procctl");
+
if (chdir(argv[0]) == -1 || chroot(".") == -1)
err(1, "%s", argv[0]);

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 1, 4:16 PM (20 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
13263072
Default Alt Text
D30130.id88696.diff (5 KB)

Event Timeline