Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F162631235
D52757.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
8 KB
Referenced Files
None
Subscribers
None
D52757.diff
View Options
diff --git a/share/man/man9/Makefile b/share/man/man9/Makefile
--- a/share/man/man9/Makefile
+++ b/share/man/man9/Makefile
@@ -2455,6 +2455,7 @@
MLINKS+=vm_page_wire.9 vm_page_unwire.9 \
vm_page_wire.9 vm_page_unwire_noq.9 \
vm_page_wire.9 vm_page_wire_mapped.9
+MLINKS+=vn_fullpath.9 vn_fullpath_jail.9
MLINKS+=VOP_ACCESS.9 VOP_ACCESSX.9
MLINKS+=VOP_ATTRIB.9 VOP_GETATTR.9 \
VOP_ATTRIB.9 VOP_SETATTR.9 \
diff --git a/share/man/man9/vn_fullpath.9 b/share/man/man9/vn_fullpath.9
--- a/share/man/man9/vn_fullpath.9
+++ b/share/man/man9/vn_fullpath.9
@@ -1,6 +1,13 @@
+.\"-
+.\" SPDX-License-Identifier: BSD-2-Clause
.\"
.\" Copyright (c) 2003 Robert N. M. Watson.
.\" All rights reserved.
+.\" Copyright (c) 2025 The FreeBSD Foundation
+.\"
+.\" Portions of this documentation were written by Olivier Certner
+.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD
+.\" Foundation.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
@@ -25,7 +32,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
.\" DAMAGE.
.\"
-.Dd June 15, 2021
+.Dd September 29, 2025
.Dt VN_FULLPATH 9
.Os
.Sh NAME
@@ -35,23 +42,64 @@
.In sys/param.h
.In sys/vnode.h
.Ft int
-.Fo vn_fullpath
-.Fa "struct vnode *vp" "char **retbuf" "char **freebuf"
+.Fn vn_fullpath "struct vnode *vp" "char **retbuf" "char **freebuf"
+.Ft int
+.Fn vn_fullpath_jail "struct vnode *vp" "char **retbuf" "char **freebuf"
+.Ft int
+.Fn vn_fullpath_global "struct vnode *vp" "char **retbuf" "char **freebuf"
+.Ft int
+.Fo vn_fullpath_hardlink
+.Fa "struct vnode *vp" "struct vnode *dvp"
+.Fa "const char *hrdl_name" "size_t hrdl_name_length"
+.Fa "char **retbuf" "char **freebuf" "size_t *buflen"
.Fc
.Sh DESCRIPTION
The
+.Fn vn_fullpath ,
+.Fn vn_fullpath_jail ,
+.Fn vn_fullpath_global
+and
+.Fn vn_fullpath_hardlink
+functions make a
+.Dq best effort
+attempt at generating a string pathname for the passed vnode.
+They differ in which directory the returned path is relative to, except for
+.Fn vn_fullpath_hardlink
+which behaves like
.Fn vn_fullpath
-function makes a
-.Dq "best effort"
-attempt to generate a string pathname for
-the passed vnode; the resulting path, if any, will be relative to
-the root directory of the process associated with the passed thread pointer.
+in this respect and is described at the end.
+.Pp
The
.Fn vn_fullpath
-function
-is implemented by inspecting the VFS name cache, and attempting to
-reconstruct a path from the process root to the object.
+function returns a path relative to the root directory of the process associated
+with the passed thread pointer.
+That root directory is either the system's or the thread's process' containing
+jail's root directory, or some descendant directory of such established by some
+.Xr chroot 2
+call.
+The
+.Fn vn_fullpath_jail
+function returns a path relative to the passed thread's process' current jail's
+root, ignoring intervening
+.Xr chroot 2
+calls possibly made inside that jail.
+The
+.Fn vn_fullpath_global
+function returns the full path from the system root, ignoring all jail roots and
+.Xr chroot 2
+calls.
+.Pp
+Paths that the kernel intends to communicate to the passed user thread should
+exclusively be obtained via
+.Fn vn_fullpath .
+Paths obtained via
+.Fn vn_fullpath_jail
+or
+.Fn vn_fullpath_global
+are only useful for specific kernel checks or auditing purposes.
.Pp
+All these functions are implemented by inspecting the VFS name cache, and
+attempting to reconstruct a path from the process root to the object.
This process is necessarily unreliable for several reasons: intermediate
entries in the path may not be found in the cache; files may have more
than one name (hard links), not all file systems use the name cache
@@ -64,7 +112,7 @@
Code consuming the results of this function should anticipate (and
properly handle) failure.
.Pp
-Its arguments are:
+These functions take the following arguments:
.Bl -tag -width ".Fa freebuf"
.It Fa vp
The vnode to search for.
@@ -72,17 +120,13 @@
.It Fa retbuf
Pointer to a
.Vt "char *"
-that
-.Fn vn_fullpath
-may (on success) point at a newly
-allocated buffer containing the resulting pathname.
+that may be set (on success) to point at a newly allocated buffer containing the
+resulting pathname.
.It Fa freebuf
Pointer to a
.Vt "char *"
-that
-.Fn vn_fullpath
-may (on success) point at a buffer
-to be freed, when the caller is done with
+that may be set (on success) to point at a buffer to be freed, when the caller
+is done with
.Fa retbuf .
.El
.Pp
@@ -110,11 +154,43 @@
.Xr free 9
with a pool type of
.Dv M_TEMP .
+.Pp
+The
+.Fn vn_fullpath_hardlink
+function is a convenience wrapper which automatically appends the hardlink name
+passed via arguments
+.Fa hrdl_name
+and
+.Fa hrdl_name_length
+to the result of calling
+.Fn vn_fullpath
+on the vnode's parent directory.
+It requires the results of a prior call to
+.Xr namei 9
+with flag
+.Dv WANTPARENT
+to be passed in the
+.Fa vp
+and
+.Fa dvp
+arguments.
+Argument
+.Fa buflen
+must point to a valid storage containing the size of the desired buffer, which
+will be reduced to
+.Dv MAXPATHLEN
+if in excess of it.
.Sh RETURN VALUES
If the vnode is successfully converted to a pathname, 0 is returned;
otherwise, an error number is returned.
.Sh SEE ALSO
.Xr free 9
.Sh AUTHORS
-This manual page was written by
-.An Robert Watson Aq Mt rwatson@FreeBSD.org .
+.An -nosplit
+This manual page was initally written by
+.An Robert Watson Aq Mt rwatson@FreeBSD.org
+to describe the
+.Fn vn_fullpath
+function.
+The descriptions of the other related functions were added by
+.An Olivier Certner Aq Mt olce@FreeBSD.org .
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
@@ -3340,12 +3340,10 @@
uap->flags, UIO_USERSPACE));
}
-/*
- * Retrieve the full filesystem path that correspond to a vnode from the name
- * cache (if available)
- */
-int
-vn_fullpath(struct vnode *vp, char **retbuf, char **freebuf)
+static int
+vn_fullpath_up_to_pwd_vnode(struct vnode *vp,
+ struct vnode *(*const get_pwd_vnode)(const struct pwd *),
+ char **retbuf, char **freebuf)
{
struct pwd *pwd;
char *buf;
@@ -3359,11 +3357,13 @@
buf = malloc(buflen, M_TEMP, M_WAITOK);
vfs_smr_enter();
pwd = pwd_get_smr();
- error = vn_fullpath_any_smr(vp, pwd->pwd_rdir, buf, retbuf, &buflen, 0);
+ error = vn_fullpath_any_smr(vp, get_pwd_vnode(pwd), buf, retbuf,
+ &buflen, 0);
VFS_SMR_ASSERT_NOT_ENTERED();
if (error < 0) {
pwd = pwd_hold(curthread);
- error = vn_fullpath_any(vp, pwd->pwd_rdir, buf, retbuf, &buflen);
+ error = vn_fullpath_any(vp, get_pwd_vnode(pwd), buf, retbuf,
+ &buflen);
pwd_drop(pwd);
}
if (error == 0)
@@ -3373,6 +3373,42 @@
return (error);
}
+static inline struct vnode *
+get_rdir(const struct pwd *pwd)
+{
+ return (pwd->pwd_rdir);
+}
+
+/*
+ * Produce a filesystem path that starts from the current chroot directory and
+ * corresponds to the passed vnode, using the name cache (if available).
+ */
+int
+vn_fullpath(struct vnode *vp, char **retbuf, char **freebuf)
+{
+ return (vn_fullpath_up_to_pwd_vnode(vp, get_rdir, retbuf, freebuf));
+}
+
+static inline struct vnode *
+get_jdir(const struct pwd *pwd)
+{
+ return (pwd->pwd_jdir);
+}
+
+/*
+ * Produce a filesystem path that starts from the current jail's root directory
+ * and corresponds to the passed vnode, using the name cache (if available).
+ *
+ * This function allows to ignore chroots done inside a jail (or the host),
+ * allowing path checks to remain unaffected by privileged or unprivileged
+ * chroot calls.
+ */
+int
+vn_fullpath_jail(struct vnode *vp, char **retbuf, char **freebuf)
+{
+ return (vn_fullpath_up_to_pwd_vnode(vp, get_jdir, retbuf, freebuf));
+}
+
/*
* This function is similar to vn_fullpath, but it attempts to lookup the
* pathname relative to the global root mount point. This is required for the
diff --git a/sys/sys/vnode.h b/sys/sys/vnode.h
--- a/sys/sys/vnode.h
+++ b/sys/sys/vnode.h
@@ -714,6 +714,7 @@
int vn_vptocnp(struct vnode **vp, char *buf, size_t *buflen);
int vn_getcwd(char *buf, char **retbuf, size_t *buflen);
int vn_fullpath(struct vnode *vp, char **retbuf, char **freebuf);
+int vn_fullpath_jail(struct vnode *vp, char **retbuf, char **freebuf);
int vn_fullpath_global(struct vnode *vp, char **retbuf, char **freebuf);
int vn_fullpath_hardlink(struct vnode *vp, struct vnode *dvp,
const char *hdrl_name, size_t hrdl_name_length, char **retbuf,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Jul 16, 6:46 AM (11 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
35126990
Default Alt Text
D52757.diff (8 KB)
Attached To
Mode
D52757: vfs cache: Add vn_fullpath_jail(), factor out common code
Attached
Detach File
Event Timeline
Log In to Comment