Index: sys/sys/vnode.h =================================================================== --- sys/sys/vnode.h (wersja 243142) +++ sys/sys/vnode.h (kopia robocza) @@ -565,6 +565,7 @@ /* vn_open_flags */ #define VN_OPEN_NOAUDIT 0x00000001 +#define VN_OPEN_NOCAPCHECK 0x00000002 /* * Public vnode manipulation functions. Index: sys/sys/namei.h =================================================================== --- sys/sys/namei.h (wersja 243142) +++ sys/sys/namei.h (kopia robocza) @@ -147,7 +147,8 @@ #define AUDITVNODE1 0x04000000 /* audit the looked up vnode information */ #define AUDITVNODE2 0x08000000 /* audit the looked up vnode information */ #define TRAILINGSLASH 0x10000000 /* path ended in a slash */ -#define PARAMASK 0x1ffffe00 /* mask of parameter descriptors */ +#define NOCAPCHECK 0x20000000 /* do not perform capability checks */ +#define PARAMASK 0x3ffffe00 /* mask of parameter descriptors */ /* * Initialization of a nameidata structure. Index: sys/kern/vfs_lookup.c =================================================================== --- sys/kern/vfs_lookup.c (wersja 243142) +++ sys/kern/vfs_lookup.c (kopia robocza) @@ -183,7 +183,7 @@ * not an absolute path, and not containing '..' components) to * a real file descriptor, not the pseudo-descriptor AT_FDCWD. */ - if (IN_CAPABILITY_MODE(td)) { + if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) { ndp->ni_strictrelative = 1; if (ndp->ni_dirfd == AT_FDCWD) { #ifdef KTRACE Index: sys/kern/vfs_vnops.c =================================================================== --- sys/kern/vfs_vnops.c (wersja 243142) +++ sys/kern/vfs_vnops.c (kopia robocza) @@ -135,6 +135,8 @@ ndp->ni_cnd.cn_flags |= FOLLOW; if (!(vn_open_flags & VN_OPEN_NOAUDIT)) ndp->ni_cnd.cn_flags |= AUDITVNODE1; + if (vn_open_flags & VN_OPEN_NOCAPCHECK) + ndp->ni_cnd.cn_flags |= NOCAPCHECK; bwillwrite(); if ((error = namei(ndp)) != 0) return (error); @@ -188,6 +190,8 @@ ndp->ni_cnd.cn_flags |= LOCKSHARED; if (!(vn_open_flags & VN_OPEN_NOAUDIT)) ndp->ni_cnd.cn_flags |= AUDITVNODE1; + if (vn_open_flags & VN_OPEN_NOCAPCHECK) + ndp->ni_cnd.cn_flags |= NOCAPCHECK; if ((error = namei(ndp)) != 0) return (error); vp = ndp->ni_vp; Index: sys/kern/kern_sig.c =================================================================== --- sys/kern/kern_sig.c (wersja 243142) +++ sys/kern/kern_sig.c (kopia robocza) @@ -171,9 +171,15 @@ (cr1)->cr_uid == (cr2)->cr_uid) static int sugid_coredump; +TUNABLE_INT("kern.sugid_coredump", &sugid_coredump); SYSCTL_INT(_kern, OID_AUTO, sugid_coredump, CTLFLAG_RW, &sugid_coredump, 0, "Allow setuid and setgid processes to dump core"); +static int capmode_coredump; +TUNABLE_INT("kern.capmode_coredump", &capmode_coredump); +SYSCTL_INT(_kern, OID_AUTO, capmode_coredump, CTLFLAG_RW, + &capmode_coredump, 0, "Allow processes in capability mode to dump core"); + static int do_coredump = 1; SYSCTL_INT(_kern, OID_AUTO, coredump, CTLFLAG_RW, &do_coredump, 0, "Enable/Disable coredumps"); @@ -3123,12 +3137,17 @@ int error, n; int flags = O_CREAT | O_EXCL | FWRITE | O_NOFOLLOW; int cmode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP; + int oflags = 0; + if (capmode_coredump) + oflags = VN_OPEN_NOCAPCHECK; + for (n = 0; n < num_cores; n++) { temp[indexpos] = '0' + n; NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, temp, td); - error = vn_open(&nd, &flags, cmode, NULL); + error = vn_open_cred(&nd, &flags, cmode, oflags, + td->td_ucred, NULL); if (error) { if (error == EEXIST) { continue; @@ -3230,8 +3249,10 @@ restart: NDINIT(&nd, LOOKUP, NOFOLLOW, UIO_SYSSPACE, name, td); flags = O_CREAT | FWRITE | O_NOFOLLOW; - error = vn_open_cred(&nd, &flags, S_IRUSR | S_IWUSR, VN_OPEN_NOAUDIT, + error = vn_open_cred(&nd, &flags, S_IRUSR | S_IWUSR, + VN_OPEN_NOAUDIT | (capmode_coredump ? VN_OPEN_NOCAPCHECK : 0), cred, NULL); + if (error) { #ifdef AUDIT audit_proc_coredump(td, name, error);