Page MenuHomeFreeBSD

D40680.id123577.diff
No OneTemporary

D40680.id123577.diff

diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -3017,7 +3017,7 @@
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
#ifdef notyet
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
#else
return (EAGAIN);
#endif
@@ -3107,7 +3107,7 @@
if (!cap_rights_contains(&ndp->ni_filecaps.fc_rights, &rights) ||
ndp->ni_filecaps.fc_fcntls != CAP_FCNTL_ALL ||
ndp->ni_filecaps.fc_nioctls != -1) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
ndp->ni_resflags |= NIRES_STRICTREL;
}
#endif
diff --git a/sys/kern/kern_exec.c b/sys/kern/kern_exec.c
--- a/sys/kern/kern_exec.c
+++ b/sys/kern/kern_exec.c
@@ -456,6 +456,8 @@
interpret:
if (args->fname != NULL) {
#ifdef CAPABILITY_MODE
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_VFS, args->fname);
/*
* While capability mode can't reach this point via direct
* path arguments to execve(), we also don't allow
diff --git a/sys/kern/uipc_shm.c b/sys/kern/uipc_shm.c
--- a/sys/kern/uipc_shm.c
+++ b/sys/kern/uipc_shm.c
@@ -1174,8 +1174,12 @@
/*
* shm_open(2) is only allowed for anonymous objects.
*/
- if (IN_CAPABILITY_MODE(td) && (userpath != SHM_ANON))
- return (ECAPMODE);
+ if (userpath != SHM_ANON) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_VFS, userpath);
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
#endif
AUDIT_ARG_FFLAGS(flags);
diff --git a/sys/kern/uipc_syscalls.c b/sys/kern/uipc_syscalls.c
--- a/sys/kern/uipc_syscalls.c
+++ b/sys/kern/uipc_syscalls.c
@@ -203,8 +203,12 @@
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
- return (ECAPMODE);
+ if (dirfd == AT_FDCWD) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_VFS, "AT_FDCWD");
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
#endif
AUDIT_ARG_FD(fd);
@@ -491,8 +495,12 @@
int error;
#ifdef CAPABILITY_MODE
- if (IN_CAPABILITY_MODE(td) && (dirfd == AT_FDCWD))
- return (ECAPMODE);
+ if (dirfd == AT_FDCWD) {
+ if (CAP_TRACING(td))
+ ktrcapfail(CAPFAIL_VFS, "AT_FDCWD");
+ if (IN_CAPABILITY_MODE(td))
+ return (ECAPMODE);
+ }
#endif
AUDIT_ARG_FD(fd);
diff --git a/sys/kern/vfs_cache.c b/sys/kern/vfs_cache.c
--- a/sys/kern/vfs_cache.c
+++ b/sys/kern/vfs_cache.c
@@ -4401,7 +4401,7 @@
cache_fpl_aborted_early(fpl);
return (false);
}
- if (IN_CAPABILITY_MODE(td)) {
+ if (IN_CAPABILITY_MODE(td) || CAP_TRACING(td)) {
cache_fpl_aborted_early(fpl);
return (false);
}
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c
--- a/sys/kern/vfs_lookup.c
+++ b/sys/kern/vfs_lookup.c
@@ -238,14 +238,17 @@
struct mount *mp;
if (dp == NULL || dp->v_type != VDIR || (ndp->ni_lcf &
- NI_LCF_STRICTRELATIVE) == 0)
+ NI_LCF_STRICTREL) == 0)
return (0);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR |
+ NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR))
+ NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf);
if ((ndp->ni_lcf & NI_LCF_CAP_DOTDOT) == 0)
return (ENOTCAPABLE);
mp = dp->v_mount;
if (lookup_cap_dotdot_nonlocal == 0 && mp != NULL &&
(mp->mnt_flag & MNT_LOCAL) == 0)
- return (ENOTCAPABLE);
+ goto capfail;
TAILQ_FOREACH_REVERSE(nt, &ndp->ni_cap_tracker, nameicap_tracker_head,
nm_link) {
if (dp == nt->dp) {
@@ -255,6 +258,10 @@
return (0);
}
}
+
+capfail:
+ if (__predict_false((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0))
+ NI_CAP_VIOLATION(ndp, ndp->ni_cnd.cn_pnbuf);
return (ENOTCAPABLE);
}
@@ -273,12 +280,12 @@
struct componentname *cnp;
cnp = &ndp->ni_cnd;
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ENOTCAPABLE);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL |
+ NI_LCF_STRICTREL_KTR)) != 0)) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0)
+ return (ENOTCAPABLE);
}
while (*(cnp->cn_nameptr) == '/') {
cnp->cn_nameptr++;
@@ -319,15 +326,17 @@
* previously walked by us, which prevents an escape from
* the relative root.
*/
- if (IN_CAPABILITY_MODE(td) && (cnp->cn_flags & NOCAPCHECK) == 0) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE;
- ndp->ni_resflags |= NIRES_STRICTREL;
- if (ndp->ni_dirfd == AT_FDCWD) {
-#ifdef KTRACE
- if (KTRPOINT(td, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
- return (ECAPMODE);
+ if ((cnp->cn_flags & NOCAPCHECK) == 0) {
+ if (CAP_TRACING(td)) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL_KTR;
+ if (ndp->ni_dirfd == AT_FDCWD)
+ NI_CAP_VIOLATION(ndp, "AT_FDCWD");
+ }
+ if (IN_CAPABILITY_MODE(td)) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL;
+ ndp->ni_resflags |= NIRES_STRICTREL;
+ if (ndp->ni_dirfd == AT_FDCWD)
+ return (ECAPMODE);
}
}
#endif
@@ -370,8 +379,8 @@
if (error == 0 && (cnp->cn_flags & RBENEATH) != 0) {
if (cnp->cn_pnbuf[0] == '/') {
error = ENOTCAPABLE;
- } else if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) == 0) {
- ndp->ni_lcf |= NI_LCF_STRICTRELATIVE |
+ } else if ((ndp->ni_lcf & NI_LCF_STRICTREL) == 0) {
+ ndp->ni_lcf |= NI_LCF_STRICTREL |
NI_LCF_CAP_DOTDOT;
}
}
@@ -393,9 +402,12 @@
pwd_drop(pwd);
return (error);
}
- if ((ndp->ni_lcf & NI_LCF_STRICTRELATIVE) != 0 &&
- lookup_cap_dotdot != 0)
- ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
+ if (lookup_cap_dotdot != 0) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ ndp->ni_lcf |= NI_LCF_CAP_DOTDOT_KTR;
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0)
+ ndp->ni_lcf |= NI_LCF_CAP_DOTDOT;
+ }
SDT_PROBE4(vfs, namei, lookup, entry, *dpp, cnp->cn_pnbuf,
cnp->cn_flags, false);
*pwdp = pwd;
@@ -1090,12 +1102,11 @@
* result of dotdot lookup.
*/
if (cnp->cn_flags & ISDOTDOT) {
- if ((ndp->ni_lcf & (NI_LCF_STRICTRELATIVE | NI_LCF_CAP_DOTDOT))
- == NI_LCF_STRICTRELATIVE) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL_KTR |
+ NI_LCF_CAP_DOTDOT_KTR)) == NI_LCF_STRICTREL_KTR))
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if (__predict_false((ndp->ni_lcf & (NI_LCF_STRICTREL |
+ NI_LCF_CAP_DOTDOT)) == NI_LCF_STRICTREL)) {
error = ENOTCAPABLE;
goto bad;
}
@@ -1112,10 +1123,14 @@
bool isroot = dp == ndp->ni_rootdir ||
dp == ndp->ni_topdir || dp == rootvnode ||
pr != NULL;
- if (isroot && (ndp->ni_lcf &
- NI_LCF_STRICTRELATIVE) != 0) {
- error = ENOTCAPABLE;
- goto capdotdot;
+ if (__predict_false(isroot && (ndp->ni_lcf &
+ (NI_LCF_STRICTREL | NI_LCF_STRICTREL_KTR)) != 0)) {
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL_KTR) != 0)
+ NI_CAP_VIOLATION(ndp, cnp->cn_pnbuf);
+ if ((ndp->ni_lcf & NI_LCF_STRICTREL) != 0) {
+ error = ENOTCAPABLE;
+ goto capdotdot;
+ }
}
if (isroot || ((dp->v_vflag & VV_ROOT) != 0 &&
(cnp->cn_flags & NOCROSSMOUNT) != 0)) {
@@ -1140,10 +1155,6 @@
error = nameicap_check_dotdot(ndp, dp);
if (error != 0) {
capdotdot:
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
goto bad;
}
}
@@ -1359,13 +1370,8 @@
}
if (cnp->cn_flags & ISDOTDOT) {
error = nameicap_check_dotdot(ndp, ndp->ni_vp);
- if (error != 0) {
-#ifdef KTRACE
- if (KTRPOINT(curthread, KTR_CAPFAIL))
- ktrcapfail(CAPFAIL_LOOKUP, NULL, NULL);
-#endif
+ if (error != 0)
goto bad2;
- }
}
if (*ndp->ni_next == '/') {
cnp->cn_nameptr = ndp->ni_next;
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -199,8 +199,17 @@
/*
* Flags in ni_lcf, valid for the duration of the namei call.
*/
-#define NI_LCF_STRICTRELATIVE 0x0001 /* relative lookup only */
+#define NI_LCF_STRICTREL 0x0001 /* relative lookup only */
#define NI_LCF_CAP_DOTDOT 0x0002 /* ".." in strictrelative case */
+/* Track capability restrictions seperately for violation ktracing. */
+#define NI_LCF_STRICTREL_KTR 0x0004 /* trace relative lookups */
+#define NI_LCF_CAP_DOTDOT_KTR 0x0008 /* ".." in strictrelative case */
+#define NI_LCF_KTR_FLAGS (NI_LCF_STRICTREL_KTR | NI_LCF_CAP_DOTDOT_KTR)
+
+#define NI_CAP_VIOLATION(ndp, path) do { \
+ ktrcapfail(CAPFAIL_VFS, (path)); \
+ (ndp)->ni_lcf &= ~NI_LCF_KTR_FLAGS; \
+} while (0)
/*
* Initialization of a nameidata structure.

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 28, 7:45 AM (13 h, 17 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17827186
Default Alt Text
D40680.id123577.diff (8 KB)

Event Timeline