Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F177414989
D61315.1794320945.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Authored By
Unknown
Size
4 KB
Referenced Files
None
Subscribers
None
D61315.1794320945.diff
View Options
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
@@ -3332,6 +3332,8 @@
VFS_SMR_ASSERT_ENTERED();
fd = ndp->ni_dirfd;
+ MPASS(fd >= 0);
+
rights = *ndp->ni_rightsneeded;
cap_rights_set_one(&rights, CAP_LOOKUP);
@@ -3397,6 +3399,8 @@
VFS_SMR_ASSERT_ENTERED();
fd = ndp->ni_dirfd;
+ MPASS(fd >= 0);
+
fdp = curproc->p_fd;
fdt = fdp->fd_files;
if (__predict_false((u_int)fd >= fdt->fdt_nfiles))
@@ -3438,6 +3442,8 @@
int error;
uint8_t flags;
+ MPASS(ndp->ni_dirfd >= 0);
+
td = curthread;
rights = *ndp->ni_rightsneeded;
cap_rights_set_one(&rights, CAP_LOOKUP);
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
@@ -76,12 +76,15 @@
/*
* Reset ndp to its original state.
+ * namei() supplies the starting directory again on restart, so unlike
+ * NDREINIT(), NAMEI_DBG_HADSTARTDIR can be set there.
*/
#define NDRESET(ndp) do { \
- NDREINIT_DBG(ndp); \
+ NDRESET_DBG(ndp); \
ndp->ni_resflags = 0; \
ndp->ni_cnd.cn_flags &= ~NAMEI_INTERNAL_FLAGS; \
} while (0)
+
/*
* Prepare namei() to restart. Reset components to its original state and set
* ISRESTARTED flag which signals the underlying lookup code to change the root
@@ -618,6 +621,7 @@
namei(struct nameidata *ndp)
{
struct vnode *dp; /* the directory we are searching */
+ struct vnode *atvp; /* NDINIT_ATVP() starting directory */
struct componentname *cnp;
struct thread *td;
struct pwd *pwd;
@@ -635,6 +639,7 @@
cnp = &ndp->ni_cnd;
td = curthread;
+ atvp = ndp->ni_startdir;
abi_symlink = NULL;
abi_symlink_len = 0;
abi_suffix_len = 0;
@@ -709,6 +714,8 @@
* We may need to start from scratch or pick up where it left off.
*/
error = cache_fplookup(ndp, &status, &pwd);
+ /* cache_can_fplookup() rejects ni_startdir. */
+ MPASS(atvp == NULL || status == CACHE_FPL_STATUS_ABORTED);
switch (status) {
case CACHE_FPL_STATUS_UNSET:
__assert_unreachable();
@@ -751,8 +758,17 @@
false, ndp);
return (ENOENT);
}
+ /*
+ * namei_setup() and vfs_lookup() consume the reference
+ * on ni_startdir. Hold the NDINIT_ATVP() vnode so that
+ * a restart can reference it again.
+ */
+ if (atvp != NULL)
+ vhold(atvp);
error = namei_setup(ndp, &dp, &pwd);
if (error != 0) {
+ if (atvp != NULL)
+ vdrop(atvp);
namei_cleanup_cnp(cnp);
nameicap_cleanup(ndp, error);
return (error);
@@ -831,6 +847,11 @@
if (abi_restart)
was_restarted = ISRESTARTED;
ndp->ni_cnd.cn_flags |= was_restarted;
+ if (atvp != NULL) {
+ vref(atvp);
+ ndp->ni_startdir = atvp;
+ vdrop(atvp);
+ }
goto restart;
}
@@ -843,6 +864,8 @@
nameicap_cleanup(ndp, 0);
pwd_drop(pwd);
uma_zfree(namei_zone, abi_symlink);
+ if (atvp != NULL)
+ vdrop(atvp);
NDVALIDATE(ndp);
return (0);
}
@@ -916,6 +939,8 @@
nameicap_cleanup(ndp, error);
pwd_drop(pwd);
uma_zfree(namei_zone, abi_symlink);
+ if (atvp != NULL)
+ vdrop(atvp);
return (error);
}
diff --git a/sys/sys/namei.h b/sys/sys/namei.h
--- a/sys/sys/namei.h
+++ b/sys/sys/namei.h
@@ -216,6 +216,7 @@
/*
* Initialization of a nameidata structure.
*/
+#define AT_ATVP (-101) /* NDINIT_ATVP dirfd */
#define NDINIT(ndp, op, flags, segflg, namep) \
NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, NULL, &cap_no_rights)
#define NDINIT_AT(ndp, op, flags, segflg, namep, dirfd) \
@@ -223,7 +224,7 @@
#define NDINIT_ATRIGHTS(ndp, op, flags, segflg, namep, dirfd, rightsp) \
NDINIT_ALL(ndp, op, flags, segflg, namep, dirfd, NULL, rightsp)
#define NDINIT_ATVP(ndp, op, flags, segflg, namep, vp) \
- NDINIT_ALL(ndp, op, flags, segflg, namep, AT_FDCWD, vp, &cap_no_rights)
+ NDINIT_ALL(ndp, op, flags, segflg, namep, AT_ATVP, vp, &cap_no_rights)
/*
* Note the constant pattern may *hide* bugs.
@@ -235,19 +236,23 @@
#define NDINIT_PREFILL(arg) memset(arg, 0xff, offsetof(struct nameidata, \
ni_dvp_seqc))
#define NDINIT_DBG(arg) { (arg)->ni_debugflags = NAMEI_DBG_INITED; }
-#define NDREINIT_DBG(arg) { \
+#define NDRESET_DBG(arg) { \
if (((arg)->ni_debugflags & NAMEI_DBG_INITED) == 0) \
panic("namei data not inited"); \
- if (((arg)->ni_debugflags & NAMEI_DBG_HADSTARTDIR) != 0) \
- panic("NDREINIT on namei data with NAMEI_DBG_HADSTARTDIR"); \
if ((arg)->ni_nctrack_mnt != NULL) \
panic("NDREINIT on namei data with leaked ni_nctrack_mnt"); \
if (!TAILQ_EMPTY(&(arg)->ni_cap_tracker)) \
panic("NDREINIT on namei data with leaked ni_cap_tracker"); \
+}
+#define NDREINIT_DBG(arg) { \
+ NDRESET_DBG(arg); \
+ if (((arg)->ni_debugflags & NAMEI_DBG_HADSTARTDIR) != 0) \
+ panic("NDREINIT on namei data with NAMEI_DBG_HADSTARTDIR"); \
(arg)->ni_debugflags = NAMEI_DBG_INITED; \
}
#else
#define NDINIT_PREFILL(arg) do { } while (0)
+#define NDRESET_DBG(arg) do { } while (0)
#define NDINIT_DBG(arg) do { } while (0)
#define NDREINIT_DBG(arg) do { } while (0)
#endif
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Tue, Nov 10, 2:29 PM (9 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
41622007
Default Alt Text
D61315.1794320945.diff (4 KB)
Attached To
Mode
D61315: namei(9): allow NDINIT_ATVP() lookups in capability mode
Attached
Detach File
Event Timeline