xref: /openbsd/sys/sys/namei.h (revision 2d7f2af4)
1 /*	$OpenBSD: namei.h,v 1.50 2022/01/11 23:59:55 jsg Exp $	*/
2 /*	$NetBSD: namei.h,v 1.11 1996/02/09 18:25:20 christos Exp $	*/
3 
4 /*
5  * Copyright (c) 1985, 1989, 1991, 1993
6  *	The Regents of the University of California.  All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the University nor the names of its contributors
17  *    may be used to endorse or promote products derived from this software
18  *    without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
24  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30  * SUCH DAMAGE.
31  *
32  *	@(#)namei.h	8.4 (Berkeley) 8/20/94
33  */
34 
35 #ifndef _SYS_NAMEI_H_
36 #define	_SYS_NAMEI_H_
37 
38 #include <sys/queue.h>
39 #include <sys/tree.h>
40 #include <sys/uio.h>
41 
42 struct unveil;
43 
44 /*
45  * Encapsulation of namei parameters.
46  */
47 struct nameidata {
48 	/*
49 	 * Arguments to namei/lookup.
50 	 */
51 	const char *ni_dirp;		/* pathname pointer */
52 	int	ni_dirfd;		/* dirfd from *at() functions */
53 	enum	uio_seg ni_segflg;	/* location of pathname */
54      /* u_long	ni_nameiop;		   namei operation */
55      /* u_long	ni_flags;		   flags to namei */
56      /* struct	proc *ni_proc;		   process requesting lookup */
57 	/*
58 	 * Arguments to lookup.
59 	 */
60      /* struct	ucred *ni_cred;		   credentials */
61 	struct	vnode *ni_startdir;	/* starting directory */
62 	struct	vnode *ni_rootdir;	/* logical root directory */
63 	uint64_t ni_pledge;		/* expected pledge for namei */
64 	u_char ni_unveil;		/* required unveil flags for namei */
65 	/*
66 	 * Results: returned from/manipulated by lookup
67 	 */
68 	struct	vnode *ni_vp;		/* vnode of result */
69 	struct	vnode *ni_dvp;		/* vnode of intermediate directory */
70 
71 	/*
72 	 * Shared between namei and lookup/commit routines.
73 	 */
74 	size_t	ni_pathlen;		/* remaining chars in path */
75 	char	*ni_next;		/* next location in pathname */
76 	u_long	ni_loopcnt;		/* count of symlinks encountered */
77 	struct unveil *ni_unveil_match; /* last matching unveil component */
78 
79 	/*
80 	 * Lookup parameters: this structure describes the subset of
81 	 * information from the nameidata structure that is passed
82 	 * through the VOP interface.
83 	 */
84 	struct componentname {
85 		/*
86 		 * Arguments to lookup.
87 		 */
88 		u_long	cn_nameiop;	/* namei operation */
89 		u_long	cn_flags;	/* flags to namei */
90 		struct	proc *cn_proc;	/* process requesting lookup */
91 		struct	ucred *cn_cred;	/* credentials */
92 		/*
93 		 * Shared between lookup and commit routines.
94 		 */
95 		char	*cn_pnbuf;	/* pathname buffer */
96 		char	*cn_rpbuf;	/* realpath buffer */
97 		size_t	cn_rpi;		/* realpath index */
98 		char	*cn_nameptr;	/* pointer to looked up name */
99 		long	cn_namelen;	/* length of looked up component */
100 		long	cn_consume;	/* chars to consume in lookup() */
101 	} ni_cnd;
102 };
103 
104 #ifdef _KERNEL
105 /*
106  * namei operations
107  */
108 #define	LOOKUP		0	/* perform name lookup only */
109 #define	CREATE		1	/* setup for file creation */
110 #define	DELETE		2	/* setup for file deletion */
111 #define	RENAME		3	/* setup for file renaming */
112 #define	OPMASK		3	/* mask for operation */
113 /*
114  * namei operational modifier flags, stored in ni_cnd.flags
115  */
116 #define	LOCKLEAF	0x0004	/* lock inode on return */
117 #define	LOCKPARENT	0x0008	/* want parent vnode returned locked */
118 #define	WANTPARENT	0x0010	/* want parent vnode returned unlocked */
119 #define	NOCACHE		0x0020	/* name must not be left in cache */
120 #define	FOLLOW		0x0040	/* follow symbolic links */
121 #define	NOFOLLOW	0x0000	/* do not follow symbolic links (pseudo) */
122 #define	MODMASK		0x00fc	/* mask of operational modifiers */
123 /*
124  * Namei parameter descriptors.
125  *
126  * SAVENAME may be set by either the callers of namei or by VOP_LOOKUP.
127  * If the caller of namei sets the flag (for example execve wants to
128  * know the name of the program that is being executed), then it must
129  * free the buffer. If VOP_LOOKUP sets the flag, then the buffer must
130  * be freed by either the commit routine or the VOP_ABORT routine.
131  * SAVESTART is set only by the callers of namei. It implies SAVENAME
132  * plus the addition of saving the parent directory that contains the
133  * name in ni_startdir. It allows repeated calls to lookup for the
134  * name being sought. The caller is responsible for releasing the
135  * buffer and for vrele'ing ni_startdir.
136  */
137 #define	NOCROSSMOUNT	0x000100      /* do not cross mount points */
138 #define	RDONLY		0x000200      /* lookup with read-only semantics */
139 #define	HASBUF		0x000400      /* has allocated pathname buffer */
140 #define	SAVENAME	0x000800      /* save pathname buffer */
141 #define	SAVESTART	0x001000      /* save starting directory */
142 #define ISDOTDOT	0x002000      /* current component name is .. */
143 #define MAKEENTRY	0x004000      /* entry is to be added to name cache */
144 #define ISLASTCN	0x008000      /* this is last component of pathname */
145 #define ISSYMLINK	0x010000      /* symlink needs interpretation */
146 #define REALPATH	0x020000      /* save pathname buffer for realpath */
147 #define	REQUIREDIR	0x080000      /* must be a directory */
148 #define STRIPSLASHES    0x100000      /* strip trailing slashes */
149 #define PDIRUNLOCK	0x200000      /* vfs_lookup() unlocked parent dir */
150 #define BYPASSUNVEIL	0x400000      /* bypass pledgepath check */
151 #define KERNELPATH	0x800000      /* access file as kernel, not process */
152 
153 /*
154  * Initialization of an nameidata structure.
155  */
156 void ndinitat(struct nameidata *ndp, u_long op, u_long flags,
157     enum uio_seg segflg, int dirfd, const char *namep, struct proc *p);
158 
159 #define NDINITAT(ndp, op, flags, segflg, dirfd, namep, p)  \
160 	ndinitat(ndp, op, flags, segflg, dirfd, namep, p)
161 
162 #define NDINIT(ndp, op, flags, segflp, namep, p) \
163 	ndinitat(ndp, op, flags, segflp, AT_FDCWD, namep, p)
164 
165 /* Defined for users of NDINIT(). */
166 #define	AT_FDCWD	-100
167 #endif
168 
169 /*
170  * This structure describes the elements in the cache of recent
171  * names looked up by namei.
172  */
173 
174 #define	NAMECACHE_MAXLEN 31 /* maximum name segment length we bother with */
175 
176 struct	namecache {
177 	TAILQ_ENTRY(namecache) nc_lru;	/* Regular Entry LRU chain */
178 	TAILQ_ENTRY(namecache) nc_neg;	/* Negative Entry LRU chain */
179 	RBT_ENTRY(namecache) n_rbcache;	/* Namecache rb tree from vnode */
180 	TAILQ_ENTRY(namecache) nc_me;	/* ncp's referring to me */
181 	struct	vnode *nc_dvp;		/* vnode of parent of name */
182 	u_long	nc_dvpid;		/* capability number of nc_dvp */
183 	struct	vnode *nc_vp;		/* vnode the name refers to */
184 	u_long	nc_vpid;		/* capability number of nc_vp */
185 	char	nc_nlen;		/* length of name */
186 	char	nc_name[NAMECACHE_MAXLEN];	/* segment name */
187 };
188 
189 #ifdef _KERNEL
190 struct	namecache_rb_cache;
191 
192 int	namei(struct nameidata *ndp);
193 int	vfs_lookup(struct nameidata *ndp);
194 int	vfs_relookup(struct vnode *dvp, struct vnode **vpp,
195 		      struct componentname *cnp);
196 void cache_tree_init(struct namecache_rb_cache *);
197 void cache_purge(struct vnode *);
198 int cache_lookup(struct vnode *, struct vnode **, struct componentname *);
199 void cache_enter(struct vnode *, struct vnode *, struct componentname *);
200 int cache_revlookup(struct vnode *, struct vnode **, char **, char *);
201 void nchinit(void);
202 struct mount;
203 void cache_purgevfs(struct mount *);
204 
205 int unveil_add(struct proc *, struct nameidata *, const char *);
206 void unveil_removevnode(struct vnode *);
207 ssize_t unveil_find_cover(struct vnode *, struct proc *);
208 struct unveil *unveil_lookup(struct vnode *, struct process *, ssize_t *);
209 void unveil_start_relative(struct proc *, struct nameidata *, struct vnode *);
210 void unveil_check_component(struct proc *, struct nameidata *, struct vnode *);
211 int unveil_check_final(struct proc *, struct nameidata *);
212 
213 extern struct pool namei_pool;
214 
215 #endif
216 
217 /*
218  * Stats on usefulness of namei caches.
219  */
220 struct	nchstats {
221 	u_int64_t	ncs_goodhits;	/* hits that we can really use */
222 	u_int64_t	ncs_neghits;	/* negative hits that we can use */
223 	u_int64_t	ncs_badhits;	/* hits we must drop */
224 	u_int64_t	ncs_falsehits;	/* hits with id mismatch */
225 	u_int64_t	ncs_miss;	/* misses */
226 	u_int64_t	ncs_long;	/* long names that ignore cache */
227 	u_int64_t	ncs_pass2;	/* names found with passes == 2 */
228 	u_int64_t	ncs_2passes;	/* number of times we attempt it */
229 	u_int64_t	ncs_revhits;	/* reverse-cache hits */
230 	u_int64_t	ncs_revmiss;	/* reverse-cache misses */
231 	u_int64_t	ncs_dothits;	/* hits on '.' lookups */
232 	u_int64_t	ncs_dotdothits;	/* hits on '..' lookups */
233 };
234 
235 /* These sysctl names are only really used by sysctl(8) */
236 #define KERN_NCHSTATS_GOODHITS		1
237 #define KERN_NCHSTATS_NEGHITS		2
238 #define KERN_NCHSTATS_BADHITS		3
239 #define KERN_NCHSTATS_FALSEHITS		4
240 #define KERN_NCHSTATS_MISS		5
241 #define KERN_NCHSTATS_LONG		6
242 #define KERN_NCHSTATS_PASS2		7
243 #define KERN_NCHSTATS_2PASSES		8
244 #define KERN_NCHSTATS_REVHITS           9
245 #define KERN_NCHSTATS_REVMISS           10
246 #define KERN_NCHSTATS_DOTHITS		11
247 #define KERN_NCHSTATS_DOTDOTHITS	12
248 #define KERN_NCHSTATS_MAXID		13
249 
250 #define CTL_KERN_NCHSTATS_NAMES {		\
251 	{ 0, 0 },				\
252 	{ "good_hits", CTLTYPE_QUAD },		\
253 	{ "negative_hits", CTLTYPE_QUAD },	\
254 	{ "bad_hits", CTLTYPE_QUAD },		\
255 	{ "false_hits", CTLTYPE_QUAD },		\
256 	{ "misses", CTLTYPE_QUAD },		\
257 	{ "long_names", CTLTYPE_QUAD },		\
258 	{ "pass2", CTLTYPE_QUAD },		\
259 	{ "2passes", CTLTYPE_QUAD },		\
260 	{ "ncs_revhits", CTLTYPE_QUAD },	\
261 	{ "ncs_revmiss", CTLTYPE_QUAD },	\
262 	{ "ncs_dothits", CTLTYPE_QUAD },	\
263 	{ "nch_dotdothits", CTLTYPE_QUAD },	\
264 }
265 
266 /* Unveil flags for namei */
267 #define	UNVEIL_READ	0x01
268 #define	UNVEIL_WRITE	0x02
269 #define	UNVEIL_CREATE	0x04
270 #define	UNVEIL_EXEC	0x08
271 #define	UNVEIL_USERSET	0x10
272 #define	UNVEIL_MASK	0x0F
273 
274 #endif /* !_SYS_NAMEI_H_ */
275