162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *  linux/fs/namei.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci *  Copyright (C) 1991, 1992  Linus Torvalds
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci/*
962306a36Sopenharmony_ci * Some corrections by tytso.
1062306a36Sopenharmony_ci */
1162306a36Sopenharmony_ci
1262306a36Sopenharmony_ci/* [Feb 1997 T. Schoebel-Theuer] Complete rewrite of the pathname
1362306a36Sopenharmony_ci * lookup logic.
1462306a36Sopenharmony_ci */
1562306a36Sopenharmony_ci/* [Feb-Apr 2000, AV] Rewrite to the new namespace architecture.
1662306a36Sopenharmony_ci */
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include <linux/init.h>
1962306a36Sopenharmony_ci#include <linux/export.h>
2062306a36Sopenharmony_ci#include <linux/kernel.h>
2162306a36Sopenharmony_ci#include <linux/slab.h>
2262306a36Sopenharmony_ci#include <linux/fs.h>
2362306a36Sopenharmony_ci#include <linux/filelock.h>
2462306a36Sopenharmony_ci#include <linux/namei.h>
2562306a36Sopenharmony_ci#include <linux/pagemap.h>
2662306a36Sopenharmony_ci#include <linux/sched/mm.h>
2762306a36Sopenharmony_ci#include <linux/fsnotify.h>
2862306a36Sopenharmony_ci#include <linux/personality.h>
2962306a36Sopenharmony_ci#include <linux/security.h>
3062306a36Sopenharmony_ci#include <linux/ima.h>
3162306a36Sopenharmony_ci#include <linux/syscalls.h>
3262306a36Sopenharmony_ci#include <linux/mount.h>
3362306a36Sopenharmony_ci#include <linux/audit.h>
3462306a36Sopenharmony_ci#include <linux/capability.h>
3562306a36Sopenharmony_ci#include <linux/file.h>
3662306a36Sopenharmony_ci#include <linux/fcntl.h>
3762306a36Sopenharmony_ci#include <linux/device_cgroup.h>
3862306a36Sopenharmony_ci#include <linux/fs_struct.h>
3962306a36Sopenharmony_ci#include <linux/posix_acl.h>
4062306a36Sopenharmony_ci#include <linux/hash.h>
4162306a36Sopenharmony_ci#include <linux/bitops.h>
4262306a36Sopenharmony_ci#include <linux/init_task.h>
4362306a36Sopenharmony_ci#include <linux/uaccess.h>
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#include "internal.h"
4662306a36Sopenharmony_ci#include "mount.h"
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/* [Feb-1997 T. Schoebel-Theuer]
4962306a36Sopenharmony_ci * Fundamental changes in the pathname lookup mechanisms (namei)
5062306a36Sopenharmony_ci * were necessary because of omirr.  The reason is that omirr needs
5162306a36Sopenharmony_ci * to know the _real_ pathname, not the user-supplied one, in case
5262306a36Sopenharmony_ci * of symlinks (and also when transname replacements occur).
5362306a36Sopenharmony_ci *
5462306a36Sopenharmony_ci * The new code replaces the old recursive symlink resolution with
5562306a36Sopenharmony_ci * an iterative one (in case of non-nested symlink chains).  It does
5662306a36Sopenharmony_ci * this with calls to <fs>_follow_link().
5762306a36Sopenharmony_ci * As a side effect, dir_namei(), _namei() and follow_link() are now
5862306a36Sopenharmony_ci * replaced with a single function lookup_dentry() that can handle all
5962306a36Sopenharmony_ci * the special cases of the former code.
6062306a36Sopenharmony_ci *
6162306a36Sopenharmony_ci * With the new dcache, the pathname is stored at each inode, at least as
6262306a36Sopenharmony_ci * long as the refcount of the inode is positive.  As a side effect, the
6362306a36Sopenharmony_ci * size of the dcache depends on the inode cache and thus is dynamic.
6462306a36Sopenharmony_ci *
6562306a36Sopenharmony_ci * [29-Apr-1998 C. Scott Ananian] Updated above description of symlink
6662306a36Sopenharmony_ci * resolution to correspond with current state of the code.
6762306a36Sopenharmony_ci *
6862306a36Sopenharmony_ci * Note that the symlink resolution is not *completely* iterative.
6962306a36Sopenharmony_ci * There is still a significant amount of tail- and mid- recursion in
7062306a36Sopenharmony_ci * the algorithm.  Also, note that <fs>_readlink() is not used in
7162306a36Sopenharmony_ci * lookup_dentry(): lookup_dentry() on the result of <fs>_readlink()
7262306a36Sopenharmony_ci * may return different results than <fs>_follow_link().  Many virtual
7362306a36Sopenharmony_ci * filesystems (including /proc) exhibit this behavior.
7462306a36Sopenharmony_ci */
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/* [24-Feb-97 T. Schoebel-Theuer] Side effects caused by new implementation:
7762306a36Sopenharmony_ci * New symlink semantics: when open() is called with flags O_CREAT | O_EXCL
7862306a36Sopenharmony_ci * and the name already exists in form of a symlink, try to create the new
7962306a36Sopenharmony_ci * name indicated by the symlink. The old code always complained that the
8062306a36Sopenharmony_ci * name already exists, due to not following the symlink even if its target
8162306a36Sopenharmony_ci * is nonexistent.  The new semantics affects also mknod() and link() when
8262306a36Sopenharmony_ci * the name is a symlink pointing to a non-existent name.
8362306a36Sopenharmony_ci *
8462306a36Sopenharmony_ci * I don't know which semantics is the right one, since I have no access
8562306a36Sopenharmony_ci * to standards. But I found by trial that HP-UX 9.0 has the full "new"
8662306a36Sopenharmony_ci * semantics implemented, while SunOS 4.1.1 and Solaris (SunOS 5.4) have the
8762306a36Sopenharmony_ci * "old" one. Personally, I think the new semantics is much more logical.
8862306a36Sopenharmony_ci * Note that "ln old new" where "new" is a symlink pointing to a non-existing
8962306a36Sopenharmony_ci * file does succeed in both HP-UX and SunOs, but not in Solaris
9062306a36Sopenharmony_ci * and in the old Linux semantics.
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_ci/* [16-Dec-97 Kevin Buhr] For security reasons, we change some symlink
9462306a36Sopenharmony_ci * semantics.  See the comments in "open_namei" and "do_link" below.
9562306a36Sopenharmony_ci *
9662306a36Sopenharmony_ci * [10-Sep-98 Alan Modra] Another symlink change.
9762306a36Sopenharmony_ci */
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci/* [Feb-Apr 2000 AV] Complete rewrite. Rules for symlinks:
10062306a36Sopenharmony_ci *	inside the path - always follow.
10162306a36Sopenharmony_ci *	in the last component in creation/removal/renaming - never follow.
10262306a36Sopenharmony_ci *	if LOOKUP_FOLLOW passed - follow.
10362306a36Sopenharmony_ci *	if the pathname has trailing slashes - follow.
10462306a36Sopenharmony_ci *	otherwise - don't follow.
10562306a36Sopenharmony_ci * (applied in that order).
10662306a36Sopenharmony_ci *
10762306a36Sopenharmony_ci * [Jun 2000 AV] Inconsistent behaviour of open() in case if flags==O_CREAT
10862306a36Sopenharmony_ci * restored for 2.4. This is the last surviving part of old 4.2BSD bug.
10962306a36Sopenharmony_ci * During the 2.4 we need to fix the userland stuff depending on it -
11062306a36Sopenharmony_ci * hopefully we will be able to get rid of that wart in 2.5. So far only
11162306a36Sopenharmony_ci * XEmacs seems to be relying on it...
11262306a36Sopenharmony_ci */
11362306a36Sopenharmony_ci/*
11462306a36Sopenharmony_ci * [Sep 2001 AV] Single-semaphore locking scheme (kudos to David Holland)
11562306a36Sopenharmony_ci * implemented.  Let's see if raised priority of ->s_vfs_rename_mutex gives
11662306a36Sopenharmony_ci * any extra contention...
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci/* In order to reduce some races, while at the same time doing additional
12062306a36Sopenharmony_ci * checking and hopefully speeding things up, we copy filenames to the
12162306a36Sopenharmony_ci * kernel data space before using them..
12262306a36Sopenharmony_ci *
12362306a36Sopenharmony_ci * POSIX.1 2.4: an empty pathname is invalid (ENOENT).
12462306a36Sopenharmony_ci * PATH_MAX includes the nul terminator --RR.
12562306a36Sopenharmony_ci */
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#define EMBEDDED_NAME_MAX	(PATH_MAX - offsetof(struct filename, iname))
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cistruct filename *
13062306a36Sopenharmony_cigetname_flags(const char __user *filename, int flags, int *empty)
13162306a36Sopenharmony_ci{
13262306a36Sopenharmony_ci	struct filename *result;
13362306a36Sopenharmony_ci	char *kname;
13462306a36Sopenharmony_ci	int len;
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci	result = audit_reusename(filename);
13762306a36Sopenharmony_ci	if (result)
13862306a36Sopenharmony_ci		return result;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	result = __getname();
14162306a36Sopenharmony_ci	if (unlikely(!result))
14262306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	/*
14562306a36Sopenharmony_ci	 * First, try to embed the struct filename inside the names_cache
14662306a36Sopenharmony_ci	 * allocation
14762306a36Sopenharmony_ci	 */
14862306a36Sopenharmony_ci	kname = (char *)result->iname;
14962306a36Sopenharmony_ci	result->name = kname;
15062306a36Sopenharmony_ci
15162306a36Sopenharmony_ci	len = strncpy_from_user(kname, filename, EMBEDDED_NAME_MAX);
15262306a36Sopenharmony_ci	if (unlikely(len < 0)) {
15362306a36Sopenharmony_ci		__putname(result);
15462306a36Sopenharmony_ci		return ERR_PTR(len);
15562306a36Sopenharmony_ci	}
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci	/*
15862306a36Sopenharmony_ci	 * Uh-oh. We have a name that's approaching PATH_MAX. Allocate a
15962306a36Sopenharmony_ci	 * separate struct filename so we can dedicate the entire
16062306a36Sopenharmony_ci	 * names_cache allocation for the pathname, and re-do the copy from
16162306a36Sopenharmony_ci	 * userland.
16262306a36Sopenharmony_ci	 */
16362306a36Sopenharmony_ci	if (unlikely(len == EMBEDDED_NAME_MAX)) {
16462306a36Sopenharmony_ci		const size_t size = offsetof(struct filename, iname[1]);
16562306a36Sopenharmony_ci		kname = (char *)result;
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		/*
16862306a36Sopenharmony_ci		 * size is chosen that way we to guarantee that
16962306a36Sopenharmony_ci		 * result->iname[0] is within the same object and that
17062306a36Sopenharmony_ci		 * kname can't be equal to result->iname, no matter what.
17162306a36Sopenharmony_ci		 */
17262306a36Sopenharmony_ci		result = kzalloc(size, GFP_KERNEL);
17362306a36Sopenharmony_ci		if (unlikely(!result)) {
17462306a36Sopenharmony_ci			__putname(kname);
17562306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
17662306a36Sopenharmony_ci		}
17762306a36Sopenharmony_ci		result->name = kname;
17862306a36Sopenharmony_ci		len = strncpy_from_user(kname, filename, PATH_MAX);
17962306a36Sopenharmony_ci		if (unlikely(len < 0)) {
18062306a36Sopenharmony_ci			__putname(kname);
18162306a36Sopenharmony_ci			kfree(result);
18262306a36Sopenharmony_ci			return ERR_PTR(len);
18362306a36Sopenharmony_ci		}
18462306a36Sopenharmony_ci		if (unlikely(len == PATH_MAX)) {
18562306a36Sopenharmony_ci			__putname(kname);
18662306a36Sopenharmony_ci			kfree(result);
18762306a36Sopenharmony_ci			return ERR_PTR(-ENAMETOOLONG);
18862306a36Sopenharmony_ci		}
18962306a36Sopenharmony_ci	}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	atomic_set(&result->refcnt, 1);
19262306a36Sopenharmony_ci	/* The empty path is special. */
19362306a36Sopenharmony_ci	if (unlikely(!len)) {
19462306a36Sopenharmony_ci		if (empty)
19562306a36Sopenharmony_ci			*empty = 1;
19662306a36Sopenharmony_ci		if (!(flags & LOOKUP_EMPTY)) {
19762306a36Sopenharmony_ci			putname(result);
19862306a36Sopenharmony_ci			return ERR_PTR(-ENOENT);
19962306a36Sopenharmony_ci		}
20062306a36Sopenharmony_ci	}
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci	result->uptr = filename;
20362306a36Sopenharmony_ci	result->aname = NULL;
20462306a36Sopenharmony_ci	audit_getname(result);
20562306a36Sopenharmony_ci	return result;
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistruct filename *
20962306a36Sopenharmony_cigetname_uflags(const char __user *filename, int uflags)
21062306a36Sopenharmony_ci{
21162306a36Sopenharmony_ci	int flags = (uflags & AT_EMPTY_PATH) ? LOOKUP_EMPTY : 0;
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	return getname_flags(filename, flags, NULL);
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistruct filename *
21762306a36Sopenharmony_cigetname(const char __user * filename)
21862306a36Sopenharmony_ci{
21962306a36Sopenharmony_ci	return getname_flags(filename, 0, NULL);
22062306a36Sopenharmony_ci}
22162306a36Sopenharmony_ci
22262306a36Sopenharmony_cistruct filename *
22362306a36Sopenharmony_cigetname_kernel(const char * filename)
22462306a36Sopenharmony_ci{
22562306a36Sopenharmony_ci	struct filename *result;
22662306a36Sopenharmony_ci	int len = strlen(filename) + 1;
22762306a36Sopenharmony_ci
22862306a36Sopenharmony_ci	result = __getname();
22962306a36Sopenharmony_ci	if (unlikely(!result))
23062306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	if (len <= EMBEDDED_NAME_MAX) {
23362306a36Sopenharmony_ci		result->name = (char *)result->iname;
23462306a36Sopenharmony_ci	} else if (len <= PATH_MAX) {
23562306a36Sopenharmony_ci		const size_t size = offsetof(struct filename, iname[1]);
23662306a36Sopenharmony_ci		struct filename *tmp;
23762306a36Sopenharmony_ci
23862306a36Sopenharmony_ci		tmp = kmalloc(size, GFP_KERNEL);
23962306a36Sopenharmony_ci		if (unlikely(!tmp)) {
24062306a36Sopenharmony_ci			__putname(result);
24162306a36Sopenharmony_ci			return ERR_PTR(-ENOMEM);
24262306a36Sopenharmony_ci		}
24362306a36Sopenharmony_ci		tmp->name = (char *)result;
24462306a36Sopenharmony_ci		result = tmp;
24562306a36Sopenharmony_ci	} else {
24662306a36Sopenharmony_ci		__putname(result);
24762306a36Sopenharmony_ci		return ERR_PTR(-ENAMETOOLONG);
24862306a36Sopenharmony_ci	}
24962306a36Sopenharmony_ci	memcpy((char *)result->name, filename, len);
25062306a36Sopenharmony_ci	result->uptr = NULL;
25162306a36Sopenharmony_ci	result->aname = NULL;
25262306a36Sopenharmony_ci	atomic_set(&result->refcnt, 1);
25362306a36Sopenharmony_ci	audit_getname(result);
25462306a36Sopenharmony_ci
25562306a36Sopenharmony_ci	return result;
25662306a36Sopenharmony_ci}
25762306a36Sopenharmony_ciEXPORT_SYMBOL(getname_kernel);
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_civoid putname(struct filename *name)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	if (IS_ERR(name))
26262306a36Sopenharmony_ci		return;
26362306a36Sopenharmony_ci
26462306a36Sopenharmony_ci	if (WARN_ON_ONCE(!atomic_read(&name->refcnt)))
26562306a36Sopenharmony_ci		return;
26662306a36Sopenharmony_ci
26762306a36Sopenharmony_ci	if (!atomic_dec_and_test(&name->refcnt))
26862306a36Sopenharmony_ci		return;
26962306a36Sopenharmony_ci
27062306a36Sopenharmony_ci	if (name->name != name->iname) {
27162306a36Sopenharmony_ci		__putname(name->name);
27262306a36Sopenharmony_ci		kfree(name);
27362306a36Sopenharmony_ci	} else
27462306a36Sopenharmony_ci		__putname(name);
27562306a36Sopenharmony_ci}
27662306a36Sopenharmony_ciEXPORT_SYMBOL(putname);
27762306a36Sopenharmony_ci
27862306a36Sopenharmony_ci/**
27962306a36Sopenharmony_ci * check_acl - perform ACL permission checking
28062306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
28162306a36Sopenharmony_ci * @inode:	inode to check permissions on
28262306a36Sopenharmony_ci * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC ...)
28362306a36Sopenharmony_ci *
28462306a36Sopenharmony_ci * This function performs the ACL permission checking. Since this function
28562306a36Sopenharmony_ci * retrieve POSIX acls it needs to know whether it is called from a blocking or
28662306a36Sopenharmony_ci * non-blocking context and thus cares about the MAY_NOT_BLOCK bit.
28762306a36Sopenharmony_ci *
28862306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
28962306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
29062306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
29162306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
29262306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
29362306a36Sopenharmony_ci */
29462306a36Sopenharmony_cistatic int check_acl(struct mnt_idmap *idmap,
29562306a36Sopenharmony_ci		     struct inode *inode, int mask)
29662306a36Sopenharmony_ci{
29762306a36Sopenharmony_ci#ifdef CONFIG_FS_POSIX_ACL
29862306a36Sopenharmony_ci	struct posix_acl *acl;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	if (mask & MAY_NOT_BLOCK) {
30162306a36Sopenharmony_ci		acl = get_cached_acl_rcu(inode, ACL_TYPE_ACCESS);
30262306a36Sopenharmony_ci	        if (!acl)
30362306a36Sopenharmony_ci	                return -EAGAIN;
30462306a36Sopenharmony_ci		/* no ->get_inode_acl() calls in RCU mode... */
30562306a36Sopenharmony_ci		if (is_uncached_acl(acl))
30662306a36Sopenharmony_ci			return -ECHILD;
30762306a36Sopenharmony_ci	        return posix_acl_permission(idmap, inode, acl, mask);
30862306a36Sopenharmony_ci	}
30962306a36Sopenharmony_ci
31062306a36Sopenharmony_ci	acl = get_inode_acl(inode, ACL_TYPE_ACCESS);
31162306a36Sopenharmony_ci	if (IS_ERR(acl))
31262306a36Sopenharmony_ci		return PTR_ERR(acl);
31362306a36Sopenharmony_ci	if (acl) {
31462306a36Sopenharmony_ci	        int error = posix_acl_permission(idmap, inode, acl, mask);
31562306a36Sopenharmony_ci	        posix_acl_release(acl);
31662306a36Sopenharmony_ci	        return error;
31762306a36Sopenharmony_ci	}
31862306a36Sopenharmony_ci#endif
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	return -EAGAIN;
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci/**
32462306a36Sopenharmony_ci * acl_permission_check - perform basic UNIX permission checking
32562306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
32662306a36Sopenharmony_ci * @inode:	inode to check permissions on
32762306a36Sopenharmony_ci * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC ...)
32862306a36Sopenharmony_ci *
32962306a36Sopenharmony_ci * This function performs the basic UNIX permission checking. Since this
33062306a36Sopenharmony_ci * function may retrieve POSIX acls it needs to know whether it is called from a
33162306a36Sopenharmony_ci * blocking or non-blocking context and thus cares about the MAY_NOT_BLOCK bit.
33262306a36Sopenharmony_ci *
33362306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
33462306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
33562306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
33662306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
33762306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
33862306a36Sopenharmony_ci */
33962306a36Sopenharmony_cistatic int acl_permission_check(struct mnt_idmap *idmap,
34062306a36Sopenharmony_ci				struct inode *inode, int mask)
34162306a36Sopenharmony_ci{
34262306a36Sopenharmony_ci	unsigned int mode = inode->i_mode;
34362306a36Sopenharmony_ci	vfsuid_t vfsuid;
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	/* Are we the owner? If so, ACL's don't matter */
34662306a36Sopenharmony_ci	vfsuid = i_uid_into_vfsuid(idmap, inode);
34762306a36Sopenharmony_ci	if (likely(vfsuid_eq_kuid(vfsuid, current_fsuid()))) {
34862306a36Sopenharmony_ci		mask &= 7;
34962306a36Sopenharmony_ci		mode >>= 6;
35062306a36Sopenharmony_ci		return (mask & ~mode) ? -EACCES : 0;
35162306a36Sopenharmony_ci	}
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	/* Do we have ACL's? */
35462306a36Sopenharmony_ci	if (IS_POSIXACL(inode) && (mode & S_IRWXG)) {
35562306a36Sopenharmony_ci		int error = check_acl(idmap, inode, mask);
35662306a36Sopenharmony_ci		if (error != -EAGAIN)
35762306a36Sopenharmony_ci			return error;
35862306a36Sopenharmony_ci	}
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	/* Only RWX matters for group/other mode bits */
36162306a36Sopenharmony_ci	mask &= 7;
36262306a36Sopenharmony_ci
36362306a36Sopenharmony_ci	/*
36462306a36Sopenharmony_ci	 * Are the group permissions different from
36562306a36Sopenharmony_ci	 * the other permissions in the bits we care
36662306a36Sopenharmony_ci	 * about? Need to check group ownership if so.
36762306a36Sopenharmony_ci	 */
36862306a36Sopenharmony_ci	if (mask & (mode ^ (mode >> 3))) {
36962306a36Sopenharmony_ci		vfsgid_t vfsgid = i_gid_into_vfsgid(idmap, inode);
37062306a36Sopenharmony_ci		if (vfsgid_in_group_p(vfsgid))
37162306a36Sopenharmony_ci			mode >>= 3;
37262306a36Sopenharmony_ci	}
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	/* Bits in 'mode' clear that we require? */
37562306a36Sopenharmony_ci	return (mask & ~mode) ? -EACCES : 0;
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_ci/**
37962306a36Sopenharmony_ci * generic_permission -  check for access rights on a Posix-like filesystem
38062306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
38162306a36Sopenharmony_ci * @inode:	inode to check access rights for
38262306a36Sopenharmony_ci * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC,
38362306a36Sopenharmony_ci *		%MAY_NOT_BLOCK ...)
38462306a36Sopenharmony_ci *
38562306a36Sopenharmony_ci * Used to check for read/write/execute permissions on a file.
38662306a36Sopenharmony_ci * We use "fsuid" for this, letting us set arbitrary permissions
38762306a36Sopenharmony_ci * for filesystem access without changing the "normal" uids which
38862306a36Sopenharmony_ci * are used for other things.
38962306a36Sopenharmony_ci *
39062306a36Sopenharmony_ci * generic_permission is rcu-walk aware. It returns -ECHILD in case an rcu-walk
39162306a36Sopenharmony_ci * request cannot be satisfied (eg. requires blocking or too much complexity).
39262306a36Sopenharmony_ci * It would then be called again in ref-walk mode.
39362306a36Sopenharmony_ci *
39462306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
39562306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
39662306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
39762306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
39862306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
39962306a36Sopenharmony_ci */
40062306a36Sopenharmony_ciint generic_permission(struct mnt_idmap *idmap, struct inode *inode,
40162306a36Sopenharmony_ci		       int mask)
40262306a36Sopenharmony_ci{
40362306a36Sopenharmony_ci	int ret;
40462306a36Sopenharmony_ci
40562306a36Sopenharmony_ci	/*
40662306a36Sopenharmony_ci	 * Do the basic permission checks.
40762306a36Sopenharmony_ci	 */
40862306a36Sopenharmony_ci	ret = acl_permission_check(idmap, inode, mask);
40962306a36Sopenharmony_ci	if (ret != -EACCES)
41062306a36Sopenharmony_ci		return ret;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode)) {
41362306a36Sopenharmony_ci		/* DACs are overridable for directories */
41462306a36Sopenharmony_ci		if (!(mask & MAY_WRITE))
41562306a36Sopenharmony_ci			if (capable_wrt_inode_uidgid(idmap, inode,
41662306a36Sopenharmony_ci						     CAP_DAC_READ_SEARCH))
41762306a36Sopenharmony_ci				return 0;
41862306a36Sopenharmony_ci		if (capable_wrt_inode_uidgid(idmap, inode,
41962306a36Sopenharmony_ci					     CAP_DAC_OVERRIDE))
42062306a36Sopenharmony_ci			return 0;
42162306a36Sopenharmony_ci		return -EACCES;
42262306a36Sopenharmony_ci	}
42362306a36Sopenharmony_ci
42462306a36Sopenharmony_ci	/*
42562306a36Sopenharmony_ci	 * Searching includes executable on directories, else just read.
42662306a36Sopenharmony_ci	 */
42762306a36Sopenharmony_ci	mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
42862306a36Sopenharmony_ci	if (mask == MAY_READ)
42962306a36Sopenharmony_ci		if (capable_wrt_inode_uidgid(idmap, inode,
43062306a36Sopenharmony_ci					     CAP_DAC_READ_SEARCH))
43162306a36Sopenharmony_ci			return 0;
43262306a36Sopenharmony_ci	/*
43362306a36Sopenharmony_ci	 * Read/write DACs are always overridable.
43462306a36Sopenharmony_ci	 * Executable DACs are overridable when there is
43562306a36Sopenharmony_ci	 * at least one exec bit set.
43662306a36Sopenharmony_ci	 */
43762306a36Sopenharmony_ci	if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
43862306a36Sopenharmony_ci		if (capable_wrt_inode_uidgid(idmap, inode,
43962306a36Sopenharmony_ci					     CAP_DAC_OVERRIDE))
44062306a36Sopenharmony_ci			return 0;
44162306a36Sopenharmony_ci
44262306a36Sopenharmony_ci	return -EACCES;
44362306a36Sopenharmony_ci}
44462306a36Sopenharmony_ciEXPORT_SYMBOL(generic_permission);
44562306a36Sopenharmony_ci
44662306a36Sopenharmony_ci/**
44762306a36Sopenharmony_ci * do_inode_permission - UNIX permission checking
44862306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
44962306a36Sopenharmony_ci * @inode:	inode to check permissions on
45062306a36Sopenharmony_ci * @mask:	right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC ...)
45162306a36Sopenharmony_ci *
45262306a36Sopenharmony_ci * We _really_ want to just do "generic_permission()" without
45362306a36Sopenharmony_ci * even looking at the inode->i_op values. So we keep a cache
45462306a36Sopenharmony_ci * flag in inode->i_opflags, that says "this has not special
45562306a36Sopenharmony_ci * permission function, use the fast case".
45662306a36Sopenharmony_ci */
45762306a36Sopenharmony_cistatic inline int do_inode_permission(struct mnt_idmap *idmap,
45862306a36Sopenharmony_ci				      struct inode *inode, int mask)
45962306a36Sopenharmony_ci{
46062306a36Sopenharmony_ci	if (unlikely(!(inode->i_opflags & IOP_FASTPERM))) {
46162306a36Sopenharmony_ci		if (likely(inode->i_op->permission))
46262306a36Sopenharmony_ci			return inode->i_op->permission(idmap, inode, mask);
46362306a36Sopenharmony_ci
46462306a36Sopenharmony_ci		/* This gets set once for the inode lifetime */
46562306a36Sopenharmony_ci		spin_lock(&inode->i_lock);
46662306a36Sopenharmony_ci		inode->i_opflags |= IOP_FASTPERM;
46762306a36Sopenharmony_ci		spin_unlock(&inode->i_lock);
46862306a36Sopenharmony_ci	}
46962306a36Sopenharmony_ci	return generic_permission(idmap, inode, mask);
47062306a36Sopenharmony_ci}
47162306a36Sopenharmony_ci
47262306a36Sopenharmony_ci/**
47362306a36Sopenharmony_ci * sb_permission - Check superblock-level permissions
47462306a36Sopenharmony_ci * @sb: Superblock of inode to check permission on
47562306a36Sopenharmony_ci * @inode: Inode to check permission on
47662306a36Sopenharmony_ci * @mask: Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
47762306a36Sopenharmony_ci *
47862306a36Sopenharmony_ci * Separate out file-system wide checks from inode-specific permission checks.
47962306a36Sopenharmony_ci */
48062306a36Sopenharmony_cistatic int sb_permission(struct super_block *sb, struct inode *inode, int mask)
48162306a36Sopenharmony_ci{
48262306a36Sopenharmony_ci	if (unlikely(mask & MAY_WRITE)) {
48362306a36Sopenharmony_ci		umode_t mode = inode->i_mode;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci		/* Nobody gets write access to a read-only fs. */
48662306a36Sopenharmony_ci		if (sb_rdonly(sb) && (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)))
48762306a36Sopenharmony_ci			return -EROFS;
48862306a36Sopenharmony_ci	}
48962306a36Sopenharmony_ci	return 0;
49062306a36Sopenharmony_ci}
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci/**
49362306a36Sopenharmony_ci * inode_permission - Check for access rights to a given inode
49462306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
49562306a36Sopenharmony_ci * @inode:	Inode to check permission on
49662306a36Sopenharmony_ci * @mask:	Right to check for (%MAY_READ, %MAY_WRITE, %MAY_EXEC)
49762306a36Sopenharmony_ci *
49862306a36Sopenharmony_ci * Check for read/write/execute permissions on an inode.  We use fs[ug]id for
49962306a36Sopenharmony_ci * this, letting us set arbitrary permissions for filesystem access without
50062306a36Sopenharmony_ci * changing the "normal" UIDs which are used for other things.
50162306a36Sopenharmony_ci *
50262306a36Sopenharmony_ci * When checking for MAY_APPEND, MAY_WRITE must also be set in @mask.
50362306a36Sopenharmony_ci */
50462306a36Sopenharmony_ciint inode_permission(struct mnt_idmap *idmap,
50562306a36Sopenharmony_ci		     struct inode *inode, int mask)
50662306a36Sopenharmony_ci{
50762306a36Sopenharmony_ci	int retval;
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ci	retval = sb_permission(inode->i_sb, inode, mask);
51062306a36Sopenharmony_ci	if (retval)
51162306a36Sopenharmony_ci		return retval;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	if (unlikely(mask & MAY_WRITE)) {
51462306a36Sopenharmony_ci		/*
51562306a36Sopenharmony_ci		 * Nobody gets write access to an immutable file.
51662306a36Sopenharmony_ci		 */
51762306a36Sopenharmony_ci		if (IS_IMMUTABLE(inode))
51862306a36Sopenharmony_ci			return -EPERM;
51962306a36Sopenharmony_ci
52062306a36Sopenharmony_ci		/*
52162306a36Sopenharmony_ci		 * Updating mtime will likely cause i_uid and i_gid to be
52262306a36Sopenharmony_ci		 * written back improperly if their true value is unknown
52362306a36Sopenharmony_ci		 * to the vfs.
52462306a36Sopenharmony_ci		 */
52562306a36Sopenharmony_ci		if (HAS_UNMAPPED_ID(idmap, inode))
52662306a36Sopenharmony_ci			return -EACCES;
52762306a36Sopenharmony_ci	}
52862306a36Sopenharmony_ci
52962306a36Sopenharmony_ci	retval = do_inode_permission(idmap, inode, mask);
53062306a36Sopenharmony_ci	if (retval)
53162306a36Sopenharmony_ci		return retval;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	retval = devcgroup_inode_permission(inode, mask);
53462306a36Sopenharmony_ci	if (retval)
53562306a36Sopenharmony_ci		return retval;
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	return security_inode_permission(inode, mask);
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ciEXPORT_SYMBOL(inode_permission);
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci/**
54262306a36Sopenharmony_ci * path_get - get a reference to a path
54362306a36Sopenharmony_ci * @path: path to get the reference to
54462306a36Sopenharmony_ci *
54562306a36Sopenharmony_ci * Given a path increment the reference count to the dentry and the vfsmount.
54662306a36Sopenharmony_ci */
54762306a36Sopenharmony_civoid path_get(const struct path *path)
54862306a36Sopenharmony_ci{
54962306a36Sopenharmony_ci	mntget(path->mnt);
55062306a36Sopenharmony_ci	dget(path->dentry);
55162306a36Sopenharmony_ci}
55262306a36Sopenharmony_ciEXPORT_SYMBOL(path_get);
55362306a36Sopenharmony_ci
55462306a36Sopenharmony_ci/**
55562306a36Sopenharmony_ci * path_put - put a reference to a path
55662306a36Sopenharmony_ci * @path: path to put the reference to
55762306a36Sopenharmony_ci *
55862306a36Sopenharmony_ci * Given a path decrement the reference count to the dentry and the vfsmount.
55962306a36Sopenharmony_ci */
56062306a36Sopenharmony_civoid path_put(const struct path *path)
56162306a36Sopenharmony_ci{
56262306a36Sopenharmony_ci	dput(path->dentry);
56362306a36Sopenharmony_ci	mntput(path->mnt);
56462306a36Sopenharmony_ci}
56562306a36Sopenharmony_ciEXPORT_SYMBOL(path_put);
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci#define EMBEDDED_LEVELS 2
56862306a36Sopenharmony_cistruct nameidata {
56962306a36Sopenharmony_ci	struct path	path;
57062306a36Sopenharmony_ci	struct qstr	last;
57162306a36Sopenharmony_ci	struct path	root;
57262306a36Sopenharmony_ci	struct inode	*inode; /* path.dentry.d_inode */
57362306a36Sopenharmony_ci	unsigned int	flags, state;
57462306a36Sopenharmony_ci	unsigned	seq, next_seq, m_seq, r_seq;
57562306a36Sopenharmony_ci	int		last_type;
57662306a36Sopenharmony_ci	unsigned	depth;
57762306a36Sopenharmony_ci	int		total_link_count;
57862306a36Sopenharmony_ci	struct saved {
57962306a36Sopenharmony_ci		struct path link;
58062306a36Sopenharmony_ci		struct delayed_call done;
58162306a36Sopenharmony_ci		const char *name;
58262306a36Sopenharmony_ci		unsigned seq;
58362306a36Sopenharmony_ci	} *stack, internal[EMBEDDED_LEVELS];
58462306a36Sopenharmony_ci	struct filename	*name;
58562306a36Sopenharmony_ci	struct nameidata *saved;
58662306a36Sopenharmony_ci	unsigned	root_seq;
58762306a36Sopenharmony_ci	int		dfd;
58862306a36Sopenharmony_ci	vfsuid_t	dir_vfsuid;
58962306a36Sopenharmony_ci	umode_t		dir_mode;
59062306a36Sopenharmony_ci} __randomize_layout;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci#define ND_ROOT_PRESET 1
59362306a36Sopenharmony_ci#define ND_ROOT_GRABBED 2
59462306a36Sopenharmony_ci#define ND_JUMPED 4
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_cistatic void __set_nameidata(struct nameidata *p, int dfd, struct filename *name)
59762306a36Sopenharmony_ci{
59862306a36Sopenharmony_ci	struct nameidata *old = current->nameidata;
59962306a36Sopenharmony_ci	p->stack = p->internal;
60062306a36Sopenharmony_ci	p->depth = 0;
60162306a36Sopenharmony_ci	p->dfd = dfd;
60262306a36Sopenharmony_ci	p->name = name;
60362306a36Sopenharmony_ci	p->path.mnt = NULL;
60462306a36Sopenharmony_ci	p->path.dentry = NULL;
60562306a36Sopenharmony_ci	p->total_link_count = old ? old->total_link_count : 0;
60662306a36Sopenharmony_ci	p->saved = old;
60762306a36Sopenharmony_ci	current->nameidata = p;
60862306a36Sopenharmony_ci}
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_cistatic inline void set_nameidata(struct nameidata *p, int dfd, struct filename *name,
61162306a36Sopenharmony_ci			  const struct path *root)
61262306a36Sopenharmony_ci{
61362306a36Sopenharmony_ci	__set_nameidata(p, dfd, name);
61462306a36Sopenharmony_ci	p->state = 0;
61562306a36Sopenharmony_ci	if (unlikely(root)) {
61662306a36Sopenharmony_ci		p->state = ND_ROOT_PRESET;
61762306a36Sopenharmony_ci		p->root = *root;
61862306a36Sopenharmony_ci	}
61962306a36Sopenharmony_ci}
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_cistatic void restore_nameidata(void)
62262306a36Sopenharmony_ci{
62362306a36Sopenharmony_ci	struct nameidata *now = current->nameidata, *old = now->saved;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci	current->nameidata = old;
62662306a36Sopenharmony_ci	if (old)
62762306a36Sopenharmony_ci		old->total_link_count = now->total_link_count;
62862306a36Sopenharmony_ci	if (now->stack != now->internal)
62962306a36Sopenharmony_ci		kfree(now->stack);
63062306a36Sopenharmony_ci}
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_cistatic bool nd_alloc_stack(struct nameidata *nd)
63362306a36Sopenharmony_ci{
63462306a36Sopenharmony_ci	struct saved *p;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	p= kmalloc_array(MAXSYMLINKS, sizeof(struct saved),
63762306a36Sopenharmony_ci			 nd->flags & LOOKUP_RCU ? GFP_ATOMIC : GFP_KERNEL);
63862306a36Sopenharmony_ci	if (unlikely(!p))
63962306a36Sopenharmony_ci		return false;
64062306a36Sopenharmony_ci	memcpy(p, nd->internal, sizeof(nd->internal));
64162306a36Sopenharmony_ci	nd->stack = p;
64262306a36Sopenharmony_ci	return true;
64362306a36Sopenharmony_ci}
64462306a36Sopenharmony_ci
64562306a36Sopenharmony_ci/**
64662306a36Sopenharmony_ci * path_connected - Verify that a dentry is below mnt.mnt_root
64762306a36Sopenharmony_ci * @mnt: The mountpoint to check.
64862306a36Sopenharmony_ci * @dentry: The dentry to check.
64962306a36Sopenharmony_ci *
65062306a36Sopenharmony_ci * Rename can sometimes move a file or directory outside of a bind
65162306a36Sopenharmony_ci * mount, path_connected allows those cases to be detected.
65262306a36Sopenharmony_ci */
65362306a36Sopenharmony_cistatic bool path_connected(struct vfsmount *mnt, struct dentry *dentry)
65462306a36Sopenharmony_ci{
65562306a36Sopenharmony_ci	struct super_block *sb = mnt->mnt_sb;
65662306a36Sopenharmony_ci
65762306a36Sopenharmony_ci	/* Bind mounts can have disconnected paths */
65862306a36Sopenharmony_ci	if (mnt->mnt_root == sb->s_root)
65962306a36Sopenharmony_ci		return true;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	return is_subdir(dentry, mnt->mnt_root);
66262306a36Sopenharmony_ci}
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_cistatic void drop_links(struct nameidata *nd)
66562306a36Sopenharmony_ci{
66662306a36Sopenharmony_ci	int i = nd->depth;
66762306a36Sopenharmony_ci	while (i--) {
66862306a36Sopenharmony_ci		struct saved *last = nd->stack + i;
66962306a36Sopenharmony_ci		do_delayed_call(&last->done);
67062306a36Sopenharmony_ci		clear_delayed_call(&last->done);
67162306a36Sopenharmony_ci	}
67262306a36Sopenharmony_ci}
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_cistatic void leave_rcu(struct nameidata *nd)
67562306a36Sopenharmony_ci{
67662306a36Sopenharmony_ci	nd->flags &= ~LOOKUP_RCU;
67762306a36Sopenharmony_ci	nd->seq = nd->next_seq = 0;
67862306a36Sopenharmony_ci	rcu_read_unlock();
67962306a36Sopenharmony_ci}
68062306a36Sopenharmony_ci
68162306a36Sopenharmony_cistatic void terminate_walk(struct nameidata *nd)
68262306a36Sopenharmony_ci{
68362306a36Sopenharmony_ci	drop_links(nd);
68462306a36Sopenharmony_ci	if (!(nd->flags & LOOKUP_RCU)) {
68562306a36Sopenharmony_ci		int i;
68662306a36Sopenharmony_ci		path_put(&nd->path);
68762306a36Sopenharmony_ci		for (i = 0; i < nd->depth; i++)
68862306a36Sopenharmony_ci			path_put(&nd->stack[i].link);
68962306a36Sopenharmony_ci		if (nd->state & ND_ROOT_GRABBED) {
69062306a36Sopenharmony_ci			path_put(&nd->root);
69162306a36Sopenharmony_ci			nd->state &= ~ND_ROOT_GRABBED;
69262306a36Sopenharmony_ci		}
69362306a36Sopenharmony_ci	} else {
69462306a36Sopenharmony_ci		leave_rcu(nd);
69562306a36Sopenharmony_ci	}
69662306a36Sopenharmony_ci	nd->depth = 0;
69762306a36Sopenharmony_ci	nd->path.mnt = NULL;
69862306a36Sopenharmony_ci	nd->path.dentry = NULL;
69962306a36Sopenharmony_ci}
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci/* path_put is needed afterwards regardless of success or failure */
70262306a36Sopenharmony_cistatic bool __legitimize_path(struct path *path, unsigned seq, unsigned mseq)
70362306a36Sopenharmony_ci{
70462306a36Sopenharmony_ci	int res = __legitimize_mnt(path->mnt, mseq);
70562306a36Sopenharmony_ci	if (unlikely(res)) {
70662306a36Sopenharmony_ci		if (res > 0)
70762306a36Sopenharmony_ci			path->mnt = NULL;
70862306a36Sopenharmony_ci		path->dentry = NULL;
70962306a36Sopenharmony_ci		return false;
71062306a36Sopenharmony_ci	}
71162306a36Sopenharmony_ci	if (unlikely(!lockref_get_not_dead(&path->dentry->d_lockref))) {
71262306a36Sopenharmony_ci		path->dentry = NULL;
71362306a36Sopenharmony_ci		return false;
71462306a36Sopenharmony_ci	}
71562306a36Sopenharmony_ci	return !read_seqcount_retry(&path->dentry->d_seq, seq);
71662306a36Sopenharmony_ci}
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_cistatic inline bool legitimize_path(struct nameidata *nd,
71962306a36Sopenharmony_ci			    struct path *path, unsigned seq)
72062306a36Sopenharmony_ci{
72162306a36Sopenharmony_ci	return __legitimize_path(path, seq, nd->m_seq);
72262306a36Sopenharmony_ci}
72362306a36Sopenharmony_ci
72462306a36Sopenharmony_cistatic bool legitimize_links(struct nameidata *nd)
72562306a36Sopenharmony_ci{
72662306a36Sopenharmony_ci	int i;
72762306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_CACHED)) {
72862306a36Sopenharmony_ci		drop_links(nd);
72962306a36Sopenharmony_ci		nd->depth = 0;
73062306a36Sopenharmony_ci		return false;
73162306a36Sopenharmony_ci	}
73262306a36Sopenharmony_ci	for (i = 0; i < nd->depth; i++) {
73362306a36Sopenharmony_ci		struct saved *last = nd->stack + i;
73462306a36Sopenharmony_ci		if (unlikely(!legitimize_path(nd, &last->link, last->seq))) {
73562306a36Sopenharmony_ci			drop_links(nd);
73662306a36Sopenharmony_ci			nd->depth = i + 1;
73762306a36Sopenharmony_ci			return false;
73862306a36Sopenharmony_ci		}
73962306a36Sopenharmony_ci	}
74062306a36Sopenharmony_ci	return true;
74162306a36Sopenharmony_ci}
74262306a36Sopenharmony_ci
74362306a36Sopenharmony_cistatic bool legitimize_root(struct nameidata *nd)
74462306a36Sopenharmony_ci{
74562306a36Sopenharmony_ci	/* Nothing to do if nd->root is zero or is managed by the VFS user. */
74662306a36Sopenharmony_ci	if (!nd->root.mnt || (nd->state & ND_ROOT_PRESET))
74762306a36Sopenharmony_ci		return true;
74862306a36Sopenharmony_ci	nd->state |= ND_ROOT_GRABBED;
74962306a36Sopenharmony_ci	return legitimize_path(nd, &nd->root, nd->root_seq);
75062306a36Sopenharmony_ci}
75162306a36Sopenharmony_ci
75262306a36Sopenharmony_ci/*
75362306a36Sopenharmony_ci * Path walking has 2 modes, rcu-walk and ref-walk (see
75462306a36Sopenharmony_ci * Documentation/filesystems/path-lookup.txt).  In situations when we can't
75562306a36Sopenharmony_ci * continue in RCU mode, we attempt to drop out of rcu-walk mode and grab
75662306a36Sopenharmony_ci * normal reference counts on dentries and vfsmounts to transition to ref-walk
75762306a36Sopenharmony_ci * mode.  Refcounts are grabbed at the last known good point before rcu-walk
75862306a36Sopenharmony_ci * got stuck, so ref-walk may continue from there. If this is not successful
75962306a36Sopenharmony_ci * (eg. a seqcount has changed), then failure is returned and it's up to caller
76062306a36Sopenharmony_ci * to restart the path walk from the beginning in ref-walk mode.
76162306a36Sopenharmony_ci */
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci/**
76462306a36Sopenharmony_ci * try_to_unlazy - try to switch to ref-walk mode.
76562306a36Sopenharmony_ci * @nd: nameidata pathwalk data
76662306a36Sopenharmony_ci * Returns: true on success, false on failure
76762306a36Sopenharmony_ci *
76862306a36Sopenharmony_ci * try_to_unlazy attempts to legitimize the current nd->path and nd->root
76962306a36Sopenharmony_ci * for ref-walk mode.
77062306a36Sopenharmony_ci * Must be called from rcu-walk context.
77162306a36Sopenharmony_ci * Nothing should touch nameidata between try_to_unlazy() failure and
77262306a36Sopenharmony_ci * terminate_walk().
77362306a36Sopenharmony_ci */
77462306a36Sopenharmony_cistatic bool try_to_unlazy(struct nameidata *nd)
77562306a36Sopenharmony_ci{
77662306a36Sopenharmony_ci	struct dentry *parent = nd->path.dentry;
77762306a36Sopenharmony_ci
77862306a36Sopenharmony_ci	BUG_ON(!(nd->flags & LOOKUP_RCU));
77962306a36Sopenharmony_ci
78062306a36Sopenharmony_ci	if (unlikely(!legitimize_links(nd)))
78162306a36Sopenharmony_ci		goto out1;
78262306a36Sopenharmony_ci	if (unlikely(!legitimize_path(nd, &nd->path, nd->seq)))
78362306a36Sopenharmony_ci		goto out;
78462306a36Sopenharmony_ci	if (unlikely(!legitimize_root(nd)))
78562306a36Sopenharmony_ci		goto out;
78662306a36Sopenharmony_ci	leave_rcu(nd);
78762306a36Sopenharmony_ci	BUG_ON(nd->inode != parent->d_inode);
78862306a36Sopenharmony_ci	return true;
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ciout1:
79162306a36Sopenharmony_ci	nd->path.mnt = NULL;
79262306a36Sopenharmony_ci	nd->path.dentry = NULL;
79362306a36Sopenharmony_ciout:
79462306a36Sopenharmony_ci	leave_rcu(nd);
79562306a36Sopenharmony_ci	return false;
79662306a36Sopenharmony_ci}
79762306a36Sopenharmony_ci
79862306a36Sopenharmony_ci/**
79962306a36Sopenharmony_ci * try_to_unlazy_next - try to switch to ref-walk mode.
80062306a36Sopenharmony_ci * @nd: nameidata pathwalk data
80162306a36Sopenharmony_ci * @dentry: next dentry to step into
80262306a36Sopenharmony_ci * Returns: true on success, false on failure
80362306a36Sopenharmony_ci *
80462306a36Sopenharmony_ci * Similar to try_to_unlazy(), but here we have the next dentry already
80562306a36Sopenharmony_ci * picked by rcu-walk and want to legitimize that in addition to the current
80662306a36Sopenharmony_ci * nd->path and nd->root for ref-walk mode.  Must be called from rcu-walk context.
80762306a36Sopenharmony_ci * Nothing should touch nameidata between try_to_unlazy_next() failure and
80862306a36Sopenharmony_ci * terminate_walk().
80962306a36Sopenharmony_ci */
81062306a36Sopenharmony_cistatic bool try_to_unlazy_next(struct nameidata *nd, struct dentry *dentry)
81162306a36Sopenharmony_ci{
81262306a36Sopenharmony_ci	int res;
81362306a36Sopenharmony_ci	BUG_ON(!(nd->flags & LOOKUP_RCU));
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_ci	if (unlikely(!legitimize_links(nd)))
81662306a36Sopenharmony_ci		goto out2;
81762306a36Sopenharmony_ci	res = __legitimize_mnt(nd->path.mnt, nd->m_seq);
81862306a36Sopenharmony_ci	if (unlikely(res)) {
81962306a36Sopenharmony_ci		if (res > 0)
82062306a36Sopenharmony_ci			goto out2;
82162306a36Sopenharmony_ci		goto out1;
82262306a36Sopenharmony_ci	}
82362306a36Sopenharmony_ci	if (unlikely(!lockref_get_not_dead(&nd->path.dentry->d_lockref)))
82462306a36Sopenharmony_ci		goto out1;
82562306a36Sopenharmony_ci
82662306a36Sopenharmony_ci	/*
82762306a36Sopenharmony_ci	 * We need to move both the parent and the dentry from the RCU domain
82862306a36Sopenharmony_ci	 * to be properly refcounted. And the sequence number in the dentry
82962306a36Sopenharmony_ci	 * validates *both* dentry counters, since we checked the sequence
83062306a36Sopenharmony_ci	 * number of the parent after we got the child sequence number. So we
83162306a36Sopenharmony_ci	 * know the parent must still be valid if the child sequence number is
83262306a36Sopenharmony_ci	 */
83362306a36Sopenharmony_ci	if (unlikely(!lockref_get_not_dead(&dentry->d_lockref)))
83462306a36Sopenharmony_ci		goto out;
83562306a36Sopenharmony_ci	if (read_seqcount_retry(&dentry->d_seq, nd->next_seq))
83662306a36Sopenharmony_ci		goto out_dput;
83762306a36Sopenharmony_ci	/*
83862306a36Sopenharmony_ci	 * Sequence counts matched. Now make sure that the root is
83962306a36Sopenharmony_ci	 * still valid and get it if required.
84062306a36Sopenharmony_ci	 */
84162306a36Sopenharmony_ci	if (unlikely(!legitimize_root(nd)))
84262306a36Sopenharmony_ci		goto out_dput;
84362306a36Sopenharmony_ci	leave_rcu(nd);
84462306a36Sopenharmony_ci	return true;
84562306a36Sopenharmony_ci
84662306a36Sopenharmony_ciout2:
84762306a36Sopenharmony_ci	nd->path.mnt = NULL;
84862306a36Sopenharmony_ciout1:
84962306a36Sopenharmony_ci	nd->path.dentry = NULL;
85062306a36Sopenharmony_ciout:
85162306a36Sopenharmony_ci	leave_rcu(nd);
85262306a36Sopenharmony_ci	return false;
85362306a36Sopenharmony_ciout_dput:
85462306a36Sopenharmony_ci	leave_rcu(nd);
85562306a36Sopenharmony_ci	dput(dentry);
85662306a36Sopenharmony_ci	return false;
85762306a36Sopenharmony_ci}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_cistatic inline int d_revalidate(struct dentry *dentry, unsigned int flags)
86062306a36Sopenharmony_ci{
86162306a36Sopenharmony_ci	if (unlikely(dentry->d_flags & DCACHE_OP_REVALIDATE))
86262306a36Sopenharmony_ci		return dentry->d_op->d_revalidate(dentry, flags);
86362306a36Sopenharmony_ci	else
86462306a36Sopenharmony_ci		return 1;
86562306a36Sopenharmony_ci}
86662306a36Sopenharmony_ci
86762306a36Sopenharmony_ci/**
86862306a36Sopenharmony_ci * complete_walk - successful completion of path walk
86962306a36Sopenharmony_ci * @nd:  pointer nameidata
87062306a36Sopenharmony_ci *
87162306a36Sopenharmony_ci * If we had been in RCU mode, drop out of it and legitimize nd->path.
87262306a36Sopenharmony_ci * Revalidate the final result, unless we'd already done that during
87362306a36Sopenharmony_ci * the path walk or the filesystem doesn't ask for it.  Return 0 on
87462306a36Sopenharmony_ci * success, -error on failure.  In case of failure caller does not
87562306a36Sopenharmony_ci * need to drop nd->path.
87662306a36Sopenharmony_ci */
87762306a36Sopenharmony_cistatic int complete_walk(struct nameidata *nd)
87862306a36Sopenharmony_ci{
87962306a36Sopenharmony_ci	struct dentry *dentry = nd->path.dentry;
88062306a36Sopenharmony_ci	int status;
88162306a36Sopenharmony_ci
88262306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
88362306a36Sopenharmony_ci		/*
88462306a36Sopenharmony_ci		 * We don't want to zero nd->root for scoped-lookups or
88562306a36Sopenharmony_ci		 * externally-managed nd->root.
88662306a36Sopenharmony_ci		 */
88762306a36Sopenharmony_ci		if (!(nd->state & ND_ROOT_PRESET))
88862306a36Sopenharmony_ci			if (!(nd->flags & LOOKUP_IS_SCOPED))
88962306a36Sopenharmony_ci				nd->root.mnt = NULL;
89062306a36Sopenharmony_ci		nd->flags &= ~LOOKUP_CACHED;
89162306a36Sopenharmony_ci		if (!try_to_unlazy(nd))
89262306a36Sopenharmony_ci			return -ECHILD;
89362306a36Sopenharmony_ci	}
89462306a36Sopenharmony_ci
89562306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_IS_SCOPED)) {
89662306a36Sopenharmony_ci		/*
89762306a36Sopenharmony_ci		 * While the guarantee of LOOKUP_IS_SCOPED is (roughly) "don't
89862306a36Sopenharmony_ci		 * ever step outside the root during lookup" and should already
89962306a36Sopenharmony_ci		 * be guaranteed by the rest of namei, we want to avoid a namei
90062306a36Sopenharmony_ci		 * BUG resulting in userspace being given a path that was not
90162306a36Sopenharmony_ci		 * scoped within the root at some point during the lookup.
90262306a36Sopenharmony_ci		 *
90362306a36Sopenharmony_ci		 * So, do a final sanity-check to make sure that in the
90462306a36Sopenharmony_ci		 * worst-case scenario (a complete bypass of LOOKUP_IS_SCOPED)
90562306a36Sopenharmony_ci		 * we won't silently return an fd completely outside of the
90662306a36Sopenharmony_ci		 * requested root to userspace.
90762306a36Sopenharmony_ci		 *
90862306a36Sopenharmony_ci		 * Userspace could move the path outside the root after this
90962306a36Sopenharmony_ci		 * check, but as discussed elsewhere this is not a concern (the
91062306a36Sopenharmony_ci		 * resolved file was inside the root at some point).
91162306a36Sopenharmony_ci		 */
91262306a36Sopenharmony_ci		if (!path_is_under(&nd->path, &nd->root))
91362306a36Sopenharmony_ci			return -EXDEV;
91462306a36Sopenharmony_ci	}
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci	if (likely(!(nd->state & ND_JUMPED)))
91762306a36Sopenharmony_ci		return 0;
91862306a36Sopenharmony_ci
91962306a36Sopenharmony_ci	if (likely(!(dentry->d_flags & DCACHE_OP_WEAK_REVALIDATE)))
92062306a36Sopenharmony_ci		return 0;
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	status = dentry->d_op->d_weak_revalidate(dentry, nd->flags);
92362306a36Sopenharmony_ci	if (status > 0)
92462306a36Sopenharmony_ci		return 0;
92562306a36Sopenharmony_ci
92662306a36Sopenharmony_ci	if (!status)
92762306a36Sopenharmony_ci		status = -ESTALE;
92862306a36Sopenharmony_ci
92962306a36Sopenharmony_ci	return status;
93062306a36Sopenharmony_ci}
93162306a36Sopenharmony_ci
93262306a36Sopenharmony_cistatic int set_root(struct nameidata *nd)
93362306a36Sopenharmony_ci{
93462306a36Sopenharmony_ci	struct fs_struct *fs = current->fs;
93562306a36Sopenharmony_ci
93662306a36Sopenharmony_ci	/*
93762306a36Sopenharmony_ci	 * Jumping to the real root in a scoped-lookup is a BUG in namei, but we
93862306a36Sopenharmony_ci	 * still have to ensure it doesn't happen because it will cause a breakout
93962306a36Sopenharmony_ci	 * from the dirfd.
94062306a36Sopenharmony_ci	 */
94162306a36Sopenharmony_ci	if (WARN_ON(nd->flags & LOOKUP_IS_SCOPED))
94262306a36Sopenharmony_ci		return -ENOTRECOVERABLE;
94362306a36Sopenharmony_ci
94462306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
94562306a36Sopenharmony_ci		unsigned seq;
94662306a36Sopenharmony_ci
94762306a36Sopenharmony_ci		do {
94862306a36Sopenharmony_ci			seq = read_seqcount_begin(&fs->seq);
94962306a36Sopenharmony_ci			nd->root = fs->root;
95062306a36Sopenharmony_ci			nd->root_seq = __read_seqcount_begin(&nd->root.dentry->d_seq);
95162306a36Sopenharmony_ci		} while (read_seqcount_retry(&fs->seq, seq));
95262306a36Sopenharmony_ci	} else {
95362306a36Sopenharmony_ci		get_fs_root(fs, &nd->root);
95462306a36Sopenharmony_ci		nd->state |= ND_ROOT_GRABBED;
95562306a36Sopenharmony_ci	}
95662306a36Sopenharmony_ci	return 0;
95762306a36Sopenharmony_ci}
95862306a36Sopenharmony_ci
95962306a36Sopenharmony_cistatic int nd_jump_root(struct nameidata *nd)
96062306a36Sopenharmony_ci{
96162306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_BENEATH))
96262306a36Sopenharmony_ci		return -EXDEV;
96362306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_NO_XDEV)) {
96462306a36Sopenharmony_ci		/* Absolute path arguments to path_init() are allowed. */
96562306a36Sopenharmony_ci		if (nd->path.mnt != NULL && nd->path.mnt != nd->root.mnt)
96662306a36Sopenharmony_ci			return -EXDEV;
96762306a36Sopenharmony_ci	}
96862306a36Sopenharmony_ci	if (!nd->root.mnt) {
96962306a36Sopenharmony_ci		int error = set_root(nd);
97062306a36Sopenharmony_ci		if (error)
97162306a36Sopenharmony_ci			return error;
97262306a36Sopenharmony_ci	}
97362306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
97462306a36Sopenharmony_ci		struct dentry *d;
97562306a36Sopenharmony_ci		nd->path = nd->root;
97662306a36Sopenharmony_ci		d = nd->path.dentry;
97762306a36Sopenharmony_ci		nd->inode = d->d_inode;
97862306a36Sopenharmony_ci		nd->seq = nd->root_seq;
97962306a36Sopenharmony_ci		if (read_seqcount_retry(&d->d_seq, nd->seq))
98062306a36Sopenharmony_ci			return -ECHILD;
98162306a36Sopenharmony_ci	} else {
98262306a36Sopenharmony_ci		path_put(&nd->path);
98362306a36Sopenharmony_ci		nd->path = nd->root;
98462306a36Sopenharmony_ci		path_get(&nd->path);
98562306a36Sopenharmony_ci		nd->inode = nd->path.dentry->d_inode;
98662306a36Sopenharmony_ci	}
98762306a36Sopenharmony_ci	nd->state |= ND_JUMPED;
98862306a36Sopenharmony_ci	return 0;
98962306a36Sopenharmony_ci}
99062306a36Sopenharmony_ci
99162306a36Sopenharmony_ci/*
99262306a36Sopenharmony_ci * Helper to directly jump to a known parsed path from ->get_link,
99362306a36Sopenharmony_ci * caller must have taken a reference to path beforehand.
99462306a36Sopenharmony_ci */
99562306a36Sopenharmony_ciint nd_jump_link(const struct path *path)
99662306a36Sopenharmony_ci{
99762306a36Sopenharmony_ci	int error = -ELOOP;
99862306a36Sopenharmony_ci	struct nameidata *nd = current->nameidata;
99962306a36Sopenharmony_ci
100062306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_NO_MAGICLINKS))
100162306a36Sopenharmony_ci		goto err;
100262306a36Sopenharmony_ci
100362306a36Sopenharmony_ci	error = -EXDEV;
100462306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_NO_XDEV)) {
100562306a36Sopenharmony_ci		if (nd->path.mnt != path->mnt)
100662306a36Sopenharmony_ci			goto err;
100762306a36Sopenharmony_ci	}
100862306a36Sopenharmony_ci	/* Not currently safe for scoped-lookups. */
100962306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_IS_SCOPED))
101062306a36Sopenharmony_ci		goto err;
101162306a36Sopenharmony_ci
101262306a36Sopenharmony_ci	path_put(&nd->path);
101362306a36Sopenharmony_ci	nd->path = *path;
101462306a36Sopenharmony_ci	nd->inode = nd->path.dentry->d_inode;
101562306a36Sopenharmony_ci	nd->state |= ND_JUMPED;
101662306a36Sopenharmony_ci	return 0;
101762306a36Sopenharmony_ci
101862306a36Sopenharmony_cierr:
101962306a36Sopenharmony_ci	path_put(path);
102062306a36Sopenharmony_ci	return error;
102162306a36Sopenharmony_ci}
102262306a36Sopenharmony_ci
102362306a36Sopenharmony_cistatic inline void put_link(struct nameidata *nd)
102462306a36Sopenharmony_ci{
102562306a36Sopenharmony_ci	struct saved *last = nd->stack + --nd->depth;
102662306a36Sopenharmony_ci	do_delayed_call(&last->done);
102762306a36Sopenharmony_ci	if (!(nd->flags & LOOKUP_RCU))
102862306a36Sopenharmony_ci		path_put(&last->link);
102962306a36Sopenharmony_ci}
103062306a36Sopenharmony_ci
103162306a36Sopenharmony_cistatic int sysctl_protected_symlinks __read_mostly;
103262306a36Sopenharmony_cistatic int sysctl_protected_hardlinks __read_mostly;
103362306a36Sopenharmony_cistatic int sysctl_protected_fifos __read_mostly;
103462306a36Sopenharmony_cistatic int sysctl_protected_regular __read_mostly;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci#ifdef CONFIG_SYSCTL
103762306a36Sopenharmony_cistatic struct ctl_table namei_sysctls[] = {
103862306a36Sopenharmony_ci	{
103962306a36Sopenharmony_ci		.procname	= "protected_symlinks",
104062306a36Sopenharmony_ci		.data		= &sysctl_protected_symlinks,
104162306a36Sopenharmony_ci		.maxlen		= sizeof(int),
104262306a36Sopenharmony_ci		.mode		= 0644,
104362306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
104462306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
104562306a36Sopenharmony_ci		.extra2		= SYSCTL_ONE,
104662306a36Sopenharmony_ci	},
104762306a36Sopenharmony_ci	{
104862306a36Sopenharmony_ci		.procname	= "protected_hardlinks",
104962306a36Sopenharmony_ci		.data		= &sysctl_protected_hardlinks,
105062306a36Sopenharmony_ci		.maxlen		= sizeof(int),
105162306a36Sopenharmony_ci		.mode		= 0644,
105262306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
105362306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
105462306a36Sopenharmony_ci		.extra2		= SYSCTL_ONE,
105562306a36Sopenharmony_ci	},
105662306a36Sopenharmony_ci	{
105762306a36Sopenharmony_ci		.procname	= "protected_fifos",
105862306a36Sopenharmony_ci		.data		= &sysctl_protected_fifos,
105962306a36Sopenharmony_ci		.maxlen		= sizeof(int),
106062306a36Sopenharmony_ci		.mode		= 0644,
106162306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
106262306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
106362306a36Sopenharmony_ci		.extra2		= SYSCTL_TWO,
106462306a36Sopenharmony_ci	},
106562306a36Sopenharmony_ci	{
106662306a36Sopenharmony_ci		.procname	= "protected_regular",
106762306a36Sopenharmony_ci		.data		= &sysctl_protected_regular,
106862306a36Sopenharmony_ci		.maxlen		= sizeof(int),
106962306a36Sopenharmony_ci		.mode		= 0644,
107062306a36Sopenharmony_ci		.proc_handler	= proc_dointvec_minmax,
107162306a36Sopenharmony_ci		.extra1		= SYSCTL_ZERO,
107262306a36Sopenharmony_ci		.extra2		= SYSCTL_TWO,
107362306a36Sopenharmony_ci	},
107462306a36Sopenharmony_ci	{ }
107562306a36Sopenharmony_ci};
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_cistatic int __init init_fs_namei_sysctls(void)
107862306a36Sopenharmony_ci{
107962306a36Sopenharmony_ci	register_sysctl_init("fs", namei_sysctls);
108062306a36Sopenharmony_ci	return 0;
108162306a36Sopenharmony_ci}
108262306a36Sopenharmony_cifs_initcall(init_fs_namei_sysctls);
108362306a36Sopenharmony_ci
108462306a36Sopenharmony_ci#endif /* CONFIG_SYSCTL */
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci/**
108762306a36Sopenharmony_ci * may_follow_link - Check symlink following for unsafe situations
108862306a36Sopenharmony_ci * @nd: nameidata pathwalk data
108962306a36Sopenharmony_ci * @inode: Used for idmapping.
109062306a36Sopenharmony_ci *
109162306a36Sopenharmony_ci * In the case of the sysctl_protected_symlinks sysctl being enabled,
109262306a36Sopenharmony_ci * CAP_DAC_OVERRIDE needs to be specifically ignored if the symlink is
109362306a36Sopenharmony_ci * in a sticky world-writable directory. This is to protect privileged
109462306a36Sopenharmony_ci * processes from failing races against path names that may change out
109562306a36Sopenharmony_ci * from under them by way of other users creating malicious symlinks.
109662306a36Sopenharmony_ci * It will permit symlinks to be followed only when outside a sticky
109762306a36Sopenharmony_ci * world-writable directory, or when the uid of the symlink and follower
109862306a36Sopenharmony_ci * match, or when the directory owner matches the symlink's owner.
109962306a36Sopenharmony_ci *
110062306a36Sopenharmony_ci * Returns 0 if following the symlink is allowed, -ve on error.
110162306a36Sopenharmony_ci */
110262306a36Sopenharmony_cistatic inline int may_follow_link(struct nameidata *nd, const struct inode *inode)
110362306a36Sopenharmony_ci{
110462306a36Sopenharmony_ci	struct mnt_idmap *idmap;
110562306a36Sopenharmony_ci	vfsuid_t vfsuid;
110662306a36Sopenharmony_ci
110762306a36Sopenharmony_ci	if (!sysctl_protected_symlinks)
110862306a36Sopenharmony_ci		return 0;
110962306a36Sopenharmony_ci
111062306a36Sopenharmony_ci	idmap = mnt_idmap(nd->path.mnt);
111162306a36Sopenharmony_ci	vfsuid = i_uid_into_vfsuid(idmap, inode);
111262306a36Sopenharmony_ci	/* Allowed if owner and follower match. */
111362306a36Sopenharmony_ci	if (vfsuid_eq_kuid(vfsuid, current_fsuid()))
111462306a36Sopenharmony_ci		return 0;
111562306a36Sopenharmony_ci
111662306a36Sopenharmony_ci	/* Allowed if parent directory not sticky and world-writable. */
111762306a36Sopenharmony_ci	if ((nd->dir_mode & (S_ISVTX|S_IWOTH)) != (S_ISVTX|S_IWOTH))
111862306a36Sopenharmony_ci		return 0;
111962306a36Sopenharmony_ci
112062306a36Sopenharmony_ci	/* Allowed if parent directory and link owner match. */
112162306a36Sopenharmony_ci	if (vfsuid_valid(nd->dir_vfsuid) && vfsuid_eq(nd->dir_vfsuid, vfsuid))
112262306a36Sopenharmony_ci		return 0;
112362306a36Sopenharmony_ci
112462306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU)
112562306a36Sopenharmony_ci		return -ECHILD;
112662306a36Sopenharmony_ci
112762306a36Sopenharmony_ci	audit_inode(nd->name, nd->stack[0].link.dentry, 0);
112862306a36Sopenharmony_ci	audit_log_path_denied(AUDIT_ANOM_LINK, "follow_link");
112962306a36Sopenharmony_ci	return -EACCES;
113062306a36Sopenharmony_ci}
113162306a36Sopenharmony_ci
113262306a36Sopenharmony_ci/**
113362306a36Sopenharmony_ci * safe_hardlink_source - Check for safe hardlink conditions
113462306a36Sopenharmony_ci * @idmap: idmap of the mount the inode was found from
113562306a36Sopenharmony_ci * @inode: the source inode to hardlink from
113662306a36Sopenharmony_ci *
113762306a36Sopenharmony_ci * Return false if at least one of the following conditions:
113862306a36Sopenharmony_ci *    - inode is not a regular file
113962306a36Sopenharmony_ci *    - inode is setuid
114062306a36Sopenharmony_ci *    - inode is setgid and group-exec
114162306a36Sopenharmony_ci *    - access failure for read and write
114262306a36Sopenharmony_ci *
114362306a36Sopenharmony_ci * Otherwise returns true.
114462306a36Sopenharmony_ci */
114562306a36Sopenharmony_cistatic bool safe_hardlink_source(struct mnt_idmap *idmap,
114662306a36Sopenharmony_ci				 struct inode *inode)
114762306a36Sopenharmony_ci{
114862306a36Sopenharmony_ci	umode_t mode = inode->i_mode;
114962306a36Sopenharmony_ci
115062306a36Sopenharmony_ci	/* Special files should not get pinned to the filesystem. */
115162306a36Sopenharmony_ci	if (!S_ISREG(mode))
115262306a36Sopenharmony_ci		return false;
115362306a36Sopenharmony_ci
115462306a36Sopenharmony_ci	/* Setuid files should not get pinned to the filesystem. */
115562306a36Sopenharmony_ci	if (mode & S_ISUID)
115662306a36Sopenharmony_ci		return false;
115762306a36Sopenharmony_ci
115862306a36Sopenharmony_ci	/* Executable setgid files should not get pinned to the filesystem. */
115962306a36Sopenharmony_ci	if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP))
116062306a36Sopenharmony_ci		return false;
116162306a36Sopenharmony_ci
116262306a36Sopenharmony_ci	/* Hardlinking to unreadable or unwritable sources is dangerous. */
116362306a36Sopenharmony_ci	if (inode_permission(idmap, inode, MAY_READ | MAY_WRITE))
116462306a36Sopenharmony_ci		return false;
116562306a36Sopenharmony_ci
116662306a36Sopenharmony_ci	return true;
116762306a36Sopenharmony_ci}
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci/**
117062306a36Sopenharmony_ci * may_linkat - Check permissions for creating a hardlink
117162306a36Sopenharmony_ci * @idmap: idmap of the mount the inode was found from
117262306a36Sopenharmony_ci * @link:  the source to hardlink from
117362306a36Sopenharmony_ci *
117462306a36Sopenharmony_ci * Block hardlink when all of:
117562306a36Sopenharmony_ci *  - sysctl_protected_hardlinks enabled
117662306a36Sopenharmony_ci *  - fsuid does not match inode
117762306a36Sopenharmony_ci *  - hardlink source is unsafe (see safe_hardlink_source() above)
117862306a36Sopenharmony_ci *  - not CAP_FOWNER in a namespace with the inode owner uid mapped
117962306a36Sopenharmony_ci *
118062306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
118162306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
118262306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
118362306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
118462306a36Sopenharmony_ci * raw inode simply pass @nop_mnt_idmap.
118562306a36Sopenharmony_ci *
118662306a36Sopenharmony_ci * Returns 0 if successful, -ve on error.
118762306a36Sopenharmony_ci */
118862306a36Sopenharmony_ciint may_linkat(struct mnt_idmap *idmap, const struct path *link)
118962306a36Sopenharmony_ci{
119062306a36Sopenharmony_ci	struct inode *inode = link->dentry->d_inode;
119162306a36Sopenharmony_ci
119262306a36Sopenharmony_ci	/* Inode writeback is not safe when the uid or gid are invalid. */
119362306a36Sopenharmony_ci	if (!vfsuid_valid(i_uid_into_vfsuid(idmap, inode)) ||
119462306a36Sopenharmony_ci	    !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))
119562306a36Sopenharmony_ci		return -EOVERFLOW;
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	if (!sysctl_protected_hardlinks)
119862306a36Sopenharmony_ci		return 0;
119962306a36Sopenharmony_ci
120062306a36Sopenharmony_ci	/* Source inode owner (or CAP_FOWNER) can hardlink all they like,
120162306a36Sopenharmony_ci	 * otherwise, it must be a safe source.
120262306a36Sopenharmony_ci	 */
120362306a36Sopenharmony_ci	if (safe_hardlink_source(idmap, inode) ||
120462306a36Sopenharmony_ci	    inode_owner_or_capable(idmap, inode))
120562306a36Sopenharmony_ci		return 0;
120662306a36Sopenharmony_ci
120762306a36Sopenharmony_ci	audit_log_path_denied(AUDIT_ANOM_LINK, "linkat");
120862306a36Sopenharmony_ci	return -EPERM;
120962306a36Sopenharmony_ci}
121062306a36Sopenharmony_ci
121162306a36Sopenharmony_ci/**
121262306a36Sopenharmony_ci * may_create_in_sticky - Check whether an O_CREAT open in a sticky directory
121362306a36Sopenharmony_ci *			  should be allowed, or not, on files that already
121462306a36Sopenharmony_ci *			  exist.
121562306a36Sopenharmony_ci * @idmap: idmap of the mount the inode was found from
121662306a36Sopenharmony_ci * @nd: nameidata pathwalk data
121762306a36Sopenharmony_ci * @inode: the inode of the file to open
121862306a36Sopenharmony_ci *
121962306a36Sopenharmony_ci * Block an O_CREAT open of a FIFO (or a regular file) when:
122062306a36Sopenharmony_ci *   - sysctl_protected_fifos (or sysctl_protected_regular) is enabled
122162306a36Sopenharmony_ci *   - the file already exists
122262306a36Sopenharmony_ci *   - we are in a sticky directory
122362306a36Sopenharmony_ci *   - we don't own the file
122462306a36Sopenharmony_ci *   - the owner of the directory doesn't own the file
122562306a36Sopenharmony_ci *   - the directory is world writable
122662306a36Sopenharmony_ci * If the sysctl_protected_fifos (or sysctl_protected_regular) is set to 2
122762306a36Sopenharmony_ci * the directory doesn't have to be world writable: being group writable will
122862306a36Sopenharmony_ci * be enough.
122962306a36Sopenharmony_ci *
123062306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
123162306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
123262306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
123362306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
123462306a36Sopenharmony_ci * raw inode simply pass @nop_mnt_idmap.
123562306a36Sopenharmony_ci *
123662306a36Sopenharmony_ci * Returns 0 if the open is allowed, -ve on error.
123762306a36Sopenharmony_ci */
123862306a36Sopenharmony_cistatic int may_create_in_sticky(struct mnt_idmap *idmap,
123962306a36Sopenharmony_ci				struct nameidata *nd, struct inode *const inode)
124062306a36Sopenharmony_ci{
124162306a36Sopenharmony_ci	umode_t dir_mode = nd->dir_mode;
124262306a36Sopenharmony_ci	vfsuid_t dir_vfsuid = nd->dir_vfsuid;
124362306a36Sopenharmony_ci
124462306a36Sopenharmony_ci	if ((!sysctl_protected_fifos && S_ISFIFO(inode->i_mode)) ||
124562306a36Sopenharmony_ci	    (!sysctl_protected_regular && S_ISREG(inode->i_mode)) ||
124662306a36Sopenharmony_ci	    likely(!(dir_mode & S_ISVTX)) ||
124762306a36Sopenharmony_ci	    vfsuid_eq(i_uid_into_vfsuid(idmap, inode), dir_vfsuid) ||
124862306a36Sopenharmony_ci	    vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, inode), current_fsuid()))
124962306a36Sopenharmony_ci		return 0;
125062306a36Sopenharmony_ci
125162306a36Sopenharmony_ci	if (likely(dir_mode & 0002) ||
125262306a36Sopenharmony_ci	    (dir_mode & 0020 &&
125362306a36Sopenharmony_ci	     ((sysctl_protected_fifos >= 2 && S_ISFIFO(inode->i_mode)) ||
125462306a36Sopenharmony_ci	      (sysctl_protected_regular >= 2 && S_ISREG(inode->i_mode))))) {
125562306a36Sopenharmony_ci		const char *operation = S_ISFIFO(inode->i_mode) ?
125662306a36Sopenharmony_ci					"sticky_create_fifo" :
125762306a36Sopenharmony_ci					"sticky_create_regular";
125862306a36Sopenharmony_ci		audit_log_path_denied(AUDIT_ANOM_CREAT, operation);
125962306a36Sopenharmony_ci		return -EACCES;
126062306a36Sopenharmony_ci	}
126162306a36Sopenharmony_ci	return 0;
126262306a36Sopenharmony_ci}
126362306a36Sopenharmony_ci
126462306a36Sopenharmony_ci/*
126562306a36Sopenharmony_ci * follow_up - Find the mountpoint of path's vfsmount
126662306a36Sopenharmony_ci *
126762306a36Sopenharmony_ci * Given a path, find the mountpoint of its source file system.
126862306a36Sopenharmony_ci * Replace @path with the path of the mountpoint in the parent mount.
126962306a36Sopenharmony_ci * Up is towards /.
127062306a36Sopenharmony_ci *
127162306a36Sopenharmony_ci * Return 1 if we went up a level and 0 if we were already at the
127262306a36Sopenharmony_ci * root.
127362306a36Sopenharmony_ci */
127462306a36Sopenharmony_ciint follow_up(struct path *path)
127562306a36Sopenharmony_ci{
127662306a36Sopenharmony_ci	struct mount *mnt = real_mount(path->mnt);
127762306a36Sopenharmony_ci	struct mount *parent;
127862306a36Sopenharmony_ci	struct dentry *mountpoint;
127962306a36Sopenharmony_ci
128062306a36Sopenharmony_ci	read_seqlock_excl(&mount_lock);
128162306a36Sopenharmony_ci	parent = mnt->mnt_parent;
128262306a36Sopenharmony_ci	if (parent == mnt) {
128362306a36Sopenharmony_ci		read_sequnlock_excl(&mount_lock);
128462306a36Sopenharmony_ci		return 0;
128562306a36Sopenharmony_ci	}
128662306a36Sopenharmony_ci	mntget(&parent->mnt);
128762306a36Sopenharmony_ci	mountpoint = dget(mnt->mnt_mountpoint);
128862306a36Sopenharmony_ci	read_sequnlock_excl(&mount_lock);
128962306a36Sopenharmony_ci	dput(path->dentry);
129062306a36Sopenharmony_ci	path->dentry = mountpoint;
129162306a36Sopenharmony_ci	mntput(path->mnt);
129262306a36Sopenharmony_ci	path->mnt = &parent->mnt;
129362306a36Sopenharmony_ci	return 1;
129462306a36Sopenharmony_ci}
129562306a36Sopenharmony_ciEXPORT_SYMBOL(follow_up);
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_cistatic bool choose_mountpoint_rcu(struct mount *m, const struct path *root,
129862306a36Sopenharmony_ci				  struct path *path, unsigned *seqp)
129962306a36Sopenharmony_ci{
130062306a36Sopenharmony_ci	while (mnt_has_parent(m)) {
130162306a36Sopenharmony_ci		struct dentry *mountpoint = m->mnt_mountpoint;
130262306a36Sopenharmony_ci
130362306a36Sopenharmony_ci		m = m->mnt_parent;
130462306a36Sopenharmony_ci		if (unlikely(root->dentry == mountpoint &&
130562306a36Sopenharmony_ci			     root->mnt == &m->mnt))
130662306a36Sopenharmony_ci			break;
130762306a36Sopenharmony_ci		if (mountpoint != m->mnt.mnt_root) {
130862306a36Sopenharmony_ci			path->mnt = &m->mnt;
130962306a36Sopenharmony_ci			path->dentry = mountpoint;
131062306a36Sopenharmony_ci			*seqp = read_seqcount_begin(&mountpoint->d_seq);
131162306a36Sopenharmony_ci			return true;
131262306a36Sopenharmony_ci		}
131362306a36Sopenharmony_ci	}
131462306a36Sopenharmony_ci	return false;
131562306a36Sopenharmony_ci}
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_cistatic bool choose_mountpoint(struct mount *m, const struct path *root,
131862306a36Sopenharmony_ci			      struct path *path)
131962306a36Sopenharmony_ci{
132062306a36Sopenharmony_ci	bool found;
132162306a36Sopenharmony_ci
132262306a36Sopenharmony_ci	rcu_read_lock();
132362306a36Sopenharmony_ci	while (1) {
132462306a36Sopenharmony_ci		unsigned seq, mseq = read_seqbegin(&mount_lock);
132562306a36Sopenharmony_ci
132662306a36Sopenharmony_ci		found = choose_mountpoint_rcu(m, root, path, &seq);
132762306a36Sopenharmony_ci		if (unlikely(!found)) {
132862306a36Sopenharmony_ci			if (!read_seqretry(&mount_lock, mseq))
132962306a36Sopenharmony_ci				break;
133062306a36Sopenharmony_ci		} else {
133162306a36Sopenharmony_ci			if (likely(__legitimize_path(path, seq, mseq)))
133262306a36Sopenharmony_ci				break;
133362306a36Sopenharmony_ci			rcu_read_unlock();
133462306a36Sopenharmony_ci			path_put(path);
133562306a36Sopenharmony_ci			rcu_read_lock();
133662306a36Sopenharmony_ci		}
133762306a36Sopenharmony_ci	}
133862306a36Sopenharmony_ci	rcu_read_unlock();
133962306a36Sopenharmony_ci	return found;
134062306a36Sopenharmony_ci}
134162306a36Sopenharmony_ci
134262306a36Sopenharmony_ci/*
134362306a36Sopenharmony_ci * Perform an automount
134462306a36Sopenharmony_ci * - return -EISDIR to tell follow_managed() to stop and return the path we
134562306a36Sopenharmony_ci *   were called with.
134662306a36Sopenharmony_ci */
134762306a36Sopenharmony_cistatic int follow_automount(struct path *path, int *count, unsigned lookup_flags)
134862306a36Sopenharmony_ci{
134962306a36Sopenharmony_ci	struct dentry *dentry = path->dentry;
135062306a36Sopenharmony_ci
135162306a36Sopenharmony_ci	/* We don't want to mount if someone's just doing a stat -
135262306a36Sopenharmony_ci	 * unless they're stat'ing a directory and appended a '/' to
135362306a36Sopenharmony_ci	 * the name.
135462306a36Sopenharmony_ci	 *
135562306a36Sopenharmony_ci	 * We do, however, want to mount if someone wants to open or
135662306a36Sopenharmony_ci	 * create a file of any type under the mountpoint, wants to
135762306a36Sopenharmony_ci	 * traverse through the mountpoint or wants to open the
135862306a36Sopenharmony_ci	 * mounted directory.  Also, autofs may mark negative dentries
135962306a36Sopenharmony_ci	 * as being automount points.  These will need the attentions
136062306a36Sopenharmony_ci	 * of the daemon to instantiate them before they can be used.
136162306a36Sopenharmony_ci	 */
136262306a36Sopenharmony_ci	if (!(lookup_flags & (LOOKUP_PARENT | LOOKUP_DIRECTORY |
136362306a36Sopenharmony_ci			   LOOKUP_OPEN | LOOKUP_CREATE | LOOKUP_AUTOMOUNT)) &&
136462306a36Sopenharmony_ci	    dentry->d_inode)
136562306a36Sopenharmony_ci		return -EISDIR;
136662306a36Sopenharmony_ci
136762306a36Sopenharmony_ci	if (count && (*count)++ >= MAXSYMLINKS)
136862306a36Sopenharmony_ci		return -ELOOP;
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ci	return finish_automount(dentry->d_op->d_automount(path), path);
137162306a36Sopenharmony_ci}
137262306a36Sopenharmony_ci
137362306a36Sopenharmony_ci/*
137462306a36Sopenharmony_ci * mount traversal - out-of-line part.  One note on ->d_flags accesses -
137562306a36Sopenharmony_ci * dentries are pinned but not locked here, so negative dentry can go
137662306a36Sopenharmony_ci * positive right under us.  Use of smp_load_acquire() provides a barrier
137762306a36Sopenharmony_ci * sufficient for ->d_inode and ->d_flags consistency.
137862306a36Sopenharmony_ci */
137962306a36Sopenharmony_cistatic int __traverse_mounts(struct path *path, unsigned flags, bool *jumped,
138062306a36Sopenharmony_ci			     int *count, unsigned lookup_flags)
138162306a36Sopenharmony_ci{
138262306a36Sopenharmony_ci	struct vfsmount *mnt = path->mnt;
138362306a36Sopenharmony_ci	bool need_mntput = false;
138462306a36Sopenharmony_ci	int ret = 0;
138562306a36Sopenharmony_ci
138662306a36Sopenharmony_ci	while (flags & DCACHE_MANAGED_DENTRY) {
138762306a36Sopenharmony_ci		/* Allow the filesystem to manage the transit without i_mutex
138862306a36Sopenharmony_ci		 * being held. */
138962306a36Sopenharmony_ci		if (flags & DCACHE_MANAGE_TRANSIT) {
139062306a36Sopenharmony_ci			ret = path->dentry->d_op->d_manage(path, false);
139162306a36Sopenharmony_ci			flags = smp_load_acquire(&path->dentry->d_flags);
139262306a36Sopenharmony_ci			if (ret < 0)
139362306a36Sopenharmony_ci				break;
139462306a36Sopenharmony_ci		}
139562306a36Sopenharmony_ci
139662306a36Sopenharmony_ci		if (flags & DCACHE_MOUNTED) {	// something's mounted on it..
139762306a36Sopenharmony_ci			struct vfsmount *mounted = lookup_mnt(path);
139862306a36Sopenharmony_ci			if (mounted) {		// ... in our namespace
139962306a36Sopenharmony_ci				dput(path->dentry);
140062306a36Sopenharmony_ci				if (need_mntput)
140162306a36Sopenharmony_ci					mntput(path->mnt);
140262306a36Sopenharmony_ci				path->mnt = mounted;
140362306a36Sopenharmony_ci				path->dentry = dget(mounted->mnt_root);
140462306a36Sopenharmony_ci				// here we know it's positive
140562306a36Sopenharmony_ci				flags = path->dentry->d_flags;
140662306a36Sopenharmony_ci				need_mntput = true;
140762306a36Sopenharmony_ci				continue;
140862306a36Sopenharmony_ci			}
140962306a36Sopenharmony_ci		}
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci		if (!(flags & DCACHE_NEED_AUTOMOUNT))
141262306a36Sopenharmony_ci			break;
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci		// uncovered automount point
141562306a36Sopenharmony_ci		ret = follow_automount(path, count, lookup_flags);
141662306a36Sopenharmony_ci		flags = smp_load_acquire(&path->dentry->d_flags);
141762306a36Sopenharmony_ci		if (ret < 0)
141862306a36Sopenharmony_ci			break;
141962306a36Sopenharmony_ci	}
142062306a36Sopenharmony_ci
142162306a36Sopenharmony_ci	if (ret == -EISDIR)
142262306a36Sopenharmony_ci		ret = 0;
142362306a36Sopenharmony_ci	// possible if you race with several mount --move
142462306a36Sopenharmony_ci	if (need_mntput && path->mnt == mnt)
142562306a36Sopenharmony_ci		mntput(path->mnt);
142662306a36Sopenharmony_ci	if (!ret && unlikely(d_flags_negative(flags)))
142762306a36Sopenharmony_ci		ret = -ENOENT;
142862306a36Sopenharmony_ci	*jumped = need_mntput;
142962306a36Sopenharmony_ci	return ret;
143062306a36Sopenharmony_ci}
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_cistatic inline int traverse_mounts(struct path *path, bool *jumped,
143362306a36Sopenharmony_ci				  int *count, unsigned lookup_flags)
143462306a36Sopenharmony_ci{
143562306a36Sopenharmony_ci	unsigned flags = smp_load_acquire(&path->dentry->d_flags);
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci	/* fastpath */
143862306a36Sopenharmony_ci	if (likely(!(flags & DCACHE_MANAGED_DENTRY))) {
143962306a36Sopenharmony_ci		*jumped = false;
144062306a36Sopenharmony_ci		if (unlikely(d_flags_negative(flags)))
144162306a36Sopenharmony_ci			return -ENOENT;
144262306a36Sopenharmony_ci		return 0;
144362306a36Sopenharmony_ci	}
144462306a36Sopenharmony_ci	return __traverse_mounts(path, flags, jumped, count, lookup_flags);
144562306a36Sopenharmony_ci}
144662306a36Sopenharmony_ci
144762306a36Sopenharmony_ciint follow_down_one(struct path *path)
144862306a36Sopenharmony_ci{
144962306a36Sopenharmony_ci	struct vfsmount *mounted;
145062306a36Sopenharmony_ci
145162306a36Sopenharmony_ci	mounted = lookup_mnt(path);
145262306a36Sopenharmony_ci	if (mounted) {
145362306a36Sopenharmony_ci		dput(path->dentry);
145462306a36Sopenharmony_ci		mntput(path->mnt);
145562306a36Sopenharmony_ci		path->mnt = mounted;
145662306a36Sopenharmony_ci		path->dentry = dget(mounted->mnt_root);
145762306a36Sopenharmony_ci		return 1;
145862306a36Sopenharmony_ci	}
145962306a36Sopenharmony_ci	return 0;
146062306a36Sopenharmony_ci}
146162306a36Sopenharmony_ciEXPORT_SYMBOL(follow_down_one);
146262306a36Sopenharmony_ci
146362306a36Sopenharmony_ci/*
146462306a36Sopenharmony_ci * Follow down to the covering mount currently visible to userspace.  At each
146562306a36Sopenharmony_ci * point, the filesystem owning that dentry may be queried as to whether the
146662306a36Sopenharmony_ci * caller is permitted to proceed or not.
146762306a36Sopenharmony_ci */
146862306a36Sopenharmony_ciint follow_down(struct path *path, unsigned int flags)
146962306a36Sopenharmony_ci{
147062306a36Sopenharmony_ci	struct vfsmount *mnt = path->mnt;
147162306a36Sopenharmony_ci	bool jumped;
147262306a36Sopenharmony_ci	int ret = traverse_mounts(path, &jumped, NULL, flags);
147362306a36Sopenharmony_ci
147462306a36Sopenharmony_ci	if (path->mnt != mnt)
147562306a36Sopenharmony_ci		mntput(mnt);
147662306a36Sopenharmony_ci	return ret;
147762306a36Sopenharmony_ci}
147862306a36Sopenharmony_ciEXPORT_SYMBOL(follow_down);
147962306a36Sopenharmony_ci
148062306a36Sopenharmony_ci/*
148162306a36Sopenharmony_ci * Try to skip to top of mountpoint pile in rcuwalk mode.  Fail if
148262306a36Sopenharmony_ci * we meet a managed dentry that would need blocking.
148362306a36Sopenharmony_ci */
148462306a36Sopenharmony_cistatic bool __follow_mount_rcu(struct nameidata *nd, struct path *path)
148562306a36Sopenharmony_ci{
148662306a36Sopenharmony_ci	struct dentry *dentry = path->dentry;
148762306a36Sopenharmony_ci	unsigned int flags = dentry->d_flags;
148862306a36Sopenharmony_ci
148962306a36Sopenharmony_ci	if (likely(!(flags & DCACHE_MANAGED_DENTRY)))
149062306a36Sopenharmony_ci		return true;
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_NO_XDEV))
149362306a36Sopenharmony_ci		return false;
149462306a36Sopenharmony_ci
149562306a36Sopenharmony_ci	for (;;) {
149662306a36Sopenharmony_ci		/*
149762306a36Sopenharmony_ci		 * Don't forget we might have a non-mountpoint managed dentry
149862306a36Sopenharmony_ci		 * that wants to block transit.
149962306a36Sopenharmony_ci		 */
150062306a36Sopenharmony_ci		if (unlikely(flags & DCACHE_MANAGE_TRANSIT)) {
150162306a36Sopenharmony_ci			int res = dentry->d_op->d_manage(path, true);
150262306a36Sopenharmony_ci			if (res)
150362306a36Sopenharmony_ci				return res == -EISDIR;
150462306a36Sopenharmony_ci			flags = dentry->d_flags;
150562306a36Sopenharmony_ci		}
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci		if (flags & DCACHE_MOUNTED) {
150862306a36Sopenharmony_ci			struct mount *mounted = __lookup_mnt(path->mnt, dentry);
150962306a36Sopenharmony_ci			if (mounted) {
151062306a36Sopenharmony_ci				path->mnt = &mounted->mnt;
151162306a36Sopenharmony_ci				dentry = path->dentry = mounted->mnt.mnt_root;
151262306a36Sopenharmony_ci				nd->state |= ND_JUMPED;
151362306a36Sopenharmony_ci				nd->next_seq = read_seqcount_begin(&dentry->d_seq);
151462306a36Sopenharmony_ci				flags = dentry->d_flags;
151562306a36Sopenharmony_ci				// makes sure that non-RCU pathwalk could reach
151662306a36Sopenharmony_ci				// this state.
151762306a36Sopenharmony_ci				if (read_seqretry(&mount_lock, nd->m_seq))
151862306a36Sopenharmony_ci					return false;
151962306a36Sopenharmony_ci				continue;
152062306a36Sopenharmony_ci			}
152162306a36Sopenharmony_ci			if (read_seqretry(&mount_lock, nd->m_seq))
152262306a36Sopenharmony_ci				return false;
152362306a36Sopenharmony_ci		}
152462306a36Sopenharmony_ci		return !(flags & DCACHE_NEED_AUTOMOUNT);
152562306a36Sopenharmony_ci	}
152662306a36Sopenharmony_ci}
152762306a36Sopenharmony_ci
152862306a36Sopenharmony_cistatic inline int handle_mounts(struct nameidata *nd, struct dentry *dentry,
152962306a36Sopenharmony_ci			  struct path *path)
153062306a36Sopenharmony_ci{
153162306a36Sopenharmony_ci	bool jumped;
153262306a36Sopenharmony_ci	int ret;
153362306a36Sopenharmony_ci
153462306a36Sopenharmony_ci	path->mnt = nd->path.mnt;
153562306a36Sopenharmony_ci	path->dentry = dentry;
153662306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
153762306a36Sopenharmony_ci		unsigned int seq = nd->next_seq;
153862306a36Sopenharmony_ci		if (likely(__follow_mount_rcu(nd, path)))
153962306a36Sopenharmony_ci			return 0;
154062306a36Sopenharmony_ci		// *path and nd->next_seq might've been clobbered
154162306a36Sopenharmony_ci		path->mnt = nd->path.mnt;
154262306a36Sopenharmony_ci		path->dentry = dentry;
154362306a36Sopenharmony_ci		nd->next_seq = seq;
154462306a36Sopenharmony_ci		if (!try_to_unlazy_next(nd, dentry))
154562306a36Sopenharmony_ci			return -ECHILD;
154662306a36Sopenharmony_ci	}
154762306a36Sopenharmony_ci	ret = traverse_mounts(path, &jumped, &nd->total_link_count, nd->flags);
154862306a36Sopenharmony_ci	if (jumped) {
154962306a36Sopenharmony_ci		if (unlikely(nd->flags & LOOKUP_NO_XDEV))
155062306a36Sopenharmony_ci			ret = -EXDEV;
155162306a36Sopenharmony_ci		else
155262306a36Sopenharmony_ci			nd->state |= ND_JUMPED;
155362306a36Sopenharmony_ci	}
155462306a36Sopenharmony_ci	if (unlikely(ret)) {
155562306a36Sopenharmony_ci		dput(path->dentry);
155662306a36Sopenharmony_ci		if (path->mnt != nd->path.mnt)
155762306a36Sopenharmony_ci			mntput(path->mnt);
155862306a36Sopenharmony_ci	}
155962306a36Sopenharmony_ci	return ret;
156062306a36Sopenharmony_ci}
156162306a36Sopenharmony_ci
156262306a36Sopenharmony_ci/*
156362306a36Sopenharmony_ci * This looks up the name in dcache and possibly revalidates the found dentry.
156462306a36Sopenharmony_ci * NULL is returned if the dentry does not exist in the cache.
156562306a36Sopenharmony_ci */
156662306a36Sopenharmony_cistatic struct dentry *lookup_dcache(const struct qstr *name,
156762306a36Sopenharmony_ci				    struct dentry *dir,
156862306a36Sopenharmony_ci				    unsigned int flags)
156962306a36Sopenharmony_ci{
157062306a36Sopenharmony_ci	struct dentry *dentry = d_lookup(dir, name);
157162306a36Sopenharmony_ci	if (dentry) {
157262306a36Sopenharmony_ci		int error = d_revalidate(dentry, flags);
157362306a36Sopenharmony_ci		if (unlikely(error <= 0)) {
157462306a36Sopenharmony_ci			if (!error)
157562306a36Sopenharmony_ci				d_invalidate(dentry);
157662306a36Sopenharmony_ci			dput(dentry);
157762306a36Sopenharmony_ci			return ERR_PTR(error);
157862306a36Sopenharmony_ci		}
157962306a36Sopenharmony_ci	}
158062306a36Sopenharmony_ci	return dentry;
158162306a36Sopenharmony_ci}
158262306a36Sopenharmony_ci
158362306a36Sopenharmony_ci/*
158462306a36Sopenharmony_ci * Parent directory has inode locked exclusive.  This is one
158562306a36Sopenharmony_ci * and only case when ->lookup() gets called on non in-lookup
158662306a36Sopenharmony_ci * dentries - as the matter of fact, this only gets called
158762306a36Sopenharmony_ci * when directory is guaranteed to have no in-lookup children
158862306a36Sopenharmony_ci * at all.
158962306a36Sopenharmony_ci */
159062306a36Sopenharmony_cistruct dentry *lookup_one_qstr_excl(const struct qstr *name,
159162306a36Sopenharmony_ci				    struct dentry *base,
159262306a36Sopenharmony_ci				    unsigned int flags)
159362306a36Sopenharmony_ci{
159462306a36Sopenharmony_ci	struct dentry *dentry = lookup_dcache(name, base, flags);
159562306a36Sopenharmony_ci	struct dentry *old;
159662306a36Sopenharmony_ci	struct inode *dir = base->d_inode;
159762306a36Sopenharmony_ci
159862306a36Sopenharmony_ci	if (dentry)
159962306a36Sopenharmony_ci		return dentry;
160062306a36Sopenharmony_ci
160162306a36Sopenharmony_ci	/* Don't create child dentry for a dead directory. */
160262306a36Sopenharmony_ci	if (unlikely(IS_DEADDIR(dir)))
160362306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
160462306a36Sopenharmony_ci
160562306a36Sopenharmony_ci	dentry = d_alloc(base, name);
160662306a36Sopenharmony_ci	if (unlikely(!dentry))
160762306a36Sopenharmony_ci		return ERR_PTR(-ENOMEM);
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	old = dir->i_op->lookup(dir, dentry, flags);
161062306a36Sopenharmony_ci	if (unlikely(old)) {
161162306a36Sopenharmony_ci		dput(dentry);
161262306a36Sopenharmony_ci		dentry = old;
161362306a36Sopenharmony_ci	}
161462306a36Sopenharmony_ci	return dentry;
161562306a36Sopenharmony_ci}
161662306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one_qstr_excl);
161762306a36Sopenharmony_ci
161862306a36Sopenharmony_cistatic struct dentry *lookup_fast(struct nameidata *nd)
161962306a36Sopenharmony_ci{
162062306a36Sopenharmony_ci	struct dentry *dentry, *parent = nd->path.dentry;
162162306a36Sopenharmony_ci	int status = 1;
162262306a36Sopenharmony_ci
162362306a36Sopenharmony_ci	/*
162462306a36Sopenharmony_ci	 * Rename seqlock is not required here because in the off chance
162562306a36Sopenharmony_ci	 * of a false negative due to a concurrent rename, the caller is
162662306a36Sopenharmony_ci	 * going to fall back to non-racy lookup.
162762306a36Sopenharmony_ci	 */
162862306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
162962306a36Sopenharmony_ci		dentry = __d_lookup_rcu(parent, &nd->last, &nd->next_seq);
163062306a36Sopenharmony_ci		if (unlikely(!dentry)) {
163162306a36Sopenharmony_ci			if (!try_to_unlazy(nd))
163262306a36Sopenharmony_ci				return ERR_PTR(-ECHILD);
163362306a36Sopenharmony_ci			return NULL;
163462306a36Sopenharmony_ci		}
163562306a36Sopenharmony_ci
163662306a36Sopenharmony_ci		/*
163762306a36Sopenharmony_ci		 * This sequence count validates that the parent had no
163862306a36Sopenharmony_ci		 * changes while we did the lookup of the dentry above.
163962306a36Sopenharmony_ci		 */
164062306a36Sopenharmony_ci		if (read_seqcount_retry(&parent->d_seq, nd->seq))
164162306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
164262306a36Sopenharmony_ci
164362306a36Sopenharmony_ci		status = d_revalidate(dentry, nd->flags);
164462306a36Sopenharmony_ci		if (likely(status > 0))
164562306a36Sopenharmony_ci			return dentry;
164662306a36Sopenharmony_ci		if (!try_to_unlazy_next(nd, dentry))
164762306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
164862306a36Sopenharmony_ci		if (status == -ECHILD)
164962306a36Sopenharmony_ci			/* we'd been told to redo it in non-rcu mode */
165062306a36Sopenharmony_ci			status = d_revalidate(dentry, nd->flags);
165162306a36Sopenharmony_ci	} else {
165262306a36Sopenharmony_ci		dentry = __d_lookup(parent, &nd->last);
165362306a36Sopenharmony_ci		if (unlikely(!dentry))
165462306a36Sopenharmony_ci			return NULL;
165562306a36Sopenharmony_ci		status = d_revalidate(dentry, nd->flags);
165662306a36Sopenharmony_ci	}
165762306a36Sopenharmony_ci	if (unlikely(status <= 0)) {
165862306a36Sopenharmony_ci		if (!status)
165962306a36Sopenharmony_ci			d_invalidate(dentry);
166062306a36Sopenharmony_ci		dput(dentry);
166162306a36Sopenharmony_ci		return ERR_PTR(status);
166262306a36Sopenharmony_ci	}
166362306a36Sopenharmony_ci	return dentry;
166462306a36Sopenharmony_ci}
166562306a36Sopenharmony_ci
166662306a36Sopenharmony_ci/* Fast lookup failed, do it the slow way */
166762306a36Sopenharmony_cistatic struct dentry *__lookup_slow(const struct qstr *name,
166862306a36Sopenharmony_ci				    struct dentry *dir,
166962306a36Sopenharmony_ci				    unsigned int flags)
167062306a36Sopenharmony_ci{
167162306a36Sopenharmony_ci	struct dentry *dentry, *old;
167262306a36Sopenharmony_ci	struct inode *inode = dir->d_inode;
167362306a36Sopenharmony_ci	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
167462306a36Sopenharmony_ci
167562306a36Sopenharmony_ci	/* Don't go there if it's already dead */
167662306a36Sopenharmony_ci	if (unlikely(IS_DEADDIR(inode)))
167762306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
167862306a36Sopenharmony_ciagain:
167962306a36Sopenharmony_ci	dentry = d_alloc_parallel(dir, name, &wq);
168062306a36Sopenharmony_ci	if (IS_ERR(dentry))
168162306a36Sopenharmony_ci		return dentry;
168262306a36Sopenharmony_ci	if (unlikely(!d_in_lookup(dentry))) {
168362306a36Sopenharmony_ci		int error = d_revalidate(dentry, flags);
168462306a36Sopenharmony_ci		if (unlikely(error <= 0)) {
168562306a36Sopenharmony_ci			if (!error) {
168662306a36Sopenharmony_ci				d_invalidate(dentry);
168762306a36Sopenharmony_ci				dput(dentry);
168862306a36Sopenharmony_ci				goto again;
168962306a36Sopenharmony_ci			}
169062306a36Sopenharmony_ci			dput(dentry);
169162306a36Sopenharmony_ci			dentry = ERR_PTR(error);
169262306a36Sopenharmony_ci		}
169362306a36Sopenharmony_ci	} else {
169462306a36Sopenharmony_ci		old = inode->i_op->lookup(inode, dentry, flags);
169562306a36Sopenharmony_ci		d_lookup_done(dentry);
169662306a36Sopenharmony_ci		if (unlikely(old)) {
169762306a36Sopenharmony_ci			dput(dentry);
169862306a36Sopenharmony_ci			dentry = old;
169962306a36Sopenharmony_ci		}
170062306a36Sopenharmony_ci	}
170162306a36Sopenharmony_ci	return dentry;
170262306a36Sopenharmony_ci}
170362306a36Sopenharmony_ci
170462306a36Sopenharmony_cistatic struct dentry *lookup_slow(const struct qstr *name,
170562306a36Sopenharmony_ci				  struct dentry *dir,
170662306a36Sopenharmony_ci				  unsigned int flags)
170762306a36Sopenharmony_ci{
170862306a36Sopenharmony_ci	struct inode *inode = dir->d_inode;
170962306a36Sopenharmony_ci	struct dentry *res;
171062306a36Sopenharmony_ci	inode_lock_shared(inode);
171162306a36Sopenharmony_ci	res = __lookup_slow(name, dir, flags);
171262306a36Sopenharmony_ci	inode_unlock_shared(inode);
171362306a36Sopenharmony_ci	return res;
171462306a36Sopenharmony_ci}
171562306a36Sopenharmony_ci
171662306a36Sopenharmony_cistatic inline int may_lookup(struct mnt_idmap *idmap,
171762306a36Sopenharmony_ci			     struct nameidata *nd)
171862306a36Sopenharmony_ci{
171962306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
172062306a36Sopenharmony_ci		int err = inode_permission(idmap, nd->inode, MAY_EXEC|MAY_NOT_BLOCK);
172162306a36Sopenharmony_ci		if (err != -ECHILD || !try_to_unlazy(nd))
172262306a36Sopenharmony_ci			return err;
172362306a36Sopenharmony_ci	}
172462306a36Sopenharmony_ci	return inode_permission(idmap, nd->inode, MAY_EXEC);
172562306a36Sopenharmony_ci}
172662306a36Sopenharmony_ci
172762306a36Sopenharmony_cistatic int reserve_stack(struct nameidata *nd, struct path *link)
172862306a36Sopenharmony_ci{
172962306a36Sopenharmony_ci	if (unlikely(nd->total_link_count++ >= MAXSYMLINKS))
173062306a36Sopenharmony_ci		return -ELOOP;
173162306a36Sopenharmony_ci
173262306a36Sopenharmony_ci	if (likely(nd->depth != EMBEDDED_LEVELS))
173362306a36Sopenharmony_ci		return 0;
173462306a36Sopenharmony_ci	if (likely(nd->stack != nd->internal))
173562306a36Sopenharmony_ci		return 0;
173662306a36Sopenharmony_ci	if (likely(nd_alloc_stack(nd)))
173762306a36Sopenharmony_ci		return 0;
173862306a36Sopenharmony_ci
173962306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
174062306a36Sopenharmony_ci		// we need to grab link before we do unlazy.  And we can't skip
174162306a36Sopenharmony_ci		// unlazy even if we fail to grab the link - cleanup needs it
174262306a36Sopenharmony_ci		bool grabbed_link = legitimize_path(nd, link, nd->next_seq);
174362306a36Sopenharmony_ci
174462306a36Sopenharmony_ci		if (!try_to_unlazy(nd) || !grabbed_link)
174562306a36Sopenharmony_ci			return -ECHILD;
174662306a36Sopenharmony_ci
174762306a36Sopenharmony_ci		if (nd_alloc_stack(nd))
174862306a36Sopenharmony_ci			return 0;
174962306a36Sopenharmony_ci	}
175062306a36Sopenharmony_ci	return -ENOMEM;
175162306a36Sopenharmony_ci}
175262306a36Sopenharmony_ci
175362306a36Sopenharmony_cienum {WALK_TRAILING = 1, WALK_MORE = 2, WALK_NOFOLLOW = 4};
175462306a36Sopenharmony_ci
175562306a36Sopenharmony_cistatic const char *pick_link(struct nameidata *nd, struct path *link,
175662306a36Sopenharmony_ci		     struct inode *inode, int flags)
175762306a36Sopenharmony_ci{
175862306a36Sopenharmony_ci	struct saved *last;
175962306a36Sopenharmony_ci	const char *res;
176062306a36Sopenharmony_ci	int error = reserve_stack(nd, link);
176162306a36Sopenharmony_ci
176262306a36Sopenharmony_ci	if (unlikely(error)) {
176362306a36Sopenharmony_ci		if (!(nd->flags & LOOKUP_RCU))
176462306a36Sopenharmony_ci			path_put(link);
176562306a36Sopenharmony_ci		return ERR_PTR(error);
176662306a36Sopenharmony_ci	}
176762306a36Sopenharmony_ci	last = nd->stack + nd->depth++;
176862306a36Sopenharmony_ci	last->link = *link;
176962306a36Sopenharmony_ci	clear_delayed_call(&last->done);
177062306a36Sopenharmony_ci	last->seq = nd->next_seq;
177162306a36Sopenharmony_ci
177262306a36Sopenharmony_ci	if (flags & WALK_TRAILING) {
177362306a36Sopenharmony_ci		error = may_follow_link(nd, inode);
177462306a36Sopenharmony_ci		if (unlikely(error))
177562306a36Sopenharmony_ci			return ERR_PTR(error);
177662306a36Sopenharmony_ci	}
177762306a36Sopenharmony_ci
177862306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_NO_SYMLINKS) ||
177962306a36Sopenharmony_ci			unlikely(link->mnt->mnt_flags & MNT_NOSYMFOLLOW))
178062306a36Sopenharmony_ci		return ERR_PTR(-ELOOP);
178162306a36Sopenharmony_ci
178262306a36Sopenharmony_ci	if (!(nd->flags & LOOKUP_RCU)) {
178362306a36Sopenharmony_ci		touch_atime(&last->link);
178462306a36Sopenharmony_ci		cond_resched();
178562306a36Sopenharmony_ci	} else if (atime_needs_update(&last->link, inode)) {
178662306a36Sopenharmony_ci		if (!try_to_unlazy(nd))
178762306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
178862306a36Sopenharmony_ci		touch_atime(&last->link);
178962306a36Sopenharmony_ci	}
179062306a36Sopenharmony_ci
179162306a36Sopenharmony_ci	error = security_inode_follow_link(link->dentry, inode,
179262306a36Sopenharmony_ci					   nd->flags & LOOKUP_RCU);
179362306a36Sopenharmony_ci	if (unlikely(error))
179462306a36Sopenharmony_ci		return ERR_PTR(error);
179562306a36Sopenharmony_ci
179662306a36Sopenharmony_ci	res = READ_ONCE(inode->i_link);
179762306a36Sopenharmony_ci	if (!res) {
179862306a36Sopenharmony_ci		const char * (*get)(struct dentry *, struct inode *,
179962306a36Sopenharmony_ci				struct delayed_call *);
180062306a36Sopenharmony_ci		get = inode->i_op->get_link;
180162306a36Sopenharmony_ci		if (nd->flags & LOOKUP_RCU) {
180262306a36Sopenharmony_ci			res = get(NULL, inode, &last->done);
180362306a36Sopenharmony_ci			if (res == ERR_PTR(-ECHILD) && try_to_unlazy(nd))
180462306a36Sopenharmony_ci				res = get(link->dentry, inode, &last->done);
180562306a36Sopenharmony_ci		} else {
180662306a36Sopenharmony_ci			res = get(link->dentry, inode, &last->done);
180762306a36Sopenharmony_ci		}
180862306a36Sopenharmony_ci		if (!res)
180962306a36Sopenharmony_ci			goto all_done;
181062306a36Sopenharmony_ci		if (IS_ERR(res))
181162306a36Sopenharmony_ci			return res;
181262306a36Sopenharmony_ci	}
181362306a36Sopenharmony_ci	if (*res == '/') {
181462306a36Sopenharmony_ci		error = nd_jump_root(nd);
181562306a36Sopenharmony_ci		if (unlikely(error))
181662306a36Sopenharmony_ci			return ERR_PTR(error);
181762306a36Sopenharmony_ci		while (unlikely(*++res == '/'))
181862306a36Sopenharmony_ci			;
181962306a36Sopenharmony_ci	}
182062306a36Sopenharmony_ci	if (*res)
182162306a36Sopenharmony_ci		return res;
182262306a36Sopenharmony_ciall_done: // pure jump
182362306a36Sopenharmony_ci	put_link(nd);
182462306a36Sopenharmony_ci	return NULL;
182562306a36Sopenharmony_ci}
182662306a36Sopenharmony_ci
182762306a36Sopenharmony_ci/*
182862306a36Sopenharmony_ci * Do we need to follow links? We _really_ want to be able
182962306a36Sopenharmony_ci * to do this check without having to look at inode->i_op,
183062306a36Sopenharmony_ci * so we keep a cache of "no, this doesn't need follow_link"
183162306a36Sopenharmony_ci * for the common case.
183262306a36Sopenharmony_ci *
183362306a36Sopenharmony_ci * NOTE: dentry must be what nd->next_seq had been sampled from.
183462306a36Sopenharmony_ci */
183562306a36Sopenharmony_cistatic const char *step_into(struct nameidata *nd, int flags,
183662306a36Sopenharmony_ci		     struct dentry *dentry)
183762306a36Sopenharmony_ci{
183862306a36Sopenharmony_ci	struct path path;
183962306a36Sopenharmony_ci	struct inode *inode;
184062306a36Sopenharmony_ci	int err = handle_mounts(nd, dentry, &path);
184162306a36Sopenharmony_ci
184262306a36Sopenharmony_ci	if (err < 0)
184362306a36Sopenharmony_ci		return ERR_PTR(err);
184462306a36Sopenharmony_ci	inode = path.dentry->d_inode;
184562306a36Sopenharmony_ci	if (likely(!d_is_symlink(path.dentry)) ||
184662306a36Sopenharmony_ci	   ((flags & WALK_TRAILING) && !(nd->flags & LOOKUP_FOLLOW)) ||
184762306a36Sopenharmony_ci	   (flags & WALK_NOFOLLOW)) {
184862306a36Sopenharmony_ci		/* not a symlink or should not follow */
184962306a36Sopenharmony_ci		if (nd->flags & LOOKUP_RCU) {
185062306a36Sopenharmony_ci			if (read_seqcount_retry(&path.dentry->d_seq, nd->next_seq))
185162306a36Sopenharmony_ci				return ERR_PTR(-ECHILD);
185262306a36Sopenharmony_ci			if (unlikely(!inode))
185362306a36Sopenharmony_ci				return ERR_PTR(-ENOENT);
185462306a36Sopenharmony_ci		} else {
185562306a36Sopenharmony_ci			dput(nd->path.dentry);
185662306a36Sopenharmony_ci			if (nd->path.mnt != path.mnt)
185762306a36Sopenharmony_ci				mntput(nd->path.mnt);
185862306a36Sopenharmony_ci		}
185962306a36Sopenharmony_ci		nd->path = path;
186062306a36Sopenharmony_ci		nd->inode = inode;
186162306a36Sopenharmony_ci		nd->seq = nd->next_seq;
186262306a36Sopenharmony_ci		return NULL;
186362306a36Sopenharmony_ci	}
186462306a36Sopenharmony_ci	if (nd->flags & LOOKUP_RCU) {
186562306a36Sopenharmony_ci		/* make sure that d_is_symlink above matches inode */
186662306a36Sopenharmony_ci		if (read_seqcount_retry(&path.dentry->d_seq, nd->next_seq))
186762306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
186862306a36Sopenharmony_ci	} else {
186962306a36Sopenharmony_ci		if (path.mnt == nd->path.mnt)
187062306a36Sopenharmony_ci			mntget(path.mnt);
187162306a36Sopenharmony_ci	}
187262306a36Sopenharmony_ci	return pick_link(nd, &path, inode, flags);
187362306a36Sopenharmony_ci}
187462306a36Sopenharmony_ci
187562306a36Sopenharmony_cistatic struct dentry *follow_dotdot_rcu(struct nameidata *nd)
187662306a36Sopenharmony_ci{
187762306a36Sopenharmony_ci	struct dentry *parent, *old;
187862306a36Sopenharmony_ci
187962306a36Sopenharmony_ci	if (path_equal(&nd->path, &nd->root))
188062306a36Sopenharmony_ci		goto in_root;
188162306a36Sopenharmony_ci	if (unlikely(nd->path.dentry == nd->path.mnt->mnt_root)) {
188262306a36Sopenharmony_ci		struct path path;
188362306a36Sopenharmony_ci		unsigned seq;
188462306a36Sopenharmony_ci		if (!choose_mountpoint_rcu(real_mount(nd->path.mnt),
188562306a36Sopenharmony_ci					   &nd->root, &path, &seq))
188662306a36Sopenharmony_ci			goto in_root;
188762306a36Sopenharmony_ci		if (unlikely(nd->flags & LOOKUP_NO_XDEV))
188862306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
188962306a36Sopenharmony_ci		nd->path = path;
189062306a36Sopenharmony_ci		nd->inode = path.dentry->d_inode;
189162306a36Sopenharmony_ci		nd->seq = seq;
189262306a36Sopenharmony_ci		// makes sure that non-RCU pathwalk could reach this state
189362306a36Sopenharmony_ci		if (read_seqretry(&mount_lock, nd->m_seq))
189462306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
189562306a36Sopenharmony_ci		/* we know that mountpoint was pinned */
189662306a36Sopenharmony_ci	}
189762306a36Sopenharmony_ci	old = nd->path.dentry;
189862306a36Sopenharmony_ci	parent = old->d_parent;
189962306a36Sopenharmony_ci	nd->next_seq = read_seqcount_begin(&parent->d_seq);
190062306a36Sopenharmony_ci	// makes sure that non-RCU pathwalk could reach this state
190162306a36Sopenharmony_ci	if (read_seqcount_retry(&old->d_seq, nd->seq))
190262306a36Sopenharmony_ci		return ERR_PTR(-ECHILD);
190362306a36Sopenharmony_ci	if (unlikely(!path_connected(nd->path.mnt, parent)))
190462306a36Sopenharmony_ci		return ERR_PTR(-ECHILD);
190562306a36Sopenharmony_ci	return parent;
190662306a36Sopenharmony_ciin_root:
190762306a36Sopenharmony_ci	if (read_seqretry(&mount_lock, nd->m_seq))
190862306a36Sopenharmony_ci		return ERR_PTR(-ECHILD);
190962306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_BENEATH))
191062306a36Sopenharmony_ci		return ERR_PTR(-ECHILD);
191162306a36Sopenharmony_ci	nd->next_seq = nd->seq;
191262306a36Sopenharmony_ci	return nd->path.dentry;
191362306a36Sopenharmony_ci}
191462306a36Sopenharmony_ci
191562306a36Sopenharmony_cistatic struct dentry *follow_dotdot(struct nameidata *nd)
191662306a36Sopenharmony_ci{
191762306a36Sopenharmony_ci	struct dentry *parent;
191862306a36Sopenharmony_ci
191962306a36Sopenharmony_ci	if (path_equal(&nd->path, &nd->root))
192062306a36Sopenharmony_ci		goto in_root;
192162306a36Sopenharmony_ci	if (unlikely(nd->path.dentry == nd->path.mnt->mnt_root)) {
192262306a36Sopenharmony_ci		struct path path;
192362306a36Sopenharmony_ci
192462306a36Sopenharmony_ci		if (!choose_mountpoint(real_mount(nd->path.mnt),
192562306a36Sopenharmony_ci				       &nd->root, &path))
192662306a36Sopenharmony_ci			goto in_root;
192762306a36Sopenharmony_ci		path_put(&nd->path);
192862306a36Sopenharmony_ci		nd->path = path;
192962306a36Sopenharmony_ci		nd->inode = path.dentry->d_inode;
193062306a36Sopenharmony_ci		if (unlikely(nd->flags & LOOKUP_NO_XDEV))
193162306a36Sopenharmony_ci			return ERR_PTR(-EXDEV);
193262306a36Sopenharmony_ci	}
193362306a36Sopenharmony_ci	/* rare case of legitimate dget_parent()... */
193462306a36Sopenharmony_ci	parent = dget_parent(nd->path.dentry);
193562306a36Sopenharmony_ci	if (unlikely(!path_connected(nd->path.mnt, parent))) {
193662306a36Sopenharmony_ci		dput(parent);
193762306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
193862306a36Sopenharmony_ci	}
193962306a36Sopenharmony_ci	return parent;
194062306a36Sopenharmony_ci
194162306a36Sopenharmony_ciin_root:
194262306a36Sopenharmony_ci	if (unlikely(nd->flags & LOOKUP_BENEATH))
194362306a36Sopenharmony_ci		return ERR_PTR(-EXDEV);
194462306a36Sopenharmony_ci	return dget(nd->path.dentry);
194562306a36Sopenharmony_ci}
194662306a36Sopenharmony_ci
194762306a36Sopenharmony_cistatic const char *handle_dots(struct nameidata *nd, int type)
194862306a36Sopenharmony_ci{
194962306a36Sopenharmony_ci	if (type == LAST_DOTDOT) {
195062306a36Sopenharmony_ci		const char *error = NULL;
195162306a36Sopenharmony_ci		struct dentry *parent;
195262306a36Sopenharmony_ci
195362306a36Sopenharmony_ci		if (!nd->root.mnt) {
195462306a36Sopenharmony_ci			error = ERR_PTR(set_root(nd));
195562306a36Sopenharmony_ci			if (error)
195662306a36Sopenharmony_ci				return error;
195762306a36Sopenharmony_ci		}
195862306a36Sopenharmony_ci		if (nd->flags & LOOKUP_RCU)
195962306a36Sopenharmony_ci			parent = follow_dotdot_rcu(nd);
196062306a36Sopenharmony_ci		else
196162306a36Sopenharmony_ci			parent = follow_dotdot(nd);
196262306a36Sopenharmony_ci		if (IS_ERR(parent))
196362306a36Sopenharmony_ci			return ERR_CAST(parent);
196462306a36Sopenharmony_ci		error = step_into(nd, WALK_NOFOLLOW, parent);
196562306a36Sopenharmony_ci		if (unlikely(error))
196662306a36Sopenharmony_ci			return error;
196762306a36Sopenharmony_ci
196862306a36Sopenharmony_ci		if (unlikely(nd->flags & LOOKUP_IS_SCOPED)) {
196962306a36Sopenharmony_ci			/*
197062306a36Sopenharmony_ci			 * If there was a racing rename or mount along our
197162306a36Sopenharmony_ci			 * path, then we can't be sure that ".." hasn't jumped
197262306a36Sopenharmony_ci			 * above nd->root (and so userspace should retry or use
197362306a36Sopenharmony_ci			 * some fallback).
197462306a36Sopenharmony_ci			 */
197562306a36Sopenharmony_ci			smp_rmb();
197662306a36Sopenharmony_ci			if (__read_seqcount_retry(&mount_lock.seqcount, nd->m_seq))
197762306a36Sopenharmony_ci				return ERR_PTR(-EAGAIN);
197862306a36Sopenharmony_ci			if (__read_seqcount_retry(&rename_lock.seqcount, nd->r_seq))
197962306a36Sopenharmony_ci				return ERR_PTR(-EAGAIN);
198062306a36Sopenharmony_ci		}
198162306a36Sopenharmony_ci	}
198262306a36Sopenharmony_ci	return NULL;
198362306a36Sopenharmony_ci}
198462306a36Sopenharmony_ci
198562306a36Sopenharmony_cistatic const char *walk_component(struct nameidata *nd, int flags)
198662306a36Sopenharmony_ci{
198762306a36Sopenharmony_ci	struct dentry *dentry;
198862306a36Sopenharmony_ci	/*
198962306a36Sopenharmony_ci	 * "." and ".." are special - ".." especially so because it has
199062306a36Sopenharmony_ci	 * to be able to know about the current root directory and
199162306a36Sopenharmony_ci	 * parent relationships.
199262306a36Sopenharmony_ci	 */
199362306a36Sopenharmony_ci	if (unlikely(nd->last_type != LAST_NORM)) {
199462306a36Sopenharmony_ci		if (!(flags & WALK_MORE) && nd->depth)
199562306a36Sopenharmony_ci			put_link(nd);
199662306a36Sopenharmony_ci		return handle_dots(nd, nd->last_type);
199762306a36Sopenharmony_ci	}
199862306a36Sopenharmony_ci	dentry = lookup_fast(nd);
199962306a36Sopenharmony_ci	if (IS_ERR(dentry))
200062306a36Sopenharmony_ci		return ERR_CAST(dentry);
200162306a36Sopenharmony_ci	if (unlikely(!dentry)) {
200262306a36Sopenharmony_ci		dentry = lookup_slow(&nd->last, nd->path.dentry, nd->flags);
200362306a36Sopenharmony_ci		if (IS_ERR(dentry))
200462306a36Sopenharmony_ci			return ERR_CAST(dentry);
200562306a36Sopenharmony_ci	}
200662306a36Sopenharmony_ci	if (!(flags & WALK_MORE) && nd->depth)
200762306a36Sopenharmony_ci		put_link(nd);
200862306a36Sopenharmony_ci	return step_into(nd, flags, dentry);
200962306a36Sopenharmony_ci}
201062306a36Sopenharmony_ci
201162306a36Sopenharmony_ci/*
201262306a36Sopenharmony_ci * We can do the critical dentry name comparison and hashing
201362306a36Sopenharmony_ci * operations one word at a time, but we are limited to:
201462306a36Sopenharmony_ci *
201562306a36Sopenharmony_ci * - Architectures with fast unaligned word accesses. We could
201662306a36Sopenharmony_ci *   do a "get_unaligned()" if this helps and is sufficiently
201762306a36Sopenharmony_ci *   fast.
201862306a36Sopenharmony_ci *
201962306a36Sopenharmony_ci * - non-CONFIG_DEBUG_PAGEALLOC configurations (so that we
202062306a36Sopenharmony_ci *   do not trap on the (extremely unlikely) case of a page
202162306a36Sopenharmony_ci *   crossing operation.
202262306a36Sopenharmony_ci *
202362306a36Sopenharmony_ci * - Furthermore, we need an efficient 64-bit compile for the
202462306a36Sopenharmony_ci *   64-bit case in order to generate the "number of bytes in
202562306a36Sopenharmony_ci *   the final mask". Again, that could be replaced with a
202662306a36Sopenharmony_ci *   efficient population count instruction or similar.
202762306a36Sopenharmony_ci */
202862306a36Sopenharmony_ci#ifdef CONFIG_DCACHE_WORD_ACCESS
202962306a36Sopenharmony_ci
203062306a36Sopenharmony_ci#include <asm/word-at-a-time.h>
203162306a36Sopenharmony_ci
203262306a36Sopenharmony_ci#ifdef HASH_MIX
203362306a36Sopenharmony_ci
203462306a36Sopenharmony_ci/* Architecture provides HASH_MIX and fold_hash() in <asm/hash.h> */
203562306a36Sopenharmony_ci
203662306a36Sopenharmony_ci#elif defined(CONFIG_64BIT)
203762306a36Sopenharmony_ci/*
203862306a36Sopenharmony_ci * Register pressure in the mixing function is an issue, particularly
203962306a36Sopenharmony_ci * on 32-bit x86, but almost any function requires one state value and
204062306a36Sopenharmony_ci * one temporary.  Instead, use a function designed for two state values
204162306a36Sopenharmony_ci * and no temporaries.
204262306a36Sopenharmony_ci *
204362306a36Sopenharmony_ci * This function cannot create a collision in only two iterations, so
204462306a36Sopenharmony_ci * we have two iterations to achieve avalanche.  In those two iterations,
204562306a36Sopenharmony_ci * we have six layers of mixing, which is enough to spread one bit's
204662306a36Sopenharmony_ci * influence out to 2^6 = 64 state bits.
204762306a36Sopenharmony_ci *
204862306a36Sopenharmony_ci * Rotate constants are scored by considering either 64 one-bit input
204962306a36Sopenharmony_ci * deltas or 64*63/2 = 2016 two-bit input deltas, and finding the
205062306a36Sopenharmony_ci * probability of that delta causing a change to each of the 128 output
205162306a36Sopenharmony_ci * bits, using a sample of random initial states.
205262306a36Sopenharmony_ci *
205362306a36Sopenharmony_ci * The Shannon entropy of the computed probabilities is then summed
205462306a36Sopenharmony_ci * to produce a score.  Ideally, any input change has a 50% chance of
205562306a36Sopenharmony_ci * toggling any given output bit.
205662306a36Sopenharmony_ci *
205762306a36Sopenharmony_ci * Mixing scores (in bits) for (12,45):
205862306a36Sopenharmony_ci * Input delta: 1-bit      2-bit
205962306a36Sopenharmony_ci * 1 round:     713.3    42542.6
206062306a36Sopenharmony_ci * 2 rounds:   2753.7   140389.8
206162306a36Sopenharmony_ci * 3 rounds:   5954.1   233458.2
206262306a36Sopenharmony_ci * 4 rounds:   7862.6   256672.2
206362306a36Sopenharmony_ci * Perfect:    8192     258048
206462306a36Sopenharmony_ci *            (64*128) (64*63/2 * 128)
206562306a36Sopenharmony_ci */
206662306a36Sopenharmony_ci#define HASH_MIX(x, y, a)	\
206762306a36Sopenharmony_ci	(	x ^= (a),	\
206862306a36Sopenharmony_ci	y ^= x,	x = rol64(x,12),\
206962306a36Sopenharmony_ci	x += y,	y = rol64(y,45),\
207062306a36Sopenharmony_ci	y *= 9			)
207162306a36Sopenharmony_ci
207262306a36Sopenharmony_ci/*
207362306a36Sopenharmony_ci * Fold two longs into one 32-bit hash value.  This must be fast, but
207462306a36Sopenharmony_ci * latency isn't quite as critical, as there is a fair bit of additional
207562306a36Sopenharmony_ci * work done before the hash value is used.
207662306a36Sopenharmony_ci */
207762306a36Sopenharmony_cistatic inline unsigned int fold_hash(unsigned long x, unsigned long y)
207862306a36Sopenharmony_ci{
207962306a36Sopenharmony_ci	y ^= x * GOLDEN_RATIO_64;
208062306a36Sopenharmony_ci	y *= GOLDEN_RATIO_64;
208162306a36Sopenharmony_ci	return y >> 32;
208262306a36Sopenharmony_ci}
208362306a36Sopenharmony_ci
208462306a36Sopenharmony_ci#else	/* 32-bit case */
208562306a36Sopenharmony_ci
208662306a36Sopenharmony_ci/*
208762306a36Sopenharmony_ci * Mixing scores (in bits) for (7,20):
208862306a36Sopenharmony_ci * Input delta: 1-bit      2-bit
208962306a36Sopenharmony_ci * 1 round:     330.3     9201.6
209062306a36Sopenharmony_ci * 2 rounds:   1246.4    25475.4
209162306a36Sopenharmony_ci * 3 rounds:   1907.1    31295.1
209262306a36Sopenharmony_ci * 4 rounds:   2042.3    31718.6
209362306a36Sopenharmony_ci * Perfect:    2048      31744
209462306a36Sopenharmony_ci *            (32*64)   (32*31/2 * 64)
209562306a36Sopenharmony_ci */
209662306a36Sopenharmony_ci#define HASH_MIX(x, y, a)	\
209762306a36Sopenharmony_ci	(	x ^= (a),	\
209862306a36Sopenharmony_ci	y ^= x,	x = rol32(x, 7),\
209962306a36Sopenharmony_ci	x += y,	y = rol32(y,20),\
210062306a36Sopenharmony_ci	y *= 9			)
210162306a36Sopenharmony_ci
210262306a36Sopenharmony_cistatic inline unsigned int fold_hash(unsigned long x, unsigned long y)
210362306a36Sopenharmony_ci{
210462306a36Sopenharmony_ci	/* Use arch-optimized multiply if one exists */
210562306a36Sopenharmony_ci	return __hash_32(y ^ __hash_32(x));
210662306a36Sopenharmony_ci}
210762306a36Sopenharmony_ci
210862306a36Sopenharmony_ci#endif
210962306a36Sopenharmony_ci
211062306a36Sopenharmony_ci/*
211162306a36Sopenharmony_ci * Return the hash of a string of known length.  This is carfully
211262306a36Sopenharmony_ci * designed to match hash_name(), which is the more critical function.
211362306a36Sopenharmony_ci * In particular, we must end by hashing a final word containing 0..7
211462306a36Sopenharmony_ci * payload bytes, to match the way that hash_name() iterates until it
211562306a36Sopenharmony_ci * finds the delimiter after the name.
211662306a36Sopenharmony_ci */
211762306a36Sopenharmony_ciunsigned int full_name_hash(const void *salt, const char *name, unsigned int len)
211862306a36Sopenharmony_ci{
211962306a36Sopenharmony_ci	unsigned long a, x = 0, y = (unsigned long)salt;
212062306a36Sopenharmony_ci
212162306a36Sopenharmony_ci	for (;;) {
212262306a36Sopenharmony_ci		if (!len)
212362306a36Sopenharmony_ci			goto done;
212462306a36Sopenharmony_ci		a = load_unaligned_zeropad(name);
212562306a36Sopenharmony_ci		if (len < sizeof(unsigned long))
212662306a36Sopenharmony_ci			break;
212762306a36Sopenharmony_ci		HASH_MIX(x, y, a);
212862306a36Sopenharmony_ci		name += sizeof(unsigned long);
212962306a36Sopenharmony_ci		len -= sizeof(unsigned long);
213062306a36Sopenharmony_ci	}
213162306a36Sopenharmony_ci	x ^= a & bytemask_from_count(len);
213262306a36Sopenharmony_cidone:
213362306a36Sopenharmony_ci	return fold_hash(x, y);
213462306a36Sopenharmony_ci}
213562306a36Sopenharmony_ciEXPORT_SYMBOL(full_name_hash);
213662306a36Sopenharmony_ci
213762306a36Sopenharmony_ci/* Return the "hash_len" (hash and length) of a null-terminated string */
213862306a36Sopenharmony_ciu64 hashlen_string(const void *salt, const char *name)
213962306a36Sopenharmony_ci{
214062306a36Sopenharmony_ci	unsigned long a = 0, x = 0, y = (unsigned long)salt;
214162306a36Sopenharmony_ci	unsigned long adata, mask, len;
214262306a36Sopenharmony_ci	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
214362306a36Sopenharmony_ci
214462306a36Sopenharmony_ci	len = 0;
214562306a36Sopenharmony_ci	goto inside;
214662306a36Sopenharmony_ci
214762306a36Sopenharmony_ci	do {
214862306a36Sopenharmony_ci		HASH_MIX(x, y, a);
214962306a36Sopenharmony_ci		len += sizeof(unsigned long);
215062306a36Sopenharmony_ciinside:
215162306a36Sopenharmony_ci		a = load_unaligned_zeropad(name+len);
215262306a36Sopenharmony_ci	} while (!has_zero(a, &adata, &constants));
215362306a36Sopenharmony_ci
215462306a36Sopenharmony_ci	adata = prep_zero_mask(a, adata, &constants);
215562306a36Sopenharmony_ci	mask = create_zero_mask(adata);
215662306a36Sopenharmony_ci	x ^= a & zero_bytemask(mask);
215762306a36Sopenharmony_ci
215862306a36Sopenharmony_ci	return hashlen_create(fold_hash(x, y), len + find_zero(mask));
215962306a36Sopenharmony_ci}
216062306a36Sopenharmony_ciEXPORT_SYMBOL(hashlen_string);
216162306a36Sopenharmony_ci
216262306a36Sopenharmony_ci/*
216362306a36Sopenharmony_ci * Calculate the length and hash of the path component, and
216462306a36Sopenharmony_ci * return the "hash_len" as the result.
216562306a36Sopenharmony_ci */
216662306a36Sopenharmony_cistatic inline u64 hash_name(const void *salt, const char *name)
216762306a36Sopenharmony_ci{
216862306a36Sopenharmony_ci	unsigned long a = 0, b, x = 0, y = (unsigned long)salt;
216962306a36Sopenharmony_ci	unsigned long adata, bdata, mask, len;
217062306a36Sopenharmony_ci	const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
217162306a36Sopenharmony_ci
217262306a36Sopenharmony_ci	len = 0;
217362306a36Sopenharmony_ci	goto inside;
217462306a36Sopenharmony_ci
217562306a36Sopenharmony_ci	do {
217662306a36Sopenharmony_ci		HASH_MIX(x, y, a);
217762306a36Sopenharmony_ci		len += sizeof(unsigned long);
217862306a36Sopenharmony_ciinside:
217962306a36Sopenharmony_ci		a = load_unaligned_zeropad(name+len);
218062306a36Sopenharmony_ci		b = a ^ REPEAT_BYTE('/');
218162306a36Sopenharmony_ci	} while (!(has_zero(a, &adata, &constants) | has_zero(b, &bdata, &constants)));
218262306a36Sopenharmony_ci
218362306a36Sopenharmony_ci	adata = prep_zero_mask(a, adata, &constants);
218462306a36Sopenharmony_ci	bdata = prep_zero_mask(b, bdata, &constants);
218562306a36Sopenharmony_ci	mask = create_zero_mask(adata | bdata);
218662306a36Sopenharmony_ci	x ^= a & zero_bytemask(mask);
218762306a36Sopenharmony_ci
218862306a36Sopenharmony_ci	return hashlen_create(fold_hash(x, y), len + find_zero(mask));
218962306a36Sopenharmony_ci}
219062306a36Sopenharmony_ci
219162306a36Sopenharmony_ci#else	/* !CONFIG_DCACHE_WORD_ACCESS: Slow, byte-at-a-time version */
219262306a36Sopenharmony_ci
219362306a36Sopenharmony_ci/* Return the hash of a string of known length */
219462306a36Sopenharmony_ciunsigned int full_name_hash(const void *salt, const char *name, unsigned int len)
219562306a36Sopenharmony_ci{
219662306a36Sopenharmony_ci	unsigned long hash = init_name_hash(salt);
219762306a36Sopenharmony_ci	while (len--)
219862306a36Sopenharmony_ci		hash = partial_name_hash((unsigned char)*name++, hash);
219962306a36Sopenharmony_ci	return end_name_hash(hash);
220062306a36Sopenharmony_ci}
220162306a36Sopenharmony_ciEXPORT_SYMBOL(full_name_hash);
220262306a36Sopenharmony_ci
220362306a36Sopenharmony_ci/* Return the "hash_len" (hash and length) of a null-terminated string */
220462306a36Sopenharmony_ciu64 hashlen_string(const void *salt, const char *name)
220562306a36Sopenharmony_ci{
220662306a36Sopenharmony_ci	unsigned long hash = init_name_hash(salt);
220762306a36Sopenharmony_ci	unsigned long len = 0, c;
220862306a36Sopenharmony_ci
220962306a36Sopenharmony_ci	c = (unsigned char)*name;
221062306a36Sopenharmony_ci	while (c) {
221162306a36Sopenharmony_ci		len++;
221262306a36Sopenharmony_ci		hash = partial_name_hash(c, hash);
221362306a36Sopenharmony_ci		c = (unsigned char)name[len];
221462306a36Sopenharmony_ci	}
221562306a36Sopenharmony_ci	return hashlen_create(end_name_hash(hash), len);
221662306a36Sopenharmony_ci}
221762306a36Sopenharmony_ciEXPORT_SYMBOL(hashlen_string);
221862306a36Sopenharmony_ci
221962306a36Sopenharmony_ci/*
222062306a36Sopenharmony_ci * We know there's a real path component here of at least
222162306a36Sopenharmony_ci * one character.
222262306a36Sopenharmony_ci */
222362306a36Sopenharmony_cistatic inline u64 hash_name(const void *salt, const char *name)
222462306a36Sopenharmony_ci{
222562306a36Sopenharmony_ci	unsigned long hash = init_name_hash(salt);
222662306a36Sopenharmony_ci	unsigned long len = 0, c;
222762306a36Sopenharmony_ci
222862306a36Sopenharmony_ci	c = (unsigned char)*name;
222962306a36Sopenharmony_ci	do {
223062306a36Sopenharmony_ci		len++;
223162306a36Sopenharmony_ci		hash = partial_name_hash(c, hash);
223262306a36Sopenharmony_ci		c = (unsigned char)name[len];
223362306a36Sopenharmony_ci	} while (c && c != '/');
223462306a36Sopenharmony_ci	return hashlen_create(end_name_hash(hash), len);
223562306a36Sopenharmony_ci}
223662306a36Sopenharmony_ci
223762306a36Sopenharmony_ci#endif
223862306a36Sopenharmony_ci
223962306a36Sopenharmony_ci/*
224062306a36Sopenharmony_ci * Name resolution.
224162306a36Sopenharmony_ci * This is the basic name resolution function, turning a pathname into
224262306a36Sopenharmony_ci * the final dentry. We expect 'base' to be positive and a directory.
224362306a36Sopenharmony_ci *
224462306a36Sopenharmony_ci * Returns 0 and nd will have valid dentry and mnt on success.
224562306a36Sopenharmony_ci * Returns error and drops reference to input namei data on failure.
224662306a36Sopenharmony_ci */
224762306a36Sopenharmony_cistatic int link_path_walk(const char *name, struct nameidata *nd)
224862306a36Sopenharmony_ci{
224962306a36Sopenharmony_ci	int depth = 0; // depth <= nd->depth
225062306a36Sopenharmony_ci	int err;
225162306a36Sopenharmony_ci
225262306a36Sopenharmony_ci	nd->last_type = LAST_ROOT;
225362306a36Sopenharmony_ci	nd->flags |= LOOKUP_PARENT;
225462306a36Sopenharmony_ci	if (IS_ERR(name))
225562306a36Sopenharmony_ci		return PTR_ERR(name);
225662306a36Sopenharmony_ci	while (*name=='/')
225762306a36Sopenharmony_ci		name++;
225862306a36Sopenharmony_ci	if (!*name) {
225962306a36Sopenharmony_ci		nd->dir_mode = 0; // short-circuit the 'hardening' idiocy
226062306a36Sopenharmony_ci		return 0;
226162306a36Sopenharmony_ci	}
226262306a36Sopenharmony_ci
226362306a36Sopenharmony_ci	/* At this point we know we have a real path component. */
226462306a36Sopenharmony_ci	for(;;) {
226562306a36Sopenharmony_ci		struct mnt_idmap *idmap;
226662306a36Sopenharmony_ci		const char *link;
226762306a36Sopenharmony_ci		u64 hash_len;
226862306a36Sopenharmony_ci		int type;
226962306a36Sopenharmony_ci
227062306a36Sopenharmony_ci		idmap = mnt_idmap(nd->path.mnt);
227162306a36Sopenharmony_ci		err = may_lookup(idmap, nd);
227262306a36Sopenharmony_ci		if (err)
227362306a36Sopenharmony_ci			return err;
227462306a36Sopenharmony_ci
227562306a36Sopenharmony_ci		hash_len = hash_name(nd->path.dentry, name);
227662306a36Sopenharmony_ci
227762306a36Sopenharmony_ci		type = LAST_NORM;
227862306a36Sopenharmony_ci		if (name[0] == '.') switch (hashlen_len(hash_len)) {
227962306a36Sopenharmony_ci			case 2:
228062306a36Sopenharmony_ci				if (name[1] == '.') {
228162306a36Sopenharmony_ci					type = LAST_DOTDOT;
228262306a36Sopenharmony_ci					nd->state |= ND_JUMPED;
228362306a36Sopenharmony_ci				}
228462306a36Sopenharmony_ci				break;
228562306a36Sopenharmony_ci			case 1:
228662306a36Sopenharmony_ci				type = LAST_DOT;
228762306a36Sopenharmony_ci		}
228862306a36Sopenharmony_ci		if (likely(type == LAST_NORM)) {
228962306a36Sopenharmony_ci			struct dentry *parent = nd->path.dentry;
229062306a36Sopenharmony_ci			nd->state &= ~ND_JUMPED;
229162306a36Sopenharmony_ci			if (unlikely(parent->d_flags & DCACHE_OP_HASH)) {
229262306a36Sopenharmony_ci				struct qstr this = { { .hash_len = hash_len }, .name = name };
229362306a36Sopenharmony_ci				err = parent->d_op->d_hash(parent, &this);
229462306a36Sopenharmony_ci				if (err < 0)
229562306a36Sopenharmony_ci					return err;
229662306a36Sopenharmony_ci				hash_len = this.hash_len;
229762306a36Sopenharmony_ci				name = this.name;
229862306a36Sopenharmony_ci			}
229962306a36Sopenharmony_ci		}
230062306a36Sopenharmony_ci
230162306a36Sopenharmony_ci		nd->last.hash_len = hash_len;
230262306a36Sopenharmony_ci		nd->last.name = name;
230362306a36Sopenharmony_ci		nd->last_type = type;
230462306a36Sopenharmony_ci
230562306a36Sopenharmony_ci		name += hashlen_len(hash_len);
230662306a36Sopenharmony_ci		if (!*name)
230762306a36Sopenharmony_ci			goto OK;
230862306a36Sopenharmony_ci		/*
230962306a36Sopenharmony_ci		 * If it wasn't NUL, we know it was '/'. Skip that
231062306a36Sopenharmony_ci		 * slash, and continue until no more slashes.
231162306a36Sopenharmony_ci		 */
231262306a36Sopenharmony_ci		do {
231362306a36Sopenharmony_ci			name++;
231462306a36Sopenharmony_ci		} while (unlikely(*name == '/'));
231562306a36Sopenharmony_ci		if (unlikely(!*name)) {
231662306a36Sopenharmony_ciOK:
231762306a36Sopenharmony_ci			/* pathname or trailing symlink, done */
231862306a36Sopenharmony_ci			if (!depth) {
231962306a36Sopenharmony_ci				nd->dir_vfsuid = i_uid_into_vfsuid(idmap, nd->inode);
232062306a36Sopenharmony_ci				nd->dir_mode = nd->inode->i_mode;
232162306a36Sopenharmony_ci				nd->flags &= ~LOOKUP_PARENT;
232262306a36Sopenharmony_ci				return 0;
232362306a36Sopenharmony_ci			}
232462306a36Sopenharmony_ci			/* last component of nested symlink */
232562306a36Sopenharmony_ci			name = nd->stack[--depth].name;
232662306a36Sopenharmony_ci			link = walk_component(nd, 0);
232762306a36Sopenharmony_ci		} else {
232862306a36Sopenharmony_ci			/* not the last component */
232962306a36Sopenharmony_ci			link = walk_component(nd, WALK_MORE);
233062306a36Sopenharmony_ci		}
233162306a36Sopenharmony_ci		if (unlikely(link)) {
233262306a36Sopenharmony_ci			if (IS_ERR(link))
233362306a36Sopenharmony_ci				return PTR_ERR(link);
233462306a36Sopenharmony_ci			/* a symlink to follow */
233562306a36Sopenharmony_ci			nd->stack[depth++].name = name;
233662306a36Sopenharmony_ci			name = link;
233762306a36Sopenharmony_ci			continue;
233862306a36Sopenharmony_ci		}
233962306a36Sopenharmony_ci		if (unlikely(!d_can_lookup(nd->path.dentry))) {
234062306a36Sopenharmony_ci			if (nd->flags & LOOKUP_RCU) {
234162306a36Sopenharmony_ci				if (!try_to_unlazy(nd))
234262306a36Sopenharmony_ci					return -ECHILD;
234362306a36Sopenharmony_ci			}
234462306a36Sopenharmony_ci			return -ENOTDIR;
234562306a36Sopenharmony_ci		}
234662306a36Sopenharmony_ci	}
234762306a36Sopenharmony_ci}
234862306a36Sopenharmony_ci
234962306a36Sopenharmony_ci/* must be paired with terminate_walk() */
235062306a36Sopenharmony_cistatic const char *path_init(struct nameidata *nd, unsigned flags)
235162306a36Sopenharmony_ci{
235262306a36Sopenharmony_ci	int error;
235362306a36Sopenharmony_ci	const char *s = nd->name->name;
235462306a36Sopenharmony_ci
235562306a36Sopenharmony_ci	/* LOOKUP_CACHED requires RCU, ask caller to retry */
235662306a36Sopenharmony_ci	if ((flags & (LOOKUP_RCU | LOOKUP_CACHED)) == LOOKUP_CACHED)
235762306a36Sopenharmony_ci		return ERR_PTR(-EAGAIN);
235862306a36Sopenharmony_ci
235962306a36Sopenharmony_ci	if (!*s)
236062306a36Sopenharmony_ci		flags &= ~LOOKUP_RCU;
236162306a36Sopenharmony_ci	if (flags & LOOKUP_RCU)
236262306a36Sopenharmony_ci		rcu_read_lock();
236362306a36Sopenharmony_ci	else
236462306a36Sopenharmony_ci		nd->seq = nd->next_seq = 0;
236562306a36Sopenharmony_ci
236662306a36Sopenharmony_ci	nd->flags = flags;
236762306a36Sopenharmony_ci	nd->state |= ND_JUMPED;
236862306a36Sopenharmony_ci
236962306a36Sopenharmony_ci	nd->m_seq = __read_seqcount_begin(&mount_lock.seqcount);
237062306a36Sopenharmony_ci	nd->r_seq = __read_seqcount_begin(&rename_lock.seqcount);
237162306a36Sopenharmony_ci	smp_rmb();
237262306a36Sopenharmony_ci
237362306a36Sopenharmony_ci	if (nd->state & ND_ROOT_PRESET) {
237462306a36Sopenharmony_ci		struct dentry *root = nd->root.dentry;
237562306a36Sopenharmony_ci		struct inode *inode = root->d_inode;
237662306a36Sopenharmony_ci		if (*s && unlikely(!d_can_lookup(root)))
237762306a36Sopenharmony_ci			return ERR_PTR(-ENOTDIR);
237862306a36Sopenharmony_ci		nd->path = nd->root;
237962306a36Sopenharmony_ci		nd->inode = inode;
238062306a36Sopenharmony_ci		if (flags & LOOKUP_RCU) {
238162306a36Sopenharmony_ci			nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
238262306a36Sopenharmony_ci			nd->root_seq = nd->seq;
238362306a36Sopenharmony_ci		} else {
238462306a36Sopenharmony_ci			path_get(&nd->path);
238562306a36Sopenharmony_ci		}
238662306a36Sopenharmony_ci		return s;
238762306a36Sopenharmony_ci	}
238862306a36Sopenharmony_ci
238962306a36Sopenharmony_ci	nd->root.mnt = NULL;
239062306a36Sopenharmony_ci
239162306a36Sopenharmony_ci	/* Absolute pathname -- fetch the root (LOOKUP_IN_ROOT uses nd->dfd). */
239262306a36Sopenharmony_ci	if (*s == '/' && !(flags & LOOKUP_IN_ROOT)) {
239362306a36Sopenharmony_ci		error = nd_jump_root(nd);
239462306a36Sopenharmony_ci		if (unlikely(error))
239562306a36Sopenharmony_ci			return ERR_PTR(error);
239662306a36Sopenharmony_ci		return s;
239762306a36Sopenharmony_ci	}
239862306a36Sopenharmony_ci
239962306a36Sopenharmony_ci	/* Relative pathname -- get the starting-point it is relative to. */
240062306a36Sopenharmony_ci	if (nd->dfd == AT_FDCWD) {
240162306a36Sopenharmony_ci		if (flags & LOOKUP_RCU) {
240262306a36Sopenharmony_ci			struct fs_struct *fs = current->fs;
240362306a36Sopenharmony_ci			unsigned seq;
240462306a36Sopenharmony_ci
240562306a36Sopenharmony_ci			do {
240662306a36Sopenharmony_ci				seq = read_seqcount_begin(&fs->seq);
240762306a36Sopenharmony_ci				nd->path = fs->pwd;
240862306a36Sopenharmony_ci				nd->inode = nd->path.dentry->d_inode;
240962306a36Sopenharmony_ci				nd->seq = __read_seqcount_begin(&nd->path.dentry->d_seq);
241062306a36Sopenharmony_ci			} while (read_seqcount_retry(&fs->seq, seq));
241162306a36Sopenharmony_ci		} else {
241262306a36Sopenharmony_ci			get_fs_pwd(current->fs, &nd->path);
241362306a36Sopenharmony_ci			nd->inode = nd->path.dentry->d_inode;
241462306a36Sopenharmony_ci		}
241562306a36Sopenharmony_ci	} else {
241662306a36Sopenharmony_ci		/* Caller must check execute permissions on the starting path component */
241762306a36Sopenharmony_ci		struct fd f = fdget_raw(nd->dfd);
241862306a36Sopenharmony_ci		struct dentry *dentry;
241962306a36Sopenharmony_ci
242062306a36Sopenharmony_ci		if (!f.file)
242162306a36Sopenharmony_ci			return ERR_PTR(-EBADF);
242262306a36Sopenharmony_ci
242362306a36Sopenharmony_ci		dentry = f.file->f_path.dentry;
242462306a36Sopenharmony_ci
242562306a36Sopenharmony_ci		if (*s && unlikely(!d_can_lookup(dentry))) {
242662306a36Sopenharmony_ci			fdput(f);
242762306a36Sopenharmony_ci			return ERR_PTR(-ENOTDIR);
242862306a36Sopenharmony_ci		}
242962306a36Sopenharmony_ci
243062306a36Sopenharmony_ci		nd->path = f.file->f_path;
243162306a36Sopenharmony_ci		if (flags & LOOKUP_RCU) {
243262306a36Sopenharmony_ci			nd->inode = nd->path.dentry->d_inode;
243362306a36Sopenharmony_ci			nd->seq = read_seqcount_begin(&nd->path.dentry->d_seq);
243462306a36Sopenharmony_ci		} else {
243562306a36Sopenharmony_ci			path_get(&nd->path);
243662306a36Sopenharmony_ci			nd->inode = nd->path.dentry->d_inode;
243762306a36Sopenharmony_ci		}
243862306a36Sopenharmony_ci		fdput(f);
243962306a36Sopenharmony_ci	}
244062306a36Sopenharmony_ci
244162306a36Sopenharmony_ci	/* For scoped-lookups we need to set the root to the dirfd as well. */
244262306a36Sopenharmony_ci	if (flags & LOOKUP_IS_SCOPED) {
244362306a36Sopenharmony_ci		nd->root = nd->path;
244462306a36Sopenharmony_ci		if (flags & LOOKUP_RCU) {
244562306a36Sopenharmony_ci			nd->root_seq = nd->seq;
244662306a36Sopenharmony_ci		} else {
244762306a36Sopenharmony_ci			path_get(&nd->root);
244862306a36Sopenharmony_ci			nd->state |= ND_ROOT_GRABBED;
244962306a36Sopenharmony_ci		}
245062306a36Sopenharmony_ci	}
245162306a36Sopenharmony_ci	return s;
245262306a36Sopenharmony_ci}
245362306a36Sopenharmony_ci
245462306a36Sopenharmony_cistatic inline const char *lookup_last(struct nameidata *nd)
245562306a36Sopenharmony_ci{
245662306a36Sopenharmony_ci	if (nd->last_type == LAST_NORM && nd->last.name[nd->last.len])
245762306a36Sopenharmony_ci		nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
245862306a36Sopenharmony_ci
245962306a36Sopenharmony_ci	return walk_component(nd, WALK_TRAILING);
246062306a36Sopenharmony_ci}
246162306a36Sopenharmony_ci
246262306a36Sopenharmony_cistatic int handle_lookup_down(struct nameidata *nd)
246362306a36Sopenharmony_ci{
246462306a36Sopenharmony_ci	if (!(nd->flags & LOOKUP_RCU))
246562306a36Sopenharmony_ci		dget(nd->path.dentry);
246662306a36Sopenharmony_ci	nd->next_seq = nd->seq;
246762306a36Sopenharmony_ci	return PTR_ERR(step_into(nd, WALK_NOFOLLOW, nd->path.dentry));
246862306a36Sopenharmony_ci}
246962306a36Sopenharmony_ci
247062306a36Sopenharmony_ci/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
247162306a36Sopenharmony_cistatic int path_lookupat(struct nameidata *nd, unsigned flags, struct path *path)
247262306a36Sopenharmony_ci{
247362306a36Sopenharmony_ci	const char *s = path_init(nd, flags);
247462306a36Sopenharmony_ci	int err;
247562306a36Sopenharmony_ci
247662306a36Sopenharmony_ci	if (unlikely(flags & LOOKUP_DOWN) && !IS_ERR(s)) {
247762306a36Sopenharmony_ci		err = handle_lookup_down(nd);
247862306a36Sopenharmony_ci		if (unlikely(err < 0))
247962306a36Sopenharmony_ci			s = ERR_PTR(err);
248062306a36Sopenharmony_ci	}
248162306a36Sopenharmony_ci
248262306a36Sopenharmony_ci	while (!(err = link_path_walk(s, nd)) &&
248362306a36Sopenharmony_ci	       (s = lookup_last(nd)) != NULL)
248462306a36Sopenharmony_ci		;
248562306a36Sopenharmony_ci	if (!err && unlikely(nd->flags & LOOKUP_MOUNTPOINT)) {
248662306a36Sopenharmony_ci		err = handle_lookup_down(nd);
248762306a36Sopenharmony_ci		nd->state &= ~ND_JUMPED; // no d_weak_revalidate(), please...
248862306a36Sopenharmony_ci	}
248962306a36Sopenharmony_ci	if (!err)
249062306a36Sopenharmony_ci		err = complete_walk(nd);
249162306a36Sopenharmony_ci
249262306a36Sopenharmony_ci	if (!err && nd->flags & LOOKUP_DIRECTORY)
249362306a36Sopenharmony_ci		if (!d_can_lookup(nd->path.dentry))
249462306a36Sopenharmony_ci			err = -ENOTDIR;
249562306a36Sopenharmony_ci	if (!err) {
249662306a36Sopenharmony_ci		*path = nd->path;
249762306a36Sopenharmony_ci		nd->path.mnt = NULL;
249862306a36Sopenharmony_ci		nd->path.dentry = NULL;
249962306a36Sopenharmony_ci	}
250062306a36Sopenharmony_ci	terminate_walk(nd);
250162306a36Sopenharmony_ci	return err;
250262306a36Sopenharmony_ci}
250362306a36Sopenharmony_ci
250462306a36Sopenharmony_ciint filename_lookup(int dfd, struct filename *name, unsigned flags,
250562306a36Sopenharmony_ci		    struct path *path, struct path *root)
250662306a36Sopenharmony_ci{
250762306a36Sopenharmony_ci	int retval;
250862306a36Sopenharmony_ci	struct nameidata nd;
250962306a36Sopenharmony_ci	if (IS_ERR(name))
251062306a36Sopenharmony_ci		return PTR_ERR(name);
251162306a36Sopenharmony_ci	set_nameidata(&nd, dfd, name, root);
251262306a36Sopenharmony_ci	retval = path_lookupat(&nd, flags | LOOKUP_RCU, path);
251362306a36Sopenharmony_ci	if (unlikely(retval == -ECHILD))
251462306a36Sopenharmony_ci		retval = path_lookupat(&nd, flags, path);
251562306a36Sopenharmony_ci	if (unlikely(retval == -ESTALE))
251662306a36Sopenharmony_ci		retval = path_lookupat(&nd, flags | LOOKUP_REVAL, path);
251762306a36Sopenharmony_ci
251862306a36Sopenharmony_ci	if (likely(!retval))
251962306a36Sopenharmony_ci		audit_inode(name, path->dentry,
252062306a36Sopenharmony_ci			    flags & LOOKUP_MOUNTPOINT ? AUDIT_INODE_NOEVAL : 0);
252162306a36Sopenharmony_ci	restore_nameidata();
252262306a36Sopenharmony_ci	return retval;
252362306a36Sopenharmony_ci}
252462306a36Sopenharmony_ci
252562306a36Sopenharmony_ci/* Returns 0 and nd will be valid on success; Retuns error, otherwise. */
252662306a36Sopenharmony_cistatic int path_parentat(struct nameidata *nd, unsigned flags,
252762306a36Sopenharmony_ci				struct path *parent)
252862306a36Sopenharmony_ci{
252962306a36Sopenharmony_ci	const char *s = path_init(nd, flags);
253062306a36Sopenharmony_ci	int err = link_path_walk(s, nd);
253162306a36Sopenharmony_ci	if (!err)
253262306a36Sopenharmony_ci		err = complete_walk(nd);
253362306a36Sopenharmony_ci	if (!err) {
253462306a36Sopenharmony_ci		*parent = nd->path;
253562306a36Sopenharmony_ci		nd->path.mnt = NULL;
253662306a36Sopenharmony_ci		nd->path.dentry = NULL;
253762306a36Sopenharmony_ci	}
253862306a36Sopenharmony_ci	terminate_walk(nd);
253962306a36Sopenharmony_ci	return err;
254062306a36Sopenharmony_ci}
254162306a36Sopenharmony_ci
254262306a36Sopenharmony_ci/* Note: this does not consume "name" */
254362306a36Sopenharmony_cistatic int __filename_parentat(int dfd, struct filename *name,
254462306a36Sopenharmony_ci			       unsigned int flags, struct path *parent,
254562306a36Sopenharmony_ci			       struct qstr *last, int *type,
254662306a36Sopenharmony_ci			       const struct path *root)
254762306a36Sopenharmony_ci{
254862306a36Sopenharmony_ci	int retval;
254962306a36Sopenharmony_ci	struct nameidata nd;
255062306a36Sopenharmony_ci
255162306a36Sopenharmony_ci	if (IS_ERR(name))
255262306a36Sopenharmony_ci		return PTR_ERR(name);
255362306a36Sopenharmony_ci	set_nameidata(&nd, dfd, name, root);
255462306a36Sopenharmony_ci	retval = path_parentat(&nd, flags | LOOKUP_RCU, parent);
255562306a36Sopenharmony_ci	if (unlikely(retval == -ECHILD))
255662306a36Sopenharmony_ci		retval = path_parentat(&nd, flags, parent);
255762306a36Sopenharmony_ci	if (unlikely(retval == -ESTALE))
255862306a36Sopenharmony_ci		retval = path_parentat(&nd, flags | LOOKUP_REVAL, parent);
255962306a36Sopenharmony_ci	if (likely(!retval)) {
256062306a36Sopenharmony_ci		*last = nd.last;
256162306a36Sopenharmony_ci		*type = nd.last_type;
256262306a36Sopenharmony_ci		audit_inode(name, parent->dentry, AUDIT_INODE_PARENT);
256362306a36Sopenharmony_ci	}
256462306a36Sopenharmony_ci	restore_nameidata();
256562306a36Sopenharmony_ci	return retval;
256662306a36Sopenharmony_ci}
256762306a36Sopenharmony_ci
256862306a36Sopenharmony_cistatic int filename_parentat(int dfd, struct filename *name,
256962306a36Sopenharmony_ci			     unsigned int flags, struct path *parent,
257062306a36Sopenharmony_ci			     struct qstr *last, int *type)
257162306a36Sopenharmony_ci{
257262306a36Sopenharmony_ci	return __filename_parentat(dfd, name, flags, parent, last, type, NULL);
257362306a36Sopenharmony_ci}
257462306a36Sopenharmony_ci
257562306a36Sopenharmony_ci/* does lookup, returns the object with parent locked */
257662306a36Sopenharmony_cistatic struct dentry *__kern_path_locked(struct filename *name, struct path *path)
257762306a36Sopenharmony_ci{
257862306a36Sopenharmony_ci	struct dentry *d;
257962306a36Sopenharmony_ci	struct qstr last;
258062306a36Sopenharmony_ci	int type, error;
258162306a36Sopenharmony_ci
258262306a36Sopenharmony_ci	error = filename_parentat(AT_FDCWD, name, 0, path, &last, &type);
258362306a36Sopenharmony_ci	if (error)
258462306a36Sopenharmony_ci		return ERR_PTR(error);
258562306a36Sopenharmony_ci	if (unlikely(type != LAST_NORM)) {
258662306a36Sopenharmony_ci		path_put(path);
258762306a36Sopenharmony_ci		return ERR_PTR(-EINVAL);
258862306a36Sopenharmony_ci	}
258962306a36Sopenharmony_ci	inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
259062306a36Sopenharmony_ci	d = lookup_one_qstr_excl(&last, path->dentry, 0);
259162306a36Sopenharmony_ci	if (IS_ERR(d)) {
259262306a36Sopenharmony_ci		inode_unlock(path->dentry->d_inode);
259362306a36Sopenharmony_ci		path_put(path);
259462306a36Sopenharmony_ci	}
259562306a36Sopenharmony_ci	return d;
259662306a36Sopenharmony_ci}
259762306a36Sopenharmony_ci
259862306a36Sopenharmony_cistruct dentry *kern_path_locked(const char *name, struct path *path)
259962306a36Sopenharmony_ci{
260062306a36Sopenharmony_ci	struct filename *filename = getname_kernel(name);
260162306a36Sopenharmony_ci	struct dentry *res = __kern_path_locked(filename, path);
260262306a36Sopenharmony_ci
260362306a36Sopenharmony_ci	putname(filename);
260462306a36Sopenharmony_ci	return res;
260562306a36Sopenharmony_ci}
260662306a36Sopenharmony_ci
260762306a36Sopenharmony_ciint kern_path(const char *name, unsigned int flags, struct path *path)
260862306a36Sopenharmony_ci{
260962306a36Sopenharmony_ci	struct filename *filename = getname_kernel(name);
261062306a36Sopenharmony_ci	int ret = filename_lookup(AT_FDCWD, filename, flags, path, NULL);
261162306a36Sopenharmony_ci
261262306a36Sopenharmony_ci	putname(filename);
261362306a36Sopenharmony_ci	return ret;
261462306a36Sopenharmony_ci
261562306a36Sopenharmony_ci}
261662306a36Sopenharmony_ciEXPORT_SYMBOL(kern_path);
261762306a36Sopenharmony_ci
261862306a36Sopenharmony_ci/**
261962306a36Sopenharmony_ci * vfs_path_parent_lookup - lookup a parent path relative to a dentry-vfsmount pair
262062306a36Sopenharmony_ci * @filename: filename structure
262162306a36Sopenharmony_ci * @flags: lookup flags
262262306a36Sopenharmony_ci * @parent: pointer to struct path to fill
262362306a36Sopenharmony_ci * @last: last component
262462306a36Sopenharmony_ci * @type: type of the last component
262562306a36Sopenharmony_ci * @root: pointer to struct path of the base directory
262662306a36Sopenharmony_ci */
262762306a36Sopenharmony_ciint vfs_path_parent_lookup(struct filename *filename, unsigned int flags,
262862306a36Sopenharmony_ci			   struct path *parent, struct qstr *last, int *type,
262962306a36Sopenharmony_ci			   const struct path *root)
263062306a36Sopenharmony_ci{
263162306a36Sopenharmony_ci	return  __filename_parentat(AT_FDCWD, filename, flags, parent, last,
263262306a36Sopenharmony_ci				    type, root);
263362306a36Sopenharmony_ci}
263462306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_path_parent_lookup);
263562306a36Sopenharmony_ci
263662306a36Sopenharmony_ci/**
263762306a36Sopenharmony_ci * vfs_path_lookup - lookup a file path relative to a dentry-vfsmount pair
263862306a36Sopenharmony_ci * @dentry:  pointer to dentry of the base directory
263962306a36Sopenharmony_ci * @mnt: pointer to vfs mount of the base directory
264062306a36Sopenharmony_ci * @name: pointer to file name
264162306a36Sopenharmony_ci * @flags: lookup flags
264262306a36Sopenharmony_ci * @path: pointer to struct path to fill
264362306a36Sopenharmony_ci */
264462306a36Sopenharmony_ciint vfs_path_lookup(struct dentry *dentry, struct vfsmount *mnt,
264562306a36Sopenharmony_ci		    const char *name, unsigned int flags,
264662306a36Sopenharmony_ci		    struct path *path)
264762306a36Sopenharmony_ci{
264862306a36Sopenharmony_ci	struct filename *filename;
264962306a36Sopenharmony_ci	struct path root = {.mnt = mnt, .dentry = dentry};
265062306a36Sopenharmony_ci	int ret;
265162306a36Sopenharmony_ci
265262306a36Sopenharmony_ci	filename = getname_kernel(name);
265362306a36Sopenharmony_ci	/* the first argument of filename_lookup() is ignored with root */
265462306a36Sopenharmony_ci	ret = filename_lookup(AT_FDCWD, filename, flags, path, &root);
265562306a36Sopenharmony_ci	putname(filename);
265662306a36Sopenharmony_ci	return ret;
265762306a36Sopenharmony_ci}
265862306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_path_lookup);
265962306a36Sopenharmony_ci
266062306a36Sopenharmony_cistatic int lookup_one_common(struct mnt_idmap *idmap,
266162306a36Sopenharmony_ci			     const char *name, struct dentry *base, int len,
266262306a36Sopenharmony_ci			     struct qstr *this)
266362306a36Sopenharmony_ci{
266462306a36Sopenharmony_ci	this->name = name;
266562306a36Sopenharmony_ci	this->len = len;
266662306a36Sopenharmony_ci	this->hash = full_name_hash(base, name, len);
266762306a36Sopenharmony_ci	if (!len)
266862306a36Sopenharmony_ci		return -EACCES;
266962306a36Sopenharmony_ci
267062306a36Sopenharmony_ci	if (unlikely(name[0] == '.')) {
267162306a36Sopenharmony_ci		if (len < 2 || (len == 2 && name[1] == '.'))
267262306a36Sopenharmony_ci			return -EACCES;
267362306a36Sopenharmony_ci	}
267462306a36Sopenharmony_ci
267562306a36Sopenharmony_ci	while (len--) {
267662306a36Sopenharmony_ci		unsigned int c = *(const unsigned char *)name++;
267762306a36Sopenharmony_ci		if (c == '/' || c == '\0')
267862306a36Sopenharmony_ci			return -EACCES;
267962306a36Sopenharmony_ci	}
268062306a36Sopenharmony_ci	/*
268162306a36Sopenharmony_ci	 * See if the low-level filesystem might want
268262306a36Sopenharmony_ci	 * to use its own hash..
268362306a36Sopenharmony_ci	 */
268462306a36Sopenharmony_ci	if (base->d_flags & DCACHE_OP_HASH) {
268562306a36Sopenharmony_ci		int err = base->d_op->d_hash(base, this);
268662306a36Sopenharmony_ci		if (err < 0)
268762306a36Sopenharmony_ci			return err;
268862306a36Sopenharmony_ci	}
268962306a36Sopenharmony_ci
269062306a36Sopenharmony_ci	return inode_permission(idmap, base->d_inode, MAY_EXEC);
269162306a36Sopenharmony_ci}
269262306a36Sopenharmony_ci
269362306a36Sopenharmony_ci/**
269462306a36Sopenharmony_ci * try_lookup_one_len - filesystem helper to lookup single pathname component
269562306a36Sopenharmony_ci * @name:	pathname component to lookup
269662306a36Sopenharmony_ci * @base:	base directory to lookup from
269762306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
269862306a36Sopenharmony_ci *
269962306a36Sopenharmony_ci * Look up a dentry by name in the dcache, returning NULL if it does not
270062306a36Sopenharmony_ci * currently exist.  The function does not try to create a dentry.
270162306a36Sopenharmony_ci *
270262306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
270362306a36Sopenharmony_ci * not be called by generic code.
270462306a36Sopenharmony_ci *
270562306a36Sopenharmony_ci * The caller must hold base->i_mutex.
270662306a36Sopenharmony_ci */
270762306a36Sopenharmony_cistruct dentry *try_lookup_one_len(const char *name, struct dentry *base, int len)
270862306a36Sopenharmony_ci{
270962306a36Sopenharmony_ci	struct qstr this;
271062306a36Sopenharmony_ci	int err;
271162306a36Sopenharmony_ci
271262306a36Sopenharmony_ci	WARN_ON_ONCE(!inode_is_locked(base->d_inode));
271362306a36Sopenharmony_ci
271462306a36Sopenharmony_ci	err = lookup_one_common(&nop_mnt_idmap, name, base, len, &this);
271562306a36Sopenharmony_ci	if (err)
271662306a36Sopenharmony_ci		return ERR_PTR(err);
271762306a36Sopenharmony_ci
271862306a36Sopenharmony_ci	return lookup_dcache(&this, base, 0);
271962306a36Sopenharmony_ci}
272062306a36Sopenharmony_ciEXPORT_SYMBOL(try_lookup_one_len);
272162306a36Sopenharmony_ci
272262306a36Sopenharmony_ci/**
272362306a36Sopenharmony_ci * lookup_one_len - filesystem helper to lookup single pathname component
272462306a36Sopenharmony_ci * @name:	pathname component to lookup
272562306a36Sopenharmony_ci * @base:	base directory to lookup from
272662306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
272762306a36Sopenharmony_ci *
272862306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
272962306a36Sopenharmony_ci * not be called by generic code.
273062306a36Sopenharmony_ci *
273162306a36Sopenharmony_ci * The caller must hold base->i_mutex.
273262306a36Sopenharmony_ci */
273362306a36Sopenharmony_cistruct dentry *lookup_one_len(const char *name, struct dentry *base, int len)
273462306a36Sopenharmony_ci{
273562306a36Sopenharmony_ci	struct dentry *dentry;
273662306a36Sopenharmony_ci	struct qstr this;
273762306a36Sopenharmony_ci	int err;
273862306a36Sopenharmony_ci
273962306a36Sopenharmony_ci	WARN_ON_ONCE(!inode_is_locked(base->d_inode));
274062306a36Sopenharmony_ci
274162306a36Sopenharmony_ci	err = lookup_one_common(&nop_mnt_idmap, name, base, len, &this);
274262306a36Sopenharmony_ci	if (err)
274362306a36Sopenharmony_ci		return ERR_PTR(err);
274462306a36Sopenharmony_ci
274562306a36Sopenharmony_ci	dentry = lookup_dcache(&this, base, 0);
274662306a36Sopenharmony_ci	return dentry ? dentry : __lookup_slow(&this, base, 0);
274762306a36Sopenharmony_ci}
274862306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one_len);
274962306a36Sopenharmony_ci
275062306a36Sopenharmony_ci/**
275162306a36Sopenharmony_ci * lookup_one - filesystem helper to lookup single pathname component
275262306a36Sopenharmony_ci * @idmap:	idmap of the mount the lookup is performed from
275362306a36Sopenharmony_ci * @name:	pathname component to lookup
275462306a36Sopenharmony_ci * @base:	base directory to lookup from
275562306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
275662306a36Sopenharmony_ci *
275762306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
275862306a36Sopenharmony_ci * not be called by generic code.
275962306a36Sopenharmony_ci *
276062306a36Sopenharmony_ci * The caller must hold base->i_mutex.
276162306a36Sopenharmony_ci */
276262306a36Sopenharmony_cistruct dentry *lookup_one(struct mnt_idmap *idmap, const char *name,
276362306a36Sopenharmony_ci			  struct dentry *base, int len)
276462306a36Sopenharmony_ci{
276562306a36Sopenharmony_ci	struct dentry *dentry;
276662306a36Sopenharmony_ci	struct qstr this;
276762306a36Sopenharmony_ci	int err;
276862306a36Sopenharmony_ci
276962306a36Sopenharmony_ci	WARN_ON_ONCE(!inode_is_locked(base->d_inode));
277062306a36Sopenharmony_ci
277162306a36Sopenharmony_ci	err = lookup_one_common(idmap, name, base, len, &this);
277262306a36Sopenharmony_ci	if (err)
277362306a36Sopenharmony_ci		return ERR_PTR(err);
277462306a36Sopenharmony_ci
277562306a36Sopenharmony_ci	dentry = lookup_dcache(&this, base, 0);
277662306a36Sopenharmony_ci	return dentry ? dentry : __lookup_slow(&this, base, 0);
277762306a36Sopenharmony_ci}
277862306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one);
277962306a36Sopenharmony_ci
278062306a36Sopenharmony_ci/**
278162306a36Sopenharmony_ci * lookup_one_unlocked - filesystem helper to lookup single pathname component
278262306a36Sopenharmony_ci * @idmap:	idmap of the mount the lookup is performed from
278362306a36Sopenharmony_ci * @name:	pathname component to lookup
278462306a36Sopenharmony_ci * @base:	base directory to lookup from
278562306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
278662306a36Sopenharmony_ci *
278762306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
278862306a36Sopenharmony_ci * not be called by generic code.
278962306a36Sopenharmony_ci *
279062306a36Sopenharmony_ci * Unlike lookup_one_len, it should be called without the parent
279162306a36Sopenharmony_ci * i_mutex held, and will take the i_mutex itself if necessary.
279262306a36Sopenharmony_ci */
279362306a36Sopenharmony_cistruct dentry *lookup_one_unlocked(struct mnt_idmap *idmap,
279462306a36Sopenharmony_ci				   const char *name, struct dentry *base,
279562306a36Sopenharmony_ci				   int len)
279662306a36Sopenharmony_ci{
279762306a36Sopenharmony_ci	struct qstr this;
279862306a36Sopenharmony_ci	int err;
279962306a36Sopenharmony_ci	struct dentry *ret;
280062306a36Sopenharmony_ci
280162306a36Sopenharmony_ci	err = lookup_one_common(idmap, name, base, len, &this);
280262306a36Sopenharmony_ci	if (err)
280362306a36Sopenharmony_ci		return ERR_PTR(err);
280462306a36Sopenharmony_ci
280562306a36Sopenharmony_ci	ret = lookup_dcache(&this, base, 0);
280662306a36Sopenharmony_ci	if (!ret)
280762306a36Sopenharmony_ci		ret = lookup_slow(&this, base, 0);
280862306a36Sopenharmony_ci	return ret;
280962306a36Sopenharmony_ci}
281062306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one_unlocked);
281162306a36Sopenharmony_ci
281262306a36Sopenharmony_ci/**
281362306a36Sopenharmony_ci * lookup_one_positive_unlocked - filesystem helper to lookup single
281462306a36Sopenharmony_ci *				  pathname component
281562306a36Sopenharmony_ci * @idmap:	idmap of the mount the lookup is performed from
281662306a36Sopenharmony_ci * @name:	pathname component to lookup
281762306a36Sopenharmony_ci * @base:	base directory to lookup from
281862306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
281962306a36Sopenharmony_ci *
282062306a36Sopenharmony_ci * This helper will yield ERR_PTR(-ENOENT) on negatives. The helper returns
282162306a36Sopenharmony_ci * known positive or ERR_PTR(). This is what most of the users want.
282262306a36Sopenharmony_ci *
282362306a36Sopenharmony_ci * Note that pinned negative with unlocked parent _can_ become positive at any
282462306a36Sopenharmony_ci * time, so callers of lookup_one_unlocked() need to be very careful; pinned
282562306a36Sopenharmony_ci * positives have >d_inode stable, so this one avoids such problems.
282662306a36Sopenharmony_ci *
282762306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
282862306a36Sopenharmony_ci * not be called by generic code.
282962306a36Sopenharmony_ci *
283062306a36Sopenharmony_ci * The helper should be called without i_mutex held.
283162306a36Sopenharmony_ci */
283262306a36Sopenharmony_cistruct dentry *lookup_one_positive_unlocked(struct mnt_idmap *idmap,
283362306a36Sopenharmony_ci					    const char *name,
283462306a36Sopenharmony_ci					    struct dentry *base, int len)
283562306a36Sopenharmony_ci{
283662306a36Sopenharmony_ci	struct dentry *ret = lookup_one_unlocked(idmap, name, base, len);
283762306a36Sopenharmony_ci
283862306a36Sopenharmony_ci	if (!IS_ERR(ret) && d_flags_negative(smp_load_acquire(&ret->d_flags))) {
283962306a36Sopenharmony_ci		dput(ret);
284062306a36Sopenharmony_ci		ret = ERR_PTR(-ENOENT);
284162306a36Sopenharmony_ci	}
284262306a36Sopenharmony_ci	return ret;
284362306a36Sopenharmony_ci}
284462306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one_positive_unlocked);
284562306a36Sopenharmony_ci
284662306a36Sopenharmony_ci/**
284762306a36Sopenharmony_ci * lookup_one_len_unlocked - filesystem helper to lookup single pathname component
284862306a36Sopenharmony_ci * @name:	pathname component to lookup
284962306a36Sopenharmony_ci * @base:	base directory to lookup from
285062306a36Sopenharmony_ci * @len:	maximum length @len should be interpreted to
285162306a36Sopenharmony_ci *
285262306a36Sopenharmony_ci * Note that this routine is purely a helper for filesystem usage and should
285362306a36Sopenharmony_ci * not be called by generic code.
285462306a36Sopenharmony_ci *
285562306a36Sopenharmony_ci * Unlike lookup_one_len, it should be called without the parent
285662306a36Sopenharmony_ci * i_mutex held, and will take the i_mutex itself if necessary.
285762306a36Sopenharmony_ci */
285862306a36Sopenharmony_cistruct dentry *lookup_one_len_unlocked(const char *name,
285962306a36Sopenharmony_ci				       struct dentry *base, int len)
286062306a36Sopenharmony_ci{
286162306a36Sopenharmony_ci	return lookup_one_unlocked(&nop_mnt_idmap, name, base, len);
286262306a36Sopenharmony_ci}
286362306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_one_len_unlocked);
286462306a36Sopenharmony_ci
286562306a36Sopenharmony_ci/*
286662306a36Sopenharmony_ci * Like lookup_one_len_unlocked(), except that it yields ERR_PTR(-ENOENT)
286762306a36Sopenharmony_ci * on negatives.  Returns known positive or ERR_PTR(); that's what
286862306a36Sopenharmony_ci * most of the users want.  Note that pinned negative with unlocked parent
286962306a36Sopenharmony_ci * _can_ become positive at any time, so callers of lookup_one_len_unlocked()
287062306a36Sopenharmony_ci * need to be very careful; pinned positives have ->d_inode stable, so
287162306a36Sopenharmony_ci * this one avoids such problems.
287262306a36Sopenharmony_ci */
287362306a36Sopenharmony_cistruct dentry *lookup_positive_unlocked(const char *name,
287462306a36Sopenharmony_ci				       struct dentry *base, int len)
287562306a36Sopenharmony_ci{
287662306a36Sopenharmony_ci	return lookup_one_positive_unlocked(&nop_mnt_idmap, name, base, len);
287762306a36Sopenharmony_ci}
287862306a36Sopenharmony_ciEXPORT_SYMBOL(lookup_positive_unlocked);
287962306a36Sopenharmony_ci
288062306a36Sopenharmony_ci#ifdef CONFIG_UNIX98_PTYS
288162306a36Sopenharmony_ciint path_pts(struct path *path)
288262306a36Sopenharmony_ci{
288362306a36Sopenharmony_ci	/* Find something mounted on "pts" in the same directory as
288462306a36Sopenharmony_ci	 * the input path.
288562306a36Sopenharmony_ci	 */
288662306a36Sopenharmony_ci	struct dentry *parent = dget_parent(path->dentry);
288762306a36Sopenharmony_ci	struct dentry *child;
288862306a36Sopenharmony_ci	struct qstr this = QSTR_INIT("pts", 3);
288962306a36Sopenharmony_ci
289062306a36Sopenharmony_ci	if (unlikely(!path_connected(path->mnt, parent))) {
289162306a36Sopenharmony_ci		dput(parent);
289262306a36Sopenharmony_ci		return -ENOENT;
289362306a36Sopenharmony_ci	}
289462306a36Sopenharmony_ci	dput(path->dentry);
289562306a36Sopenharmony_ci	path->dentry = parent;
289662306a36Sopenharmony_ci	child = d_hash_and_lookup(parent, &this);
289762306a36Sopenharmony_ci	if (IS_ERR_OR_NULL(child))
289862306a36Sopenharmony_ci		return -ENOENT;
289962306a36Sopenharmony_ci
290062306a36Sopenharmony_ci	path->dentry = child;
290162306a36Sopenharmony_ci	dput(parent);
290262306a36Sopenharmony_ci	follow_down(path, 0);
290362306a36Sopenharmony_ci	return 0;
290462306a36Sopenharmony_ci}
290562306a36Sopenharmony_ci#endif
290662306a36Sopenharmony_ci
290762306a36Sopenharmony_ciint user_path_at_empty(int dfd, const char __user *name, unsigned flags,
290862306a36Sopenharmony_ci		 struct path *path, int *empty)
290962306a36Sopenharmony_ci{
291062306a36Sopenharmony_ci	struct filename *filename = getname_flags(name, flags, empty);
291162306a36Sopenharmony_ci	int ret = filename_lookup(dfd, filename, flags, path, NULL);
291262306a36Sopenharmony_ci
291362306a36Sopenharmony_ci	putname(filename);
291462306a36Sopenharmony_ci	return ret;
291562306a36Sopenharmony_ci}
291662306a36Sopenharmony_ciEXPORT_SYMBOL(user_path_at_empty);
291762306a36Sopenharmony_ci
291862306a36Sopenharmony_ciint __check_sticky(struct mnt_idmap *idmap, struct inode *dir,
291962306a36Sopenharmony_ci		   struct inode *inode)
292062306a36Sopenharmony_ci{
292162306a36Sopenharmony_ci	kuid_t fsuid = current_fsuid();
292262306a36Sopenharmony_ci
292362306a36Sopenharmony_ci	if (vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, inode), fsuid))
292462306a36Sopenharmony_ci		return 0;
292562306a36Sopenharmony_ci	if (vfsuid_eq_kuid(i_uid_into_vfsuid(idmap, dir), fsuid))
292662306a36Sopenharmony_ci		return 0;
292762306a36Sopenharmony_ci	return !capable_wrt_inode_uidgid(idmap, inode, CAP_FOWNER);
292862306a36Sopenharmony_ci}
292962306a36Sopenharmony_ciEXPORT_SYMBOL(__check_sticky);
293062306a36Sopenharmony_ci
293162306a36Sopenharmony_ci/*
293262306a36Sopenharmony_ci *	Check whether we can remove a link victim from directory dir, check
293362306a36Sopenharmony_ci *  whether the type of victim is right.
293462306a36Sopenharmony_ci *  1. We can't do it if dir is read-only (done in permission())
293562306a36Sopenharmony_ci *  2. We should have write and exec permissions on dir
293662306a36Sopenharmony_ci *  3. We can't remove anything from append-only dir
293762306a36Sopenharmony_ci *  4. We can't do anything with immutable dir (done in permission())
293862306a36Sopenharmony_ci *  5. If the sticky bit on dir is set we should either
293962306a36Sopenharmony_ci *	a. be owner of dir, or
294062306a36Sopenharmony_ci *	b. be owner of victim, or
294162306a36Sopenharmony_ci *	c. have CAP_FOWNER capability
294262306a36Sopenharmony_ci *  6. If the victim is append-only or immutable we can't do antyhing with
294362306a36Sopenharmony_ci *     links pointing to it.
294462306a36Sopenharmony_ci *  7. If the victim has an unknown uid or gid we can't change the inode.
294562306a36Sopenharmony_ci *  8. If we were asked to remove a directory and victim isn't one - ENOTDIR.
294662306a36Sopenharmony_ci *  9. If we were asked to remove a non-directory and victim isn't one - EISDIR.
294762306a36Sopenharmony_ci * 10. We can't remove a root or mountpoint.
294862306a36Sopenharmony_ci * 11. We don't allow removal of NFS sillyrenamed files; it's handled by
294962306a36Sopenharmony_ci *     nfs_async_unlink().
295062306a36Sopenharmony_ci */
295162306a36Sopenharmony_cistatic int may_delete(struct mnt_idmap *idmap, struct inode *dir,
295262306a36Sopenharmony_ci		      struct dentry *victim, bool isdir)
295362306a36Sopenharmony_ci{
295462306a36Sopenharmony_ci	struct inode *inode = d_backing_inode(victim);
295562306a36Sopenharmony_ci	int error;
295662306a36Sopenharmony_ci
295762306a36Sopenharmony_ci	if (d_is_negative(victim))
295862306a36Sopenharmony_ci		return -ENOENT;
295962306a36Sopenharmony_ci	BUG_ON(!inode);
296062306a36Sopenharmony_ci
296162306a36Sopenharmony_ci	BUG_ON(victim->d_parent->d_inode != dir);
296262306a36Sopenharmony_ci
296362306a36Sopenharmony_ci	/* Inode writeback is not safe when the uid or gid are invalid. */
296462306a36Sopenharmony_ci	if (!vfsuid_valid(i_uid_into_vfsuid(idmap, inode)) ||
296562306a36Sopenharmony_ci	    !vfsgid_valid(i_gid_into_vfsgid(idmap, inode)))
296662306a36Sopenharmony_ci		return -EOVERFLOW;
296762306a36Sopenharmony_ci
296862306a36Sopenharmony_ci	audit_inode_child(dir, victim, AUDIT_TYPE_CHILD_DELETE);
296962306a36Sopenharmony_ci
297062306a36Sopenharmony_ci	error = inode_permission(idmap, dir, MAY_WRITE | MAY_EXEC);
297162306a36Sopenharmony_ci	if (error)
297262306a36Sopenharmony_ci		return error;
297362306a36Sopenharmony_ci	if (IS_APPEND(dir))
297462306a36Sopenharmony_ci		return -EPERM;
297562306a36Sopenharmony_ci
297662306a36Sopenharmony_ci	if (check_sticky(idmap, dir, inode) || IS_APPEND(inode) ||
297762306a36Sopenharmony_ci	    IS_IMMUTABLE(inode) || IS_SWAPFILE(inode) ||
297862306a36Sopenharmony_ci	    HAS_UNMAPPED_ID(idmap, inode))
297962306a36Sopenharmony_ci		return -EPERM;
298062306a36Sopenharmony_ci	if (isdir) {
298162306a36Sopenharmony_ci		if (!d_is_dir(victim))
298262306a36Sopenharmony_ci			return -ENOTDIR;
298362306a36Sopenharmony_ci		if (IS_ROOT(victim))
298462306a36Sopenharmony_ci			return -EBUSY;
298562306a36Sopenharmony_ci	} else if (d_is_dir(victim))
298662306a36Sopenharmony_ci		return -EISDIR;
298762306a36Sopenharmony_ci	if (IS_DEADDIR(dir))
298862306a36Sopenharmony_ci		return -ENOENT;
298962306a36Sopenharmony_ci	if (victim->d_flags & DCACHE_NFSFS_RENAMED)
299062306a36Sopenharmony_ci		return -EBUSY;
299162306a36Sopenharmony_ci	return 0;
299262306a36Sopenharmony_ci}
299362306a36Sopenharmony_ci
299462306a36Sopenharmony_ci/*	Check whether we can create an object with dentry child in directory
299562306a36Sopenharmony_ci *  dir.
299662306a36Sopenharmony_ci *  1. We can't do it if child already exists (open has special treatment for
299762306a36Sopenharmony_ci *     this case, but since we are inlined it's OK)
299862306a36Sopenharmony_ci *  2. We can't do it if dir is read-only (done in permission())
299962306a36Sopenharmony_ci *  3. We can't do it if the fs can't represent the fsuid or fsgid.
300062306a36Sopenharmony_ci *  4. We should have write and exec permissions on dir
300162306a36Sopenharmony_ci *  5. We can't do it if dir is immutable (done in permission())
300262306a36Sopenharmony_ci */
300362306a36Sopenharmony_cistatic inline int may_create(struct mnt_idmap *idmap,
300462306a36Sopenharmony_ci			     struct inode *dir, struct dentry *child)
300562306a36Sopenharmony_ci{
300662306a36Sopenharmony_ci	audit_inode_child(dir, child, AUDIT_TYPE_CHILD_CREATE);
300762306a36Sopenharmony_ci	if (child->d_inode)
300862306a36Sopenharmony_ci		return -EEXIST;
300962306a36Sopenharmony_ci	if (IS_DEADDIR(dir))
301062306a36Sopenharmony_ci		return -ENOENT;
301162306a36Sopenharmony_ci	if (!fsuidgid_has_mapping(dir->i_sb, idmap))
301262306a36Sopenharmony_ci		return -EOVERFLOW;
301362306a36Sopenharmony_ci
301462306a36Sopenharmony_ci	return inode_permission(idmap, dir, MAY_WRITE | MAY_EXEC);
301562306a36Sopenharmony_ci}
301662306a36Sopenharmony_ci
301762306a36Sopenharmony_cistatic struct dentry *lock_two_directories(struct dentry *p1, struct dentry *p2)
301862306a36Sopenharmony_ci{
301962306a36Sopenharmony_ci	struct dentry *p;
302062306a36Sopenharmony_ci
302162306a36Sopenharmony_ci	p = d_ancestor(p2, p1);
302262306a36Sopenharmony_ci	if (p) {
302362306a36Sopenharmony_ci		inode_lock_nested(p2->d_inode, I_MUTEX_PARENT);
302462306a36Sopenharmony_ci		inode_lock_nested(p1->d_inode, I_MUTEX_PARENT2);
302562306a36Sopenharmony_ci		return p;
302662306a36Sopenharmony_ci	}
302762306a36Sopenharmony_ci
302862306a36Sopenharmony_ci	p = d_ancestor(p1, p2);
302962306a36Sopenharmony_ci	inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
303062306a36Sopenharmony_ci	inode_lock_nested(p2->d_inode, I_MUTEX_PARENT2);
303162306a36Sopenharmony_ci	return p;
303262306a36Sopenharmony_ci}
303362306a36Sopenharmony_ci
303462306a36Sopenharmony_ci/*
303562306a36Sopenharmony_ci * p1 and p2 should be directories on the same fs.
303662306a36Sopenharmony_ci */
303762306a36Sopenharmony_cistruct dentry *lock_rename(struct dentry *p1, struct dentry *p2)
303862306a36Sopenharmony_ci{
303962306a36Sopenharmony_ci	if (p1 == p2) {
304062306a36Sopenharmony_ci		inode_lock_nested(p1->d_inode, I_MUTEX_PARENT);
304162306a36Sopenharmony_ci		return NULL;
304262306a36Sopenharmony_ci	}
304362306a36Sopenharmony_ci
304462306a36Sopenharmony_ci	mutex_lock(&p1->d_sb->s_vfs_rename_mutex);
304562306a36Sopenharmony_ci	return lock_two_directories(p1, p2);
304662306a36Sopenharmony_ci}
304762306a36Sopenharmony_ciEXPORT_SYMBOL(lock_rename);
304862306a36Sopenharmony_ci
304962306a36Sopenharmony_ci/*
305062306a36Sopenharmony_ci * c1 and p2 should be on the same fs.
305162306a36Sopenharmony_ci */
305262306a36Sopenharmony_cistruct dentry *lock_rename_child(struct dentry *c1, struct dentry *p2)
305362306a36Sopenharmony_ci{
305462306a36Sopenharmony_ci	if (READ_ONCE(c1->d_parent) == p2) {
305562306a36Sopenharmony_ci		/*
305662306a36Sopenharmony_ci		 * hopefully won't need to touch ->s_vfs_rename_mutex at all.
305762306a36Sopenharmony_ci		 */
305862306a36Sopenharmony_ci		inode_lock_nested(p2->d_inode, I_MUTEX_PARENT);
305962306a36Sopenharmony_ci		/*
306062306a36Sopenharmony_ci		 * now that p2 is locked, nobody can move in or out of it,
306162306a36Sopenharmony_ci		 * so the test below is safe.
306262306a36Sopenharmony_ci		 */
306362306a36Sopenharmony_ci		if (likely(c1->d_parent == p2))
306462306a36Sopenharmony_ci			return NULL;
306562306a36Sopenharmony_ci
306662306a36Sopenharmony_ci		/*
306762306a36Sopenharmony_ci		 * c1 got moved out of p2 while we'd been taking locks;
306862306a36Sopenharmony_ci		 * unlock and fall back to slow case.
306962306a36Sopenharmony_ci		 */
307062306a36Sopenharmony_ci		inode_unlock(p2->d_inode);
307162306a36Sopenharmony_ci	}
307262306a36Sopenharmony_ci
307362306a36Sopenharmony_ci	mutex_lock(&c1->d_sb->s_vfs_rename_mutex);
307462306a36Sopenharmony_ci	/*
307562306a36Sopenharmony_ci	 * nobody can move out of any directories on this fs.
307662306a36Sopenharmony_ci	 */
307762306a36Sopenharmony_ci	if (likely(c1->d_parent != p2))
307862306a36Sopenharmony_ci		return lock_two_directories(c1->d_parent, p2);
307962306a36Sopenharmony_ci
308062306a36Sopenharmony_ci	/*
308162306a36Sopenharmony_ci	 * c1 got moved into p2 while we were taking locks;
308262306a36Sopenharmony_ci	 * we need p2 locked and ->s_vfs_rename_mutex unlocked,
308362306a36Sopenharmony_ci	 * for consistency with lock_rename().
308462306a36Sopenharmony_ci	 */
308562306a36Sopenharmony_ci	inode_lock_nested(p2->d_inode, I_MUTEX_PARENT);
308662306a36Sopenharmony_ci	mutex_unlock(&c1->d_sb->s_vfs_rename_mutex);
308762306a36Sopenharmony_ci	return NULL;
308862306a36Sopenharmony_ci}
308962306a36Sopenharmony_ciEXPORT_SYMBOL(lock_rename_child);
309062306a36Sopenharmony_ci
309162306a36Sopenharmony_civoid unlock_rename(struct dentry *p1, struct dentry *p2)
309262306a36Sopenharmony_ci{
309362306a36Sopenharmony_ci	inode_unlock(p1->d_inode);
309462306a36Sopenharmony_ci	if (p1 != p2) {
309562306a36Sopenharmony_ci		inode_unlock(p2->d_inode);
309662306a36Sopenharmony_ci		mutex_unlock(&p1->d_sb->s_vfs_rename_mutex);
309762306a36Sopenharmony_ci	}
309862306a36Sopenharmony_ci}
309962306a36Sopenharmony_ciEXPORT_SYMBOL(unlock_rename);
310062306a36Sopenharmony_ci
310162306a36Sopenharmony_ci/**
310262306a36Sopenharmony_ci * mode_strip_umask - handle vfs umask stripping
310362306a36Sopenharmony_ci * @dir:	parent directory of the new inode
310462306a36Sopenharmony_ci * @mode:	mode of the new inode to be created in @dir
310562306a36Sopenharmony_ci *
310662306a36Sopenharmony_ci * Umask stripping depends on whether or not the filesystem supports POSIX
310762306a36Sopenharmony_ci * ACLs. If the filesystem doesn't support it umask stripping is done directly
310862306a36Sopenharmony_ci * in here. If the filesystem does support POSIX ACLs umask stripping is
310962306a36Sopenharmony_ci * deferred until the filesystem calls posix_acl_create().
311062306a36Sopenharmony_ci *
311162306a36Sopenharmony_ci * Returns: mode
311262306a36Sopenharmony_ci */
311362306a36Sopenharmony_cistatic inline umode_t mode_strip_umask(const struct inode *dir, umode_t mode)
311462306a36Sopenharmony_ci{
311562306a36Sopenharmony_ci	if (!IS_POSIXACL(dir))
311662306a36Sopenharmony_ci		mode &= ~current_umask();
311762306a36Sopenharmony_ci	return mode;
311862306a36Sopenharmony_ci}
311962306a36Sopenharmony_ci
312062306a36Sopenharmony_ci/**
312162306a36Sopenharmony_ci * vfs_prepare_mode - prepare the mode to be used for a new inode
312262306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
312362306a36Sopenharmony_ci * @dir:	parent directory of the new inode
312462306a36Sopenharmony_ci * @mode:	mode of the new inode
312562306a36Sopenharmony_ci * @mask_perms:	allowed permission by the vfs
312662306a36Sopenharmony_ci * @type:	type of file to be created
312762306a36Sopenharmony_ci *
312862306a36Sopenharmony_ci * This helper consolidates and enforces vfs restrictions on the @mode of a new
312962306a36Sopenharmony_ci * object to be created.
313062306a36Sopenharmony_ci *
313162306a36Sopenharmony_ci * Umask stripping depends on whether the filesystem supports POSIX ACLs (see
313262306a36Sopenharmony_ci * the kernel documentation for mode_strip_umask()). Moving umask stripping
313362306a36Sopenharmony_ci * after setgid stripping allows the same ordering for both non-POSIX ACL and
313462306a36Sopenharmony_ci * POSIX ACL supporting filesystems.
313562306a36Sopenharmony_ci *
313662306a36Sopenharmony_ci * Note that it's currently valid for @type to be 0 if a directory is created.
313762306a36Sopenharmony_ci * Filesystems raise that flag individually and we need to check whether each
313862306a36Sopenharmony_ci * filesystem can deal with receiving S_IFDIR from the vfs before we enforce a
313962306a36Sopenharmony_ci * non-zero type.
314062306a36Sopenharmony_ci *
314162306a36Sopenharmony_ci * Returns: mode to be passed to the filesystem
314262306a36Sopenharmony_ci */
314362306a36Sopenharmony_cistatic inline umode_t vfs_prepare_mode(struct mnt_idmap *idmap,
314462306a36Sopenharmony_ci				       const struct inode *dir, umode_t mode,
314562306a36Sopenharmony_ci				       umode_t mask_perms, umode_t type)
314662306a36Sopenharmony_ci{
314762306a36Sopenharmony_ci	mode = mode_strip_sgid(idmap, dir, mode);
314862306a36Sopenharmony_ci	mode = mode_strip_umask(dir, mode);
314962306a36Sopenharmony_ci
315062306a36Sopenharmony_ci	/*
315162306a36Sopenharmony_ci	 * Apply the vfs mandated allowed permission mask and set the type of
315262306a36Sopenharmony_ci	 * file to be created before we call into the filesystem.
315362306a36Sopenharmony_ci	 */
315462306a36Sopenharmony_ci	mode &= (mask_perms & ~S_IFMT);
315562306a36Sopenharmony_ci	mode |= (type & S_IFMT);
315662306a36Sopenharmony_ci
315762306a36Sopenharmony_ci	return mode;
315862306a36Sopenharmony_ci}
315962306a36Sopenharmony_ci
316062306a36Sopenharmony_ci/**
316162306a36Sopenharmony_ci * vfs_create - create new file
316262306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
316362306a36Sopenharmony_ci * @dir:	inode of @dentry
316462306a36Sopenharmony_ci * @dentry:	pointer to dentry of the base directory
316562306a36Sopenharmony_ci * @mode:	mode of the new file
316662306a36Sopenharmony_ci * @want_excl:	whether the file must not yet exist
316762306a36Sopenharmony_ci *
316862306a36Sopenharmony_ci * Create a new file.
316962306a36Sopenharmony_ci *
317062306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
317162306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
317262306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
317362306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
317462306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
317562306a36Sopenharmony_ci */
317662306a36Sopenharmony_ciint vfs_create(struct mnt_idmap *idmap, struct inode *dir,
317762306a36Sopenharmony_ci	       struct dentry *dentry, umode_t mode, bool want_excl)
317862306a36Sopenharmony_ci{
317962306a36Sopenharmony_ci	int error;
318062306a36Sopenharmony_ci
318162306a36Sopenharmony_ci	error = may_create(idmap, dir, dentry);
318262306a36Sopenharmony_ci	if (error)
318362306a36Sopenharmony_ci		return error;
318462306a36Sopenharmony_ci
318562306a36Sopenharmony_ci	if (!dir->i_op->create)
318662306a36Sopenharmony_ci		return -EACCES;	/* shouldn't it be ENOSYS? */
318762306a36Sopenharmony_ci
318862306a36Sopenharmony_ci	mode = vfs_prepare_mode(idmap, dir, mode, S_IALLUGO, S_IFREG);
318962306a36Sopenharmony_ci	error = security_inode_create(dir, dentry, mode);
319062306a36Sopenharmony_ci	if (error)
319162306a36Sopenharmony_ci		return error;
319262306a36Sopenharmony_ci	error = dir->i_op->create(idmap, dir, dentry, mode, want_excl);
319362306a36Sopenharmony_ci	if (!error)
319462306a36Sopenharmony_ci		fsnotify_create(dir, dentry);
319562306a36Sopenharmony_ci	return error;
319662306a36Sopenharmony_ci}
319762306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_create);
319862306a36Sopenharmony_ci
319962306a36Sopenharmony_ciint vfs_mkobj(struct dentry *dentry, umode_t mode,
320062306a36Sopenharmony_ci		int (*f)(struct dentry *, umode_t, void *),
320162306a36Sopenharmony_ci		void *arg)
320262306a36Sopenharmony_ci{
320362306a36Sopenharmony_ci	struct inode *dir = dentry->d_parent->d_inode;
320462306a36Sopenharmony_ci	int error = may_create(&nop_mnt_idmap, dir, dentry);
320562306a36Sopenharmony_ci	if (error)
320662306a36Sopenharmony_ci		return error;
320762306a36Sopenharmony_ci
320862306a36Sopenharmony_ci	mode &= S_IALLUGO;
320962306a36Sopenharmony_ci	mode |= S_IFREG;
321062306a36Sopenharmony_ci	error = security_inode_create(dir, dentry, mode);
321162306a36Sopenharmony_ci	if (error)
321262306a36Sopenharmony_ci		return error;
321362306a36Sopenharmony_ci	error = f(dentry, mode, arg);
321462306a36Sopenharmony_ci	if (!error)
321562306a36Sopenharmony_ci		fsnotify_create(dir, dentry);
321662306a36Sopenharmony_ci	return error;
321762306a36Sopenharmony_ci}
321862306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_mkobj);
321962306a36Sopenharmony_ci
322062306a36Sopenharmony_cibool may_open_dev(const struct path *path)
322162306a36Sopenharmony_ci{
322262306a36Sopenharmony_ci	return !(path->mnt->mnt_flags & MNT_NODEV) &&
322362306a36Sopenharmony_ci		!(path->mnt->mnt_sb->s_iflags & SB_I_NODEV);
322462306a36Sopenharmony_ci}
322562306a36Sopenharmony_ci
322662306a36Sopenharmony_cistatic int may_open(struct mnt_idmap *idmap, const struct path *path,
322762306a36Sopenharmony_ci		    int acc_mode, int flag)
322862306a36Sopenharmony_ci{
322962306a36Sopenharmony_ci	struct dentry *dentry = path->dentry;
323062306a36Sopenharmony_ci	struct inode *inode = dentry->d_inode;
323162306a36Sopenharmony_ci	int error;
323262306a36Sopenharmony_ci
323362306a36Sopenharmony_ci	if (!inode)
323462306a36Sopenharmony_ci		return -ENOENT;
323562306a36Sopenharmony_ci
323662306a36Sopenharmony_ci	switch (inode->i_mode & S_IFMT) {
323762306a36Sopenharmony_ci	case S_IFLNK:
323862306a36Sopenharmony_ci		return -ELOOP;
323962306a36Sopenharmony_ci	case S_IFDIR:
324062306a36Sopenharmony_ci		if (acc_mode & MAY_WRITE)
324162306a36Sopenharmony_ci			return -EISDIR;
324262306a36Sopenharmony_ci		if (acc_mode & MAY_EXEC)
324362306a36Sopenharmony_ci			return -EACCES;
324462306a36Sopenharmony_ci		break;
324562306a36Sopenharmony_ci	case S_IFBLK:
324662306a36Sopenharmony_ci	case S_IFCHR:
324762306a36Sopenharmony_ci		if (!may_open_dev(path))
324862306a36Sopenharmony_ci			return -EACCES;
324962306a36Sopenharmony_ci		fallthrough;
325062306a36Sopenharmony_ci	case S_IFIFO:
325162306a36Sopenharmony_ci	case S_IFSOCK:
325262306a36Sopenharmony_ci		if (acc_mode & MAY_EXEC)
325362306a36Sopenharmony_ci			return -EACCES;
325462306a36Sopenharmony_ci		flag &= ~O_TRUNC;
325562306a36Sopenharmony_ci		break;
325662306a36Sopenharmony_ci	case S_IFREG:
325762306a36Sopenharmony_ci		if ((acc_mode & MAY_EXEC) && path_noexec(path))
325862306a36Sopenharmony_ci			return -EACCES;
325962306a36Sopenharmony_ci		break;
326062306a36Sopenharmony_ci	}
326162306a36Sopenharmony_ci
326262306a36Sopenharmony_ci	error = inode_permission(idmap, inode, MAY_OPEN | acc_mode);
326362306a36Sopenharmony_ci	if (error)
326462306a36Sopenharmony_ci		return error;
326562306a36Sopenharmony_ci
326662306a36Sopenharmony_ci	/*
326762306a36Sopenharmony_ci	 * An append-only file must be opened in append mode for writing.
326862306a36Sopenharmony_ci	 */
326962306a36Sopenharmony_ci	if (IS_APPEND(inode)) {
327062306a36Sopenharmony_ci		if  ((flag & O_ACCMODE) != O_RDONLY && !(flag & O_APPEND))
327162306a36Sopenharmony_ci			return -EPERM;
327262306a36Sopenharmony_ci		if (flag & O_TRUNC)
327362306a36Sopenharmony_ci			return -EPERM;
327462306a36Sopenharmony_ci	}
327562306a36Sopenharmony_ci
327662306a36Sopenharmony_ci	/* O_NOATIME can only be set by the owner or superuser */
327762306a36Sopenharmony_ci	if (flag & O_NOATIME && !inode_owner_or_capable(idmap, inode))
327862306a36Sopenharmony_ci		return -EPERM;
327962306a36Sopenharmony_ci
328062306a36Sopenharmony_ci	return 0;
328162306a36Sopenharmony_ci}
328262306a36Sopenharmony_ci
328362306a36Sopenharmony_cistatic int handle_truncate(struct mnt_idmap *idmap, struct file *filp)
328462306a36Sopenharmony_ci{
328562306a36Sopenharmony_ci	const struct path *path = &filp->f_path;
328662306a36Sopenharmony_ci	struct inode *inode = path->dentry->d_inode;
328762306a36Sopenharmony_ci	int error = get_write_access(inode);
328862306a36Sopenharmony_ci	if (error)
328962306a36Sopenharmony_ci		return error;
329062306a36Sopenharmony_ci
329162306a36Sopenharmony_ci	error = security_file_truncate(filp);
329262306a36Sopenharmony_ci	if (!error) {
329362306a36Sopenharmony_ci		error = do_truncate(idmap, path->dentry, 0,
329462306a36Sopenharmony_ci				    ATTR_MTIME|ATTR_CTIME|ATTR_OPEN,
329562306a36Sopenharmony_ci				    filp);
329662306a36Sopenharmony_ci	}
329762306a36Sopenharmony_ci	put_write_access(inode);
329862306a36Sopenharmony_ci	return error;
329962306a36Sopenharmony_ci}
330062306a36Sopenharmony_ci
330162306a36Sopenharmony_cistatic inline int open_to_namei_flags(int flag)
330262306a36Sopenharmony_ci{
330362306a36Sopenharmony_ci	if ((flag & O_ACCMODE) == 3)
330462306a36Sopenharmony_ci		flag--;
330562306a36Sopenharmony_ci	return flag;
330662306a36Sopenharmony_ci}
330762306a36Sopenharmony_ci
330862306a36Sopenharmony_cistatic int may_o_create(struct mnt_idmap *idmap,
330962306a36Sopenharmony_ci			const struct path *dir, struct dentry *dentry,
331062306a36Sopenharmony_ci			umode_t mode)
331162306a36Sopenharmony_ci{
331262306a36Sopenharmony_ci	int error = security_path_mknod(dir, dentry, mode, 0);
331362306a36Sopenharmony_ci	if (error)
331462306a36Sopenharmony_ci		return error;
331562306a36Sopenharmony_ci
331662306a36Sopenharmony_ci	if (!fsuidgid_has_mapping(dir->dentry->d_sb, idmap))
331762306a36Sopenharmony_ci		return -EOVERFLOW;
331862306a36Sopenharmony_ci
331962306a36Sopenharmony_ci	error = inode_permission(idmap, dir->dentry->d_inode,
332062306a36Sopenharmony_ci				 MAY_WRITE | MAY_EXEC);
332162306a36Sopenharmony_ci	if (error)
332262306a36Sopenharmony_ci		return error;
332362306a36Sopenharmony_ci
332462306a36Sopenharmony_ci	return security_inode_create(dir->dentry->d_inode, dentry, mode);
332562306a36Sopenharmony_ci}
332662306a36Sopenharmony_ci
332762306a36Sopenharmony_ci/*
332862306a36Sopenharmony_ci * Attempt to atomically look up, create and open a file from a negative
332962306a36Sopenharmony_ci * dentry.
333062306a36Sopenharmony_ci *
333162306a36Sopenharmony_ci * Returns 0 if successful.  The file will have been created and attached to
333262306a36Sopenharmony_ci * @file by the filesystem calling finish_open().
333362306a36Sopenharmony_ci *
333462306a36Sopenharmony_ci * If the file was looked up only or didn't need creating, FMODE_OPENED won't
333562306a36Sopenharmony_ci * be set.  The caller will need to perform the open themselves.  @path will
333662306a36Sopenharmony_ci * have been updated to point to the new dentry.  This may be negative.
333762306a36Sopenharmony_ci *
333862306a36Sopenharmony_ci * Returns an error code otherwise.
333962306a36Sopenharmony_ci */
334062306a36Sopenharmony_cistatic struct dentry *atomic_open(struct nameidata *nd, struct dentry *dentry,
334162306a36Sopenharmony_ci				  struct file *file,
334262306a36Sopenharmony_ci				  int open_flag, umode_t mode)
334362306a36Sopenharmony_ci{
334462306a36Sopenharmony_ci	struct dentry *const DENTRY_NOT_SET = (void *) -1UL;
334562306a36Sopenharmony_ci	struct inode *dir =  nd->path.dentry->d_inode;
334662306a36Sopenharmony_ci	int error;
334762306a36Sopenharmony_ci
334862306a36Sopenharmony_ci	if (nd->flags & LOOKUP_DIRECTORY)
334962306a36Sopenharmony_ci		open_flag |= O_DIRECTORY;
335062306a36Sopenharmony_ci
335162306a36Sopenharmony_ci	file->f_path.dentry = DENTRY_NOT_SET;
335262306a36Sopenharmony_ci	file->f_path.mnt = nd->path.mnt;
335362306a36Sopenharmony_ci	error = dir->i_op->atomic_open(dir, dentry, file,
335462306a36Sopenharmony_ci				       open_to_namei_flags(open_flag), mode);
335562306a36Sopenharmony_ci	d_lookup_done(dentry);
335662306a36Sopenharmony_ci	if (!error) {
335762306a36Sopenharmony_ci		if (file->f_mode & FMODE_OPENED) {
335862306a36Sopenharmony_ci			if (unlikely(dentry != file->f_path.dentry)) {
335962306a36Sopenharmony_ci				dput(dentry);
336062306a36Sopenharmony_ci				dentry = dget(file->f_path.dentry);
336162306a36Sopenharmony_ci			}
336262306a36Sopenharmony_ci		} else if (WARN_ON(file->f_path.dentry == DENTRY_NOT_SET)) {
336362306a36Sopenharmony_ci			error = -EIO;
336462306a36Sopenharmony_ci		} else {
336562306a36Sopenharmony_ci			if (file->f_path.dentry) {
336662306a36Sopenharmony_ci				dput(dentry);
336762306a36Sopenharmony_ci				dentry = file->f_path.dentry;
336862306a36Sopenharmony_ci			}
336962306a36Sopenharmony_ci			if (unlikely(d_is_negative(dentry)))
337062306a36Sopenharmony_ci				error = -ENOENT;
337162306a36Sopenharmony_ci		}
337262306a36Sopenharmony_ci	}
337362306a36Sopenharmony_ci	if (error) {
337462306a36Sopenharmony_ci		dput(dentry);
337562306a36Sopenharmony_ci		dentry = ERR_PTR(error);
337662306a36Sopenharmony_ci	}
337762306a36Sopenharmony_ci	return dentry;
337862306a36Sopenharmony_ci}
337962306a36Sopenharmony_ci
338062306a36Sopenharmony_ci/*
338162306a36Sopenharmony_ci * Look up and maybe create and open the last component.
338262306a36Sopenharmony_ci *
338362306a36Sopenharmony_ci * Must be called with parent locked (exclusive in O_CREAT case).
338462306a36Sopenharmony_ci *
338562306a36Sopenharmony_ci * Returns 0 on success, that is, if
338662306a36Sopenharmony_ci *  the file was successfully atomically created (if necessary) and opened, or
338762306a36Sopenharmony_ci *  the file was not completely opened at this time, though lookups and
338862306a36Sopenharmony_ci *  creations were performed.
338962306a36Sopenharmony_ci * These case are distinguished by presence of FMODE_OPENED on file->f_mode.
339062306a36Sopenharmony_ci * In the latter case dentry returned in @path might be negative if O_CREAT
339162306a36Sopenharmony_ci * hadn't been specified.
339262306a36Sopenharmony_ci *
339362306a36Sopenharmony_ci * An error code is returned on failure.
339462306a36Sopenharmony_ci */
339562306a36Sopenharmony_cistatic struct dentry *lookup_open(struct nameidata *nd, struct file *file,
339662306a36Sopenharmony_ci				  const struct open_flags *op,
339762306a36Sopenharmony_ci				  bool got_write)
339862306a36Sopenharmony_ci{
339962306a36Sopenharmony_ci	struct mnt_idmap *idmap;
340062306a36Sopenharmony_ci	struct dentry *dir = nd->path.dentry;
340162306a36Sopenharmony_ci	struct inode *dir_inode = dir->d_inode;
340262306a36Sopenharmony_ci	int open_flag = op->open_flag;
340362306a36Sopenharmony_ci	struct dentry *dentry;
340462306a36Sopenharmony_ci	int error, create_error = 0;
340562306a36Sopenharmony_ci	umode_t mode = op->mode;
340662306a36Sopenharmony_ci	DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
340762306a36Sopenharmony_ci
340862306a36Sopenharmony_ci	if (unlikely(IS_DEADDIR(dir_inode)))
340962306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
341062306a36Sopenharmony_ci
341162306a36Sopenharmony_ci	file->f_mode &= ~FMODE_CREATED;
341262306a36Sopenharmony_ci	dentry = d_lookup(dir, &nd->last);
341362306a36Sopenharmony_ci	for (;;) {
341462306a36Sopenharmony_ci		if (!dentry) {
341562306a36Sopenharmony_ci			dentry = d_alloc_parallel(dir, &nd->last, &wq);
341662306a36Sopenharmony_ci			if (IS_ERR(dentry))
341762306a36Sopenharmony_ci				return dentry;
341862306a36Sopenharmony_ci		}
341962306a36Sopenharmony_ci		if (d_in_lookup(dentry))
342062306a36Sopenharmony_ci			break;
342162306a36Sopenharmony_ci
342262306a36Sopenharmony_ci		error = d_revalidate(dentry, nd->flags);
342362306a36Sopenharmony_ci		if (likely(error > 0))
342462306a36Sopenharmony_ci			break;
342562306a36Sopenharmony_ci		if (error)
342662306a36Sopenharmony_ci			goto out_dput;
342762306a36Sopenharmony_ci		d_invalidate(dentry);
342862306a36Sopenharmony_ci		dput(dentry);
342962306a36Sopenharmony_ci		dentry = NULL;
343062306a36Sopenharmony_ci	}
343162306a36Sopenharmony_ci	if (dentry->d_inode) {
343262306a36Sopenharmony_ci		/* Cached positive dentry: will open in f_op->open */
343362306a36Sopenharmony_ci		return dentry;
343462306a36Sopenharmony_ci	}
343562306a36Sopenharmony_ci
343662306a36Sopenharmony_ci	/*
343762306a36Sopenharmony_ci	 * Checking write permission is tricky, bacuse we don't know if we are
343862306a36Sopenharmony_ci	 * going to actually need it: O_CREAT opens should work as long as the
343962306a36Sopenharmony_ci	 * file exists.  But checking existence breaks atomicity.  The trick is
344062306a36Sopenharmony_ci	 * to check access and if not granted clear O_CREAT from the flags.
344162306a36Sopenharmony_ci	 *
344262306a36Sopenharmony_ci	 * Another problem is returing the "right" error value (e.g. for an
344362306a36Sopenharmony_ci	 * O_EXCL open we want to return EEXIST not EROFS).
344462306a36Sopenharmony_ci	 */
344562306a36Sopenharmony_ci	if (unlikely(!got_write))
344662306a36Sopenharmony_ci		open_flag &= ~O_TRUNC;
344762306a36Sopenharmony_ci	idmap = mnt_idmap(nd->path.mnt);
344862306a36Sopenharmony_ci	if (open_flag & O_CREAT) {
344962306a36Sopenharmony_ci		if (open_flag & O_EXCL)
345062306a36Sopenharmony_ci			open_flag &= ~O_TRUNC;
345162306a36Sopenharmony_ci		mode = vfs_prepare_mode(idmap, dir->d_inode, mode, mode, mode);
345262306a36Sopenharmony_ci		if (likely(got_write))
345362306a36Sopenharmony_ci			create_error = may_o_create(idmap, &nd->path,
345462306a36Sopenharmony_ci						    dentry, mode);
345562306a36Sopenharmony_ci		else
345662306a36Sopenharmony_ci			create_error = -EROFS;
345762306a36Sopenharmony_ci	}
345862306a36Sopenharmony_ci	if (create_error)
345962306a36Sopenharmony_ci		open_flag &= ~O_CREAT;
346062306a36Sopenharmony_ci	if (dir_inode->i_op->atomic_open) {
346162306a36Sopenharmony_ci		dentry = atomic_open(nd, dentry, file, open_flag, mode);
346262306a36Sopenharmony_ci		if (unlikely(create_error) && dentry == ERR_PTR(-ENOENT))
346362306a36Sopenharmony_ci			dentry = ERR_PTR(create_error);
346462306a36Sopenharmony_ci		return dentry;
346562306a36Sopenharmony_ci	}
346662306a36Sopenharmony_ci
346762306a36Sopenharmony_ci	if (d_in_lookup(dentry)) {
346862306a36Sopenharmony_ci		struct dentry *res = dir_inode->i_op->lookup(dir_inode, dentry,
346962306a36Sopenharmony_ci							     nd->flags);
347062306a36Sopenharmony_ci		d_lookup_done(dentry);
347162306a36Sopenharmony_ci		if (unlikely(res)) {
347262306a36Sopenharmony_ci			if (IS_ERR(res)) {
347362306a36Sopenharmony_ci				error = PTR_ERR(res);
347462306a36Sopenharmony_ci				goto out_dput;
347562306a36Sopenharmony_ci			}
347662306a36Sopenharmony_ci			dput(dentry);
347762306a36Sopenharmony_ci			dentry = res;
347862306a36Sopenharmony_ci		}
347962306a36Sopenharmony_ci	}
348062306a36Sopenharmony_ci
348162306a36Sopenharmony_ci	/* Negative dentry, just create the file */
348262306a36Sopenharmony_ci	if (!dentry->d_inode && (open_flag & O_CREAT)) {
348362306a36Sopenharmony_ci		file->f_mode |= FMODE_CREATED;
348462306a36Sopenharmony_ci		audit_inode_child(dir_inode, dentry, AUDIT_TYPE_CHILD_CREATE);
348562306a36Sopenharmony_ci		if (!dir_inode->i_op->create) {
348662306a36Sopenharmony_ci			error = -EACCES;
348762306a36Sopenharmony_ci			goto out_dput;
348862306a36Sopenharmony_ci		}
348962306a36Sopenharmony_ci
349062306a36Sopenharmony_ci		error = dir_inode->i_op->create(idmap, dir_inode, dentry,
349162306a36Sopenharmony_ci						mode, open_flag & O_EXCL);
349262306a36Sopenharmony_ci		if (error)
349362306a36Sopenharmony_ci			goto out_dput;
349462306a36Sopenharmony_ci	}
349562306a36Sopenharmony_ci	if (unlikely(create_error) && !dentry->d_inode) {
349662306a36Sopenharmony_ci		error = create_error;
349762306a36Sopenharmony_ci		goto out_dput;
349862306a36Sopenharmony_ci	}
349962306a36Sopenharmony_ci	return dentry;
350062306a36Sopenharmony_ci
350162306a36Sopenharmony_ciout_dput:
350262306a36Sopenharmony_ci	dput(dentry);
350362306a36Sopenharmony_ci	return ERR_PTR(error);
350462306a36Sopenharmony_ci}
350562306a36Sopenharmony_ci
350662306a36Sopenharmony_cistatic const char *open_last_lookups(struct nameidata *nd,
350762306a36Sopenharmony_ci		   struct file *file, const struct open_flags *op)
350862306a36Sopenharmony_ci{
350962306a36Sopenharmony_ci	struct dentry *dir = nd->path.dentry;
351062306a36Sopenharmony_ci	int open_flag = op->open_flag;
351162306a36Sopenharmony_ci	bool got_write = false;
351262306a36Sopenharmony_ci	struct dentry *dentry;
351362306a36Sopenharmony_ci	const char *res;
351462306a36Sopenharmony_ci
351562306a36Sopenharmony_ci	nd->flags |= op->intent;
351662306a36Sopenharmony_ci
351762306a36Sopenharmony_ci	if (nd->last_type != LAST_NORM) {
351862306a36Sopenharmony_ci		if (nd->depth)
351962306a36Sopenharmony_ci			put_link(nd);
352062306a36Sopenharmony_ci		return handle_dots(nd, nd->last_type);
352162306a36Sopenharmony_ci	}
352262306a36Sopenharmony_ci
352362306a36Sopenharmony_ci	if (!(open_flag & O_CREAT)) {
352462306a36Sopenharmony_ci		if (nd->last.name[nd->last.len])
352562306a36Sopenharmony_ci			nd->flags |= LOOKUP_FOLLOW | LOOKUP_DIRECTORY;
352662306a36Sopenharmony_ci		/* we _can_ be in RCU mode here */
352762306a36Sopenharmony_ci		dentry = lookup_fast(nd);
352862306a36Sopenharmony_ci		if (IS_ERR(dentry))
352962306a36Sopenharmony_ci			return ERR_CAST(dentry);
353062306a36Sopenharmony_ci		if (likely(dentry))
353162306a36Sopenharmony_ci			goto finish_lookup;
353262306a36Sopenharmony_ci
353362306a36Sopenharmony_ci		BUG_ON(nd->flags & LOOKUP_RCU);
353462306a36Sopenharmony_ci	} else {
353562306a36Sopenharmony_ci		/* create side of things */
353662306a36Sopenharmony_ci		if (nd->flags & LOOKUP_RCU) {
353762306a36Sopenharmony_ci			if (!try_to_unlazy(nd))
353862306a36Sopenharmony_ci				return ERR_PTR(-ECHILD);
353962306a36Sopenharmony_ci		}
354062306a36Sopenharmony_ci		audit_inode(nd->name, dir, AUDIT_INODE_PARENT);
354162306a36Sopenharmony_ci		/* trailing slashes? */
354262306a36Sopenharmony_ci		if (unlikely(nd->last.name[nd->last.len]))
354362306a36Sopenharmony_ci			return ERR_PTR(-EISDIR);
354462306a36Sopenharmony_ci	}
354562306a36Sopenharmony_ci
354662306a36Sopenharmony_ci	if (open_flag & (O_CREAT | O_TRUNC | O_WRONLY | O_RDWR)) {
354762306a36Sopenharmony_ci		got_write = !mnt_want_write(nd->path.mnt);
354862306a36Sopenharmony_ci		/*
354962306a36Sopenharmony_ci		 * do _not_ fail yet - we might not need that or fail with
355062306a36Sopenharmony_ci		 * a different error; let lookup_open() decide; we'll be
355162306a36Sopenharmony_ci		 * dropping this one anyway.
355262306a36Sopenharmony_ci		 */
355362306a36Sopenharmony_ci	}
355462306a36Sopenharmony_ci	if (open_flag & O_CREAT)
355562306a36Sopenharmony_ci		inode_lock(dir->d_inode);
355662306a36Sopenharmony_ci	else
355762306a36Sopenharmony_ci		inode_lock_shared(dir->d_inode);
355862306a36Sopenharmony_ci	dentry = lookup_open(nd, file, op, got_write);
355962306a36Sopenharmony_ci	if (!IS_ERR(dentry) && (file->f_mode & FMODE_CREATED))
356062306a36Sopenharmony_ci		fsnotify_create(dir->d_inode, dentry);
356162306a36Sopenharmony_ci	if (open_flag & O_CREAT)
356262306a36Sopenharmony_ci		inode_unlock(dir->d_inode);
356362306a36Sopenharmony_ci	else
356462306a36Sopenharmony_ci		inode_unlock_shared(dir->d_inode);
356562306a36Sopenharmony_ci
356662306a36Sopenharmony_ci	if (got_write)
356762306a36Sopenharmony_ci		mnt_drop_write(nd->path.mnt);
356862306a36Sopenharmony_ci
356962306a36Sopenharmony_ci	if (IS_ERR(dentry))
357062306a36Sopenharmony_ci		return ERR_CAST(dentry);
357162306a36Sopenharmony_ci
357262306a36Sopenharmony_ci	if (file->f_mode & (FMODE_OPENED | FMODE_CREATED)) {
357362306a36Sopenharmony_ci		dput(nd->path.dentry);
357462306a36Sopenharmony_ci		nd->path.dentry = dentry;
357562306a36Sopenharmony_ci		return NULL;
357662306a36Sopenharmony_ci	}
357762306a36Sopenharmony_ci
357862306a36Sopenharmony_cifinish_lookup:
357962306a36Sopenharmony_ci	if (nd->depth)
358062306a36Sopenharmony_ci		put_link(nd);
358162306a36Sopenharmony_ci	res = step_into(nd, WALK_TRAILING, dentry);
358262306a36Sopenharmony_ci	if (unlikely(res))
358362306a36Sopenharmony_ci		nd->flags &= ~(LOOKUP_OPEN|LOOKUP_CREATE|LOOKUP_EXCL);
358462306a36Sopenharmony_ci	return res;
358562306a36Sopenharmony_ci}
358662306a36Sopenharmony_ci
358762306a36Sopenharmony_ci/*
358862306a36Sopenharmony_ci * Handle the last step of open()
358962306a36Sopenharmony_ci */
359062306a36Sopenharmony_cistatic int do_open(struct nameidata *nd,
359162306a36Sopenharmony_ci		   struct file *file, const struct open_flags *op)
359262306a36Sopenharmony_ci{
359362306a36Sopenharmony_ci	struct mnt_idmap *idmap;
359462306a36Sopenharmony_ci	int open_flag = op->open_flag;
359562306a36Sopenharmony_ci	bool do_truncate;
359662306a36Sopenharmony_ci	int acc_mode;
359762306a36Sopenharmony_ci	int error;
359862306a36Sopenharmony_ci
359962306a36Sopenharmony_ci	if (!(file->f_mode & (FMODE_OPENED | FMODE_CREATED))) {
360062306a36Sopenharmony_ci		error = complete_walk(nd);
360162306a36Sopenharmony_ci		if (error)
360262306a36Sopenharmony_ci			return error;
360362306a36Sopenharmony_ci	}
360462306a36Sopenharmony_ci	if (!(file->f_mode & FMODE_CREATED))
360562306a36Sopenharmony_ci		audit_inode(nd->name, nd->path.dentry, 0);
360662306a36Sopenharmony_ci	idmap = mnt_idmap(nd->path.mnt);
360762306a36Sopenharmony_ci	if (open_flag & O_CREAT) {
360862306a36Sopenharmony_ci		if ((open_flag & O_EXCL) && !(file->f_mode & FMODE_CREATED))
360962306a36Sopenharmony_ci			return -EEXIST;
361062306a36Sopenharmony_ci		if (d_is_dir(nd->path.dentry))
361162306a36Sopenharmony_ci			return -EISDIR;
361262306a36Sopenharmony_ci		error = may_create_in_sticky(idmap, nd,
361362306a36Sopenharmony_ci					     d_backing_inode(nd->path.dentry));
361462306a36Sopenharmony_ci		if (unlikely(error))
361562306a36Sopenharmony_ci			return error;
361662306a36Sopenharmony_ci	}
361762306a36Sopenharmony_ci	if ((nd->flags & LOOKUP_DIRECTORY) && !d_can_lookup(nd->path.dentry))
361862306a36Sopenharmony_ci		return -ENOTDIR;
361962306a36Sopenharmony_ci
362062306a36Sopenharmony_ci	do_truncate = false;
362162306a36Sopenharmony_ci	acc_mode = op->acc_mode;
362262306a36Sopenharmony_ci	if (file->f_mode & FMODE_CREATED) {
362362306a36Sopenharmony_ci		/* Don't check for write permission, don't truncate */
362462306a36Sopenharmony_ci		open_flag &= ~O_TRUNC;
362562306a36Sopenharmony_ci		acc_mode = 0;
362662306a36Sopenharmony_ci	} else if (d_is_reg(nd->path.dentry) && open_flag & O_TRUNC) {
362762306a36Sopenharmony_ci		error = mnt_want_write(nd->path.mnt);
362862306a36Sopenharmony_ci		if (error)
362962306a36Sopenharmony_ci			return error;
363062306a36Sopenharmony_ci		do_truncate = true;
363162306a36Sopenharmony_ci	}
363262306a36Sopenharmony_ci	error = may_open(idmap, &nd->path, acc_mode, open_flag);
363362306a36Sopenharmony_ci	if (!error && !(file->f_mode & FMODE_OPENED))
363462306a36Sopenharmony_ci		error = vfs_open(&nd->path, file);
363562306a36Sopenharmony_ci	if (!error)
363662306a36Sopenharmony_ci		error = ima_file_check(file, op->acc_mode);
363762306a36Sopenharmony_ci	if (!error && do_truncate)
363862306a36Sopenharmony_ci		error = handle_truncate(idmap, file);
363962306a36Sopenharmony_ci	if (unlikely(error > 0)) {
364062306a36Sopenharmony_ci		WARN_ON(1);
364162306a36Sopenharmony_ci		error = -EINVAL;
364262306a36Sopenharmony_ci	}
364362306a36Sopenharmony_ci	if (do_truncate)
364462306a36Sopenharmony_ci		mnt_drop_write(nd->path.mnt);
364562306a36Sopenharmony_ci	return error;
364662306a36Sopenharmony_ci}
364762306a36Sopenharmony_ci
364862306a36Sopenharmony_ci/**
364962306a36Sopenharmony_ci * vfs_tmpfile - create tmpfile
365062306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
365162306a36Sopenharmony_ci * @parentpath:	pointer to the path of the base directory
365262306a36Sopenharmony_ci * @file:	file descriptor of the new tmpfile
365362306a36Sopenharmony_ci * @mode:	mode of the new tmpfile
365462306a36Sopenharmony_ci *
365562306a36Sopenharmony_ci * Create a temporary file.
365662306a36Sopenharmony_ci *
365762306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
365862306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
365962306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
366062306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
366162306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
366262306a36Sopenharmony_ci */
366362306a36Sopenharmony_cistatic int vfs_tmpfile(struct mnt_idmap *idmap,
366462306a36Sopenharmony_ci		       const struct path *parentpath,
366562306a36Sopenharmony_ci		       struct file *file, umode_t mode)
366662306a36Sopenharmony_ci{
366762306a36Sopenharmony_ci	struct dentry *child;
366862306a36Sopenharmony_ci	struct inode *dir = d_inode(parentpath->dentry);
366962306a36Sopenharmony_ci	struct inode *inode;
367062306a36Sopenharmony_ci	int error;
367162306a36Sopenharmony_ci	int open_flag = file->f_flags;
367262306a36Sopenharmony_ci
367362306a36Sopenharmony_ci	/* we want directory to be writable */
367462306a36Sopenharmony_ci	error = inode_permission(idmap, dir, MAY_WRITE | MAY_EXEC);
367562306a36Sopenharmony_ci	if (error)
367662306a36Sopenharmony_ci		return error;
367762306a36Sopenharmony_ci	if (!dir->i_op->tmpfile)
367862306a36Sopenharmony_ci		return -EOPNOTSUPP;
367962306a36Sopenharmony_ci	child = d_alloc(parentpath->dentry, &slash_name);
368062306a36Sopenharmony_ci	if (unlikely(!child))
368162306a36Sopenharmony_ci		return -ENOMEM;
368262306a36Sopenharmony_ci	file->f_path.mnt = parentpath->mnt;
368362306a36Sopenharmony_ci	file->f_path.dentry = child;
368462306a36Sopenharmony_ci	mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
368562306a36Sopenharmony_ci	error = dir->i_op->tmpfile(idmap, dir, file, mode);
368662306a36Sopenharmony_ci	dput(child);
368762306a36Sopenharmony_ci	if (error)
368862306a36Sopenharmony_ci		return error;
368962306a36Sopenharmony_ci	/* Don't check for other permissions, the inode was just created */
369062306a36Sopenharmony_ci	error = may_open(idmap, &file->f_path, 0, file->f_flags);
369162306a36Sopenharmony_ci	if (error)
369262306a36Sopenharmony_ci		return error;
369362306a36Sopenharmony_ci	inode = file_inode(file);
369462306a36Sopenharmony_ci	if (!(open_flag & O_EXCL)) {
369562306a36Sopenharmony_ci		spin_lock(&inode->i_lock);
369662306a36Sopenharmony_ci		inode->i_state |= I_LINKABLE;
369762306a36Sopenharmony_ci		spin_unlock(&inode->i_lock);
369862306a36Sopenharmony_ci	}
369962306a36Sopenharmony_ci	ima_post_create_tmpfile(idmap, inode);
370062306a36Sopenharmony_ci	return 0;
370162306a36Sopenharmony_ci}
370262306a36Sopenharmony_ci
370362306a36Sopenharmony_ci/**
370462306a36Sopenharmony_ci * kernel_tmpfile_open - open a tmpfile for kernel internal use
370562306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
370662306a36Sopenharmony_ci * @parentpath:	path of the base directory
370762306a36Sopenharmony_ci * @mode:	mode of the new tmpfile
370862306a36Sopenharmony_ci * @open_flag:	flags
370962306a36Sopenharmony_ci * @cred:	credentials for open
371062306a36Sopenharmony_ci *
371162306a36Sopenharmony_ci * Create and open a temporary file.  The file is not accounted in nr_files,
371262306a36Sopenharmony_ci * hence this is only for kernel internal use, and must not be installed into
371362306a36Sopenharmony_ci * file tables or such.
371462306a36Sopenharmony_ci */
371562306a36Sopenharmony_cistruct file *kernel_tmpfile_open(struct mnt_idmap *idmap,
371662306a36Sopenharmony_ci				 const struct path *parentpath,
371762306a36Sopenharmony_ci				 umode_t mode, int open_flag,
371862306a36Sopenharmony_ci				 const struct cred *cred)
371962306a36Sopenharmony_ci{
372062306a36Sopenharmony_ci	struct file *file;
372162306a36Sopenharmony_ci	int error;
372262306a36Sopenharmony_ci
372362306a36Sopenharmony_ci	file = alloc_empty_file_noaccount(open_flag, cred);
372462306a36Sopenharmony_ci	if (IS_ERR(file))
372562306a36Sopenharmony_ci		return file;
372662306a36Sopenharmony_ci
372762306a36Sopenharmony_ci	error = vfs_tmpfile(idmap, parentpath, file, mode);
372862306a36Sopenharmony_ci	if (error) {
372962306a36Sopenharmony_ci		fput(file);
373062306a36Sopenharmony_ci		file = ERR_PTR(error);
373162306a36Sopenharmony_ci	}
373262306a36Sopenharmony_ci	return file;
373362306a36Sopenharmony_ci}
373462306a36Sopenharmony_ciEXPORT_SYMBOL(kernel_tmpfile_open);
373562306a36Sopenharmony_ci
373662306a36Sopenharmony_cistatic int do_tmpfile(struct nameidata *nd, unsigned flags,
373762306a36Sopenharmony_ci		const struct open_flags *op,
373862306a36Sopenharmony_ci		struct file *file)
373962306a36Sopenharmony_ci{
374062306a36Sopenharmony_ci	struct path path;
374162306a36Sopenharmony_ci	int error = path_lookupat(nd, flags | LOOKUP_DIRECTORY, &path);
374262306a36Sopenharmony_ci
374362306a36Sopenharmony_ci	if (unlikely(error))
374462306a36Sopenharmony_ci		return error;
374562306a36Sopenharmony_ci	error = mnt_want_write(path.mnt);
374662306a36Sopenharmony_ci	if (unlikely(error))
374762306a36Sopenharmony_ci		goto out;
374862306a36Sopenharmony_ci	error = vfs_tmpfile(mnt_idmap(path.mnt), &path, file, op->mode);
374962306a36Sopenharmony_ci	if (error)
375062306a36Sopenharmony_ci		goto out2;
375162306a36Sopenharmony_ci	audit_inode(nd->name, file->f_path.dentry, 0);
375262306a36Sopenharmony_ciout2:
375362306a36Sopenharmony_ci	mnt_drop_write(path.mnt);
375462306a36Sopenharmony_ciout:
375562306a36Sopenharmony_ci	path_put(&path);
375662306a36Sopenharmony_ci	return error;
375762306a36Sopenharmony_ci}
375862306a36Sopenharmony_ci
375962306a36Sopenharmony_cistatic int do_o_path(struct nameidata *nd, unsigned flags, struct file *file)
376062306a36Sopenharmony_ci{
376162306a36Sopenharmony_ci	struct path path;
376262306a36Sopenharmony_ci	int error = path_lookupat(nd, flags, &path);
376362306a36Sopenharmony_ci	if (!error) {
376462306a36Sopenharmony_ci		audit_inode(nd->name, path.dentry, 0);
376562306a36Sopenharmony_ci		error = vfs_open(&path, file);
376662306a36Sopenharmony_ci		path_put(&path);
376762306a36Sopenharmony_ci	}
376862306a36Sopenharmony_ci	return error;
376962306a36Sopenharmony_ci}
377062306a36Sopenharmony_ci
377162306a36Sopenharmony_cistatic struct file *path_openat(struct nameidata *nd,
377262306a36Sopenharmony_ci			const struct open_flags *op, unsigned flags)
377362306a36Sopenharmony_ci{
377462306a36Sopenharmony_ci	struct file *file;
377562306a36Sopenharmony_ci	int error;
377662306a36Sopenharmony_ci
377762306a36Sopenharmony_ci	file = alloc_empty_file(op->open_flag, current_cred());
377862306a36Sopenharmony_ci	if (IS_ERR(file))
377962306a36Sopenharmony_ci		return file;
378062306a36Sopenharmony_ci
378162306a36Sopenharmony_ci	if (unlikely(file->f_flags & __O_TMPFILE)) {
378262306a36Sopenharmony_ci		error = do_tmpfile(nd, flags, op, file);
378362306a36Sopenharmony_ci	} else if (unlikely(file->f_flags & O_PATH)) {
378462306a36Sopenharmony_ci		error = do_o_path(nd, flags, file);
378562306a36Sopenharmony_ci	} else {
378662306a36Sopenharmony_ci		const char *s = path_init(nd, flags);
378762306a36Sopenharmony_ci		while (!(error = link_path_walk(s, nd)) &&
378862306a36Sopenharmony_ci		       (s = open_last_lookups(nd, file, op)) != NULL)
378962306a36Sopenharmony_ci			;
379062306a36Sopenharmony_ci		if (!error)
379162306a36Sopenharmony_ci			error = do_open(nd, file, op);
379262306a36Sopenharmony_ci		terminate_walk(nd);
379362306a36Sopenharmony_ci	}
379462306a36Sopenharmony_ci	if (likely(!error)) {
379562306a36Sopenharmony_ci		if (likely(file->f_mode & FMODE_OPENED))
379662306a36Sopenharmony_ci			return file;
379762306a36Sopenharmony_ci		WARN_ON(1);
379862306a36Sopenharmony_ci		error = -EINVAL;
379962306a36Sopenharmony_ci	}
380062306a36Sopenharmony_ci	fput(file);
380162306a36Sopenharmony_ci	if (error == -EOPENSTALE) {
380262306a36Sopenharmony_ci		if (flags & LOOKUP_RCU)
380362306a36Sopenharmony_ci			error = -ECHILD;
380462306a36Sopenharmony_ci		else
380562306a36Sopenharmony_ci			error = -ESTALE;
380662306a36Sopenharmony_ci	}
380762306a36Sopenharmony_ci	return ERR_PTR(error);
380862306a36Sopenharmony_ci}
380962306a36Sopenharmony_ci
381062306a36Sopenharmony_cistruct file *do_filp_open(int dfd, struct filename *pathname,
381162306a36Sopenharmony_ci		const struct open_flags *op)
381262306a36Sopenharmony_ci{
381362306a36Sopenharmony_ci	struct nameidata nd;
381462306a36Sopenharmony_ci	int flags = op->lookup_flags;
381562306a36Sopenharmony_ci	struct file *filp;
381662306a36Sopenharmony_ci
381762306a36Sopenharmony_ci	set_nameidata(&nd, dfd, pathname, NULL);
381862306a36Sopenharmony_ci	filp = path_openat(&nd, op, flags | LOOKUP_RCU);
381962306a36Sopenharmony_ci	if (unlikely(filp == ERR_PTR(-ECHILD)))
382062306a36Sopenharmony_ci		filp = path_openat(&nd, op, flags);
382162306a36Sopenharmony_ci	if (unlikely(filp == ERR_PTR(-ESTALE)))
382262306a36Sopenharmony_ci		filp = path_openat(&nd, op, flags | LOOKUP_REVAL);
382362306a36Sopenharmony_ci	restore_nameidata();
382462306a36Sopenharmony_ci	return filp;
382562306a36Sopenharmony_ci}
382662306a36Sopenharmony_ci
382762306a36Sopenharmony_cistruct file *do_file_open_root(const struct path *root,
382862306a36Sopenharmony_ci		const char *name, const struct open_flags *op)
382962306a36Sopenharmony_ci{
383062306a36Sopenharmony_ci	struct nameidata nd;
383162306a36Sopenharmony_ci	struct file *file;
383262306a36Sopenharmony_ci	struct filename *filename;
383362306a36Sopenharmony_ci	int flags = op->lookup_flags;
383462306a36Sopenharmony_ci
383562306a36Sopenharmony_ci	if (d_is_symlink(root->dentry) && op->intent & LOOKUP_OPEN)
383662306a36Sopenharmony_ci		return ERR_PTR(-ELOOP);
383762306a36Sopenharmony_ci
383862306a36Sopenharmony_ci	filename = getname_kernel(name);
383962306a36Sopenharmony_ci	if (IS_ERR(filename))
384062306a36Sopenharmony_ci		return ERR_CAST(filename);
384162306a36Sopenharmony_ci
384262306a36Sopenharmony_ci	set_nameidata(&nd, -1, filename, root);
384362306a36Sopenharmony_ci	file = path_openat(&nd, op, flags | LOOKUP_RCU);
384462306a36Sopenharmony_ci	if (unlikely(file == ERR_PTR(-ECHILD)))
384562306a36Sopenharmony_ci		file = path_openat(&nd, op, flags);
384662306a36Sopenharmony_ci	if (unlikely(file == ERR_PTR(-ESTALE)))
384762306a36Sopenharmony_ci		file = path_openat(&nd, op, flags | LOOKUP_REVAL);
384862306a36Sopenharmony_ci	restore_nameidata();
384962306a36Sopenharmony_ci	putname(filename);
385062306a36Sopenharmony_ci	return file;
385162306a36Sopenharmony_ci}
385262306a36Sopenharmony_ci
385362306a36Sopenharmony_cistatic struct dentry *filename_create(int dfd, struct filename *name,
385462306a36Sopenharmony_ci				      struct path *path, unsigned int lookup_flags)
385562306a36Sopenharmony_ci{
385662306a36Sopenharmony_ci	struct dentry *dentry = ERR_PTR(-EEXIST);
385762306a36Sopenharmony_ci	struct qstr last;
385862306a36Sopenharmony_ci	bool want_dir = lookup_flags & LOOKUP_DIRECTORY;
385962306a36Sopenharmony_ci	unsigned int reval_flag = lookup_flags & LOOKUP_REVAL;
386062306a36Sopenharmony_ci	unsigned int create_flags = LOOKUP_CREATE | LOOKUP_EXCL;
386162306a36Sopenharmony_ci	int type;
386262306a36Sopenharmony_ci	int err2;
386362306a36Sopenharmony_ci	int error;
386462306a36Sopenharmony_ci
386562306a36Sopenharmony_ci	error = filename_parentat(dfd, name, reval_flag, path, &last, &type);
386662306a36Sopenharmony_ci	if (error)
386762306a36Sopenharmony_ci		return ERR_PTR(error);
386862306a36Sopenharmony_ci
386962306a36Sopenharmony_ci	/*
387062306a36Sopenharmony_ci	 * Yucky last component or no last component at all?
387162306a36Sopenharmony_ci	 * (foo/., foo/.., /////)
387262306a36Sopenharmony_ci	 */
387362306a36Sopenharmony_ci	if (unlikely(type != LAST_NORM))
387462306a36Sopenharmony_ci		goto out;
387562306a36Sopenharmony_ci
387662306a36Sopenharmony_ci	/* don't fail immediately if it's r/o, at least try to report other errors */
387762306a36Sopenharmony_ci	err2 = mnt_want_write(path->mnt);
387862306a36Sopenharmony_ci	/*
387962306a36Sopenharmony_ci	 * Do the final lookup.  Suppress 'create' if there is a trailing
388062306a36Sopenharmony_ci	 * '/', and a directory wasn't requested.
388162306a36Sopenharmony_ci	 */
388262306a36Sopenharmony_ci	if (last.name[last.len] && !want_dir)
388362306a36Sopenharmony_ci		create_flags = 0;
388462306a36Sopenharmony_ci	inode_lock_nested(path->dentry->d_inode, I_MUTEX_PARENT);
388562306a36Sopenharmony_ci	dentry = lookup_one_qstr_excl(&last, path->dentry,
388662306a36Sopenharmony_ci				      reval_flag | create_flags);
388762306a36Sopenharmony_ci	if (IS_ERR(dentry))
388862306a36Sopenharmony_ci		goto unlock;
388962306a36Sopenharmony_ci
389062306a36Sopenharmony_ci	error = -EEXIST;
389162306a36Sopenharmony_ci	if (d_is_positive(dentry))
389262306a36Sopenharmony_ci		goto fail;
389362306a36Sopenharmony_ci
389462306a36Sopenharmony_ci	/*
389562306a36Sopenharmony_ci	 * Special case - lookup gave negative, but... we had foo/bar/
389662306a36Sopenharmony_ci	 * From the vfs_mknod() POV we just have a negative dentry -
389762306a36Sopenharmony_ci	 * all is fine. Let's be bastards - you had / on the end, you've
389862306a36Sopenharmony_ci	 * been asking for (non-existent) directory. -ENOENT for you.
389962306a36Sopenharmony_ci	 */
390062306a36Sopenharmony_ci	if (unlikely(!create_flags)) {
390162306a36Sopenharmony_ci		error = -ENOENT;
390262306a36Sopenharmony_ci		goto fail;
390362306a36Sopenharmony_ci	}
390462306a36Sopenharmony_ci	if (unlikely(err2)) {
390562306a36Sopenharmony_ci		error = err2;
390662306a36Sopenharmony_ci		goto fail;
390762306a36Sopenharmony_ci	}
390862306a36Sopenharmony_ci	return dentry;
390962306a36Sopenharmony_cifail:
391062306a36Sopenharmony_ci	dput(dentry);
391162306a36Sopenharmony_ci	dentry = ERR_PTR(error);
391262306a36Sopenharmony_ciunlock:
391362306a36Sopenharmony_ci	inode_unlock(path->dentry->d_inode);
391462306a36Sopenharmony_ci	if (!err2)
391562306a36Sopenharmony_ci		mnt_drop_write(path->mnt);
391662306a36Sopenharmony_ciout:
391762306a36Sopenharmony_ci	path_put(path);
391862306a36Sopenharmony_ci	return dentry;
391962306a36Sopenharmony_ci}
392062306a36Sopenharmony_ci
392162306a36Sopenharmony_cistruct dentry *kern_path_create(int dfd, const char *pathname,
392262306a36Sopenharmony_ci				struct path *path, unsigned int lookup_flags)
392362306a36Sopenharmony_ci{
392462306a36Sopenharmony_ci	struct filename *filename = getname_kernel(pathname);
392562306a36Sopenharmony_ci	struct dentry *res = filename_create(dfd, filename, path, lookup_flags);
392662306a36Sopenharmony_ci
392762306a36Sopenharmony_ci	putname(filename);
392862306a36Sopenharmony_ci	return res;
392962306a36Sopenharmony_ci}
393062306a36Sopenharmony_ciEXPORT_SYMBOL(kern_path_create);
393162306a36Sopenharmony_ci
393262306a36Sopenharmony_civoid done_path_create(struct path *path, struct dentry *dentry)
393362306a36Sopenharmony_ci{
393462306a36Sopenharmony_ci	dput(dentry);
393562306a36Sopenharmony_ci	inode_unlock(path->dentry->d_inode);
393662306a36Sopenharmony_ci	mnt_drop_write(path->mnt);
393762306a36Sopenharmony_ci	path_put(path);
393862306a36Sopenharmony_ci}
393962306a36Sopenharmony_ciEXPORT_SYMBOL(done_path_create);
394062306a36Sopenharmony_ci
394162306a36Sopenharmony_ciinline struct dentry *user_path_create(int dfd, const char __user *pathname,
394262306a36Sopenharmony_ci				struct path *path, unsigned int lookup_flags)
394362306a36Sopenharmony_ci{
394462306a36Sopenharmony_ci	struct filename *filename = getname(pathname);
394562306a36Sopenharmony_ci	struct dentry *res = filename_create(dfd, filename, path, lookup_flags);
394662306a36Sopenharmony_ci
394762306a36Sopenharmony_ci	putname(filename);
394862306a36Sopenharmony_ci	return res;
394962306a36Sopenharmony_ci}
395062306a36Sopenharmony_ciEXPORT_SYMBOL(user_path_create);
395162306a36Sopenharmony_ci
395262306a36Sopenharmony_ci/**
395362306a36Sopenharmony_ci * vfs_mknod - create device node or file
395462306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
395562306a36Sopenharmony_ci * @dir:	inode of @dentry
395662306a36Sopenharmony_ci * @dentry:	pointer to dentry of the base directory
395762306a36Sopenharmony_ci * @mode:	mode of the new device node or file
395862306a36Sopenharmony_ci * @dev:	device number of device to create
395962306a36Sopenharmony_ci *
396062306a36Sopenharmony_ci * Create a device node or file.
396162306a36Sopenharmony_ci *
396262306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
396362306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
396462306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
396562306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
396662306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
396762306a36Sopenharmony_ci */
396862306a36Sopenharmony_ciint vfs_mknod(struct mnt_idmap *idmap, struct inode *dir,
396962306a36Sopenharmony_ci	      struct dentry *dentry, umode_t mode, dev_t dev)
397062306a36Sopenharmony_ci{
397162306a36Sopenharmony_ci	bool is_whiteout = S_ISCHR(mode) && dev == WHITEOUT_DEV;
397262306a36Sopenharmony_ci	int error = may_create(idmap, dir, dentry);
397362306a36Sopenharmony_ci
397462306a36Sopenharmony_ci	if (error)
397562306a36Sopenharmony_ci		return error;
397662306a36Sopenharmony_ci
397762306a36Sopenharmony_ci	if ((S_ISCHR(mode) || S_ISBLK(mode)) && !is_whiteout &&
397862306a36Sopenharmony_ci	    !capable(CAP_MKNOD))
397962306a36Sopenharmony_ci		return -EPERM;
398062306a36Sopenharmony_ci
398162306a36Sopenharmony_ci	if (!dir->i_op->mknod)
398262306a36Sopenharmony_ci		return -EPERM;
398362306a36Sopenharmony_ci
398462306a36Sopenharmony_ci	mode = vfs_prepare_mode(idmap, dir, mode, mode, mode);
398562306a36Sopenharmony_ci	error = devcgroup_inode_mknod(mode, dev);
398662306a36Sopenharmony_ci	if (error)
398762306a36Sopenharmony_ci		return error;
398862306a36Sopenharmony_ci
398962306a36Sopenharmony_ci	error = security_inode_mknod(dir, dentry, mode, dev);
399062306a36Sopenharmony_ci	if (error)
399162306a36Sopenharmony_ci		return error;
399262306a36Sopenharmony_ci
399362306a36Sopenharmony_ci	error = dir->i_op->mknod(idmap, dir, dentry, mode, dev);
399462306a36Sopenharmony_ci	if (!error)
399562306a36Sopenharmony_ci		fsnotify_create(dir, dentry);
399662306a36Sopenharmony_ci	return error;
399762306a36Sopenharmony_ci}
399862306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_mknod);
399962306a36Sopenharmony_ci
400062306a36Sopenharmony_cistatic int may_mknod(umode_t mode)
400162306a36Sopenharmony_ci{
400262306a36Sopenharmony_ci	switch (mode & S_IFMT) {
400362306a36Sopenharmony_ci	case S_IFREG:
400462306a36Sopenharmony_ci	case S_IFCHR:
400562306a36Sopenharmony_ci	case S_IFBLK:
400662306a36Sopenharmony_ci	case S_IFIFO:
400762306a36Sopenharmony_ci	case S_IFSOCK:
400862306a36Sopenharmony_ci	case 0: /* zero mode translates to S_IFREG */
400962306a36Sopenharmony_ci		return 0;
401062306a36Sopenharmony_ci	case S_IFDIR:
401162306a36Sopenharmony_ci		return -EPERM;
401262306a36Sopenharmony_ci	default:
401362306a36Sopenharmony_ci		return -EINVAL;
401462306a36Sopenharmony_ci	}
401562306a36Sopenharmony_ci}
401662306a36Sopenharmony_ci
401762306a36Sopenharmony_cistatic int do_mknodat(int dfd, struct filename *name, umode_t mode,
401862306a36Sopenharmony_ci		unsigned int dev)
401962306a36Sopenharmony_ci{
402062306a36Sopenharmony_ci	struct mnt_idmap *idmap;
402162306a36Sopenharmony_ci	struct dentry *dentry;
402262306a36Sopenharmony_ci	struct path path;
402362306a36Sopenharmony_ci	int error;
402462306a36Sopenharmony_ci	unsigned int lookup_flags = 0;
402562306a36Sopenharmony_ci
402662306a36Sopenharmony_ci	error = may_mknod(mode);
402762306a36Sopenharmony_ci	if (error)
402862306a36Sopenharmony_ci		goto out1;
402962306a36Sopenharmony_ciretry:
403062306a36Sopenharmony_ci	dentry = filename_create(dfd, name, &path, lookup_flags);
403162306a36Sopenharmony_ci	error = PTR_ERR(dentry);
403262306a36Sopenharmony_ci	if (IS_ERR(dentry))
403362306a36Sopenharmony_ci		goto out1;
403462306a36Sopenharmony_ci
403562306a36Sopenharmony_ci	error = security_path_mknod(&path, dentry,
403662306a36Sopenharmony_ci			mode_strip_umask(path.dentry->d_inode, mode), dev);
403762306a36Sopenharmony_ci	if (error)
403862306a36Sopenharmony_ci		goto out2;
403962306a36Sopenharmony_ci
404062306a36Sopenharmony_ci	idmap = mnt_idmap(path.mnt);
404162306a36Sopenharmony_ci	switch (mode & S_IFMT) {
404262306a36Sopenharmony_ci		case 0: case S_IFREG:
404362306a36Sopenharmony_ci			error = vfs_create(idmap, path.dentry->d_inode,
404462306a36Sopenharmony_ci					   dentry, mode, true);
404562306a36Sopenharmony_ci			if (!error)
404662306a36Sopenharmony_ci				ima_post_path_mknod(idmap, dentry);
404762306a36Sopenharmony_ci			break;
404862306a36Sopenharmony_ci		case S_IFCHR: case S_IFBLK:
404962306a36Sopenharmony_ci			error = vfs_mknod(idmap, path.dentry->d_inode,
405062306a36Sopenharmony_ci					  dentry, mode, new_decode_dev(dev));
405162306a36Sopenharmony_ci			break;
405262306a36Sopenharmony_ci		case S_IFIFO: case S_IFSOCK:
405362306a36Sopenharmony_ci			error = vfs_mknod(idmap, path.dentry->d_inode,
405462306a36Sopenharmony_ci					  dentry, mode, 0);
405562306a36Sopenharmony_ci			break;
405662306a36Sopenharmony_ci	}
405762306a36Sopenharmony_ciout2:
405862306a36Sopenharmony_ci	done_path_create(&path, dentry);
405962306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags)) {
406062306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
406162306a36Sopenharmony_ci		goto retry;
406262306a36Sopenharmony_ci	}
406362306a36Sopenharmony_ciout1:
406462306a36Sopenharmony_ci	putname(name);
406562306a36Sopenharmony_ci	return error;
406662306a36Sopenharmony_ci}
406762306a36Sopenharmony_ci
406862306a36Sopenharmony_ciSYSCALL_DEFINE4(mknodat, int, dfd, const char __user *, filename, umode_t, mode,
406962306a36Sopenharmony_ci		unsigned int, dev)
407062306a36Sopenharmony_ci{
407162306a36Sopenharmony_ci	return do_mknodat(dfd, getname(filename), mode, dev);
407262306a36Sopenharmony_ci}
407362306a36Sopenharmony_ci
407462306a36Sopenharmony_ciSYSCALL_DEFINE3(mknod, const char __user *, filename, umode_t, mode, unsigned, dev)
407562306a36Sopenharmony_ci{
407662306a36Sopenharmony_ci	return do_mknodat(AT_FDCWD, getname(filename), mode, dev);
407762306a36Sopenharmony_ci}
407862306a36Sopenharmony_ci
407962306a36Sopenharmony_ci/**
408062306a36Sopenharmony_ci * vfs_mkdir - create directory
408162306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
408262306a36Sopenharmony_ci * @dir:	inode of @dentry
408362306a36Sopenharmony_ci * @dentry:	pointer to dentry of the base directory
408462306a36Sopenharmony_ci * @mode:	mode of the new directory
408562306a36Sopenharmony_ci *
408662306a36Sopenharmony_ci * Create a directory.
408762306a36Sopenharmony_ci *
408862306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
408962306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
409062306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
409162306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
409262306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
409362306a36Sopenharmony_ci */
409462306a36Sopenharmony_ciint vfs_mkdir(struct mnt_idmap *idmap, struct inode *dir,
409562306a36Sopenharmony_ci	      struct dentry *dentry, umode_t mode)
409662306a36Sopenharmony_ci{
409762306a36Sopenharmony_ci	int error;
409862306a36Sopenharmony_ci	unsigned max_links = dir->i_sb->s_max_links;
409962306a36Sopenharmony_ci
410062306a36Sopenharmony_ci	error = may_create(idmap, dir, dentry);
410162306a36Sopenharmony_ci	if (error)
410262306a36Sopenharmony_ci		return error;
410362306a36Sopenharmony_ci
410462306a36Sopenharmony_ci	if (!dir->i_op->mkdir)
410562306a36Sopenharmony_ci		return -EPERM;
410662306a36Sopenharmony_ci
410762306a36Sopenharmony_ci	mode = vfs_prepare_mode(idmap, dir, mode, S_IRWXUGO | S_ISVTX, 0);
410862306a36Sopenharmony_ci	error = security_inode_mkdir(dir, dentry, mode);
410962306a36Sopenharmony_ci	if (error)
411062306a36Sopenharmony_ci		return error;
411162306a36Sopenharmony_ci
411262306a36Sopenharmony_ci	if (max_links && dir->i_nlink >= max_links)
411362306a36Sopenharmony_ci		return -EMLINK;
411462306a36Sopenharmony_ci
411562306a36Sopenharmony_ci	error = dir->i_op->mkdir(idmap, dir, dentry, mode);
411662306a36Sopenharmony_ci	if (!error)
411762306a36Sopenharmony_ci		fsnotify_mkdir(dir, dentry);
411862306a36Sopenharmony_ci	return error;
411962306a36Sopenharmony_ci}
412062306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_mkdir);
412162306a36Sopenharmony_ci
412262306a36Sopenharmony_ciint do_mkdirat(int dfd, struct filename *name, umode_t mode)
412362306a36Sopenharmony_ci{
412462306a36Sopenharmony_ci	struct dentry *dentry;
412562306a36Sopenharmony_ci	struct path path;
412662306a36Sopenharmony_ci	int error;
412762306a36Sopenharmony_ci	unsigned int lookup_flags = LOOKUP_DIRECTORY;
412862306a36Sopenharmony_ci
412962306a36Sopenharmony_ciretry:
413062306a36Sopenharmony_ci	dentry = filename_create(dfd, name, &path, lookup_flags);
413162306a36Sopenharmony_ci	error = PTR_ERR(dentry);
413262306a36Sopenharmony_ci	if (IS_ERR(dentry))
413362306a36Sopenharmony_ci		goto out_putname;
413462306a36Sopenharmony_ci
413562306a36Sopenharmony_ci	error = security_path_mkdir(&path, dentry,
413662306a36Sopenharmony_ci			mode_strip_umask(path.dentry->d_inode, mode));
413762306a36Sopenharmony_ci	if (!error) {
413862306a36Sopenharmony_ci		error = vfs_mkdir(mnt_idmap(path.mnt), path.dentry->d_inode,
413962306a36Sopenharmony_ci				  dentry, mode);
414062306a36Sopenharmony_ci	}
414162306a36Sopenharmony_ci	done_path_create(&path, dentry);
414262306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags)) {
414362306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
414462306a36Sopenharmony_ci		goto retry;
414562306a36Sopenharmony_ci	}
414662306a36Sopenharmony_ciout_putname:
414762306a36Sopenharmony_ci	putname(name);
414862306a36Sopenharmony_ci	return error;
414962306a36Sopenharmony_ci}
415062306a36Sopenharmony_ci
415162306a36Sopenharmony_ciSYSCALL_DEFINE3(mkdirat, int, dfd, const char __user *, pathname, umode_t, mode)
415262306a36Sopenharmony_ci{
415362306a36Sopenharmony_ci	return do_mkdirat(dfd, getname(pathname), mode);
415462306a36Sopenharmony_ci}
415562306a36Sopenharmony_ci
415662306a36Sopenharmony_ciSYSCALL_DEFINE2(mkdir, const char __user *, pathname, umode_t, mode)
415762306a36Sopenharmony_ci{
415862306a36Sopenharmony_ci	return do_mkdirat(AT_FDCWD, getname(pathname), mode);
415962306a36Sopenharmony_ci}
416062306a36Sopenharmony_ci
416162306a36Sopenharmony_ci/**
416262306a36Sopenharmony_ci * vfs_rmdir - remove directory
416362306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
416462306a36Sopenharmony_ci * @dir:	inode of @dentry
416562306a36Sopenharmony_ci * @dentry:	pointer to dentry of the base directory
416662306a36Sopenharmony_ci *
416762306a36Sopenharmony_ci * Remove a directory.
416862306a36Sopenharmony_ci *
416962306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
417062306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
417162306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
417262306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
417362306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
417462306a36Sopenharmony_ci */
417562306a36Sopenharmony_ciint vfs_rmdir(struct mnt_idmap *idmap, struct inode *dir,
417662306a36Sopenharmony_ci		     struct dentry *dentry)
417762306a36Sopenharmony_ci{
417862306a36Sopenharmony_ci	int error = may_delete(idmap, dir, dentry, 1);
417962306a36Sopenharmony_ci
418062306a36Sopenharmony_ci	if (error)
418162306a36Sopenharmony_ci		return error;
418262306a36Sopenharmony_ci
418362306a36Sopenharmony_ci	if (!dir->i_op->rmdir)
418462306a36Sopenharmony_ci		return -EPERM;
418562306a36Sopenharmony_ci
418662306a36Sopenharmony_ci	dget(dentry);
418762306a36Sopenharmony_ci	inode_lock(dentry->d_inode);
418862306a36Sopenharmony_ci
418962306a36Sopenharmony_ci	error = -EBUSY;
419062306a36Sopenharmony_ci	if (is_local_mountpoint(dentry) ||
419162306a36Sopenharmony_ci	    (dentry->d_inode->i_flags & S_KERNEL_FILE))
419262306a36Sopenharmony_ci		goto out;
419362306a36Sopenharmony_ci
419462306a36Sopenharmony_ci	error = security_inode_rmdir(dir, dentry);
419562306a36Sopenharmony_ci	if (error)
419662306a36Sopenharmony_ci		goto out;
419762306a36Sopenharmony_ci
419862306a36Sopenharmony_ci	error = dir->i_op->rmdir(dir, dentry);
419962306a36Sopenharmony_ci	if (error)
420062306a36Sopenharmony_ci		goto out;
420162306a36Sopenharmony_ci
420262306a36Sopenharmony_ci	shrink_dcache_parent(dentry);
420362306a36Sopenharmony_ci	dentry->d_inode->i_flags |= S_DEAD;
420462306a36Sopenharmony_ci	dont_mount(dentry);
420562306a36Sopenharmony_ci	detach_mounts(dentry);
420662306a36Sopenharmony_ci
420762306a36Sopenharmony_ciout:
420862306a36Sopenharmony_ci	inode_unlock(dentry->d_inode);
420962306a36Sopenharmony_ci	dput(dentry);
421062306a36Sopenharmony_ci	if (!error)
421162306a36Sopenharmony_ci		d_delete_notify(dir, dentry);
421262306a36Sopenharmony_ci	return error;
421362306a36Sopenharmony_ci}
421462306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_rmdir);
421562306a36Sopenharmony_ci
421662306a36Sopenharmony_ciint do_rmdir(int dfd, struct filename *name)
421762306a36Sopenharmony_ci{
421862306a36Sopenharmony_ci	int error;
421962306a36Sopenharmony_ci	struct dentry *dentry;
422062306a36Sopenharmony_ci	struct path path;
422162306a36Sopenharmony_ci	struct qstr last;
422262306a36Sopenharmony_ci	int type;
422362306a36Sopenharmony_ci	unsigned int lookup_flags = 0;
422462306a36Sopenharmony_ciretry:
422562306a36Sopenharmony_ci	error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
422662306a36Sopenharmony_ci	if (error)
422762306a36Sopenharmony_ci		goto exit1;
422862306a36Sopenharmony_ci
422962306a36Sopenharmony_ci	switch (type) {
423062306a36Sopenharmony_ci	case LAST_DOTDOT:
423162306a36Sopenharmony_ci		error = -ENOTEMPTY;
423262306a36Sopenharmony_ci		goto exit2;
423362306a36Sopenharmony_ci	case LAST_DOT:
423462306a36Sopenharmony_ci		error = -EINVAL;
423562306a36Sopenharmony_ci		goto exit2;
423662306a36Sopenharmony_ci	case LAST_ROOT:
423762306a36Sopenharmony_ci		error = -EBUSY;
423862306a36Sopenharmony_ci		goto exit2;
423962306a36Sopenharmony_ci	}
424062306a36Sopenharmony_ci
424162306a36Sopenharmony_ci	error = mnt_want_write(path.mnt);
424262306a36Sopenharmony_ci	if (error)
424362306a36Sopenharmony_ci		goto exit2;
424462306a36Sopenharmony_ci
424562306a36Sopenharmony_ci	inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
424662306a36Sopenharmony_ci	dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags);
424762306a36Sopenharmony_ci	error = PTR_ERR(dentry);
424862306a36Sopenharmony_ci	if (IS_ERR(dentry))
424962306a36Sopenharmony_ci		goto exit3;
425062306a36Sopenharmony_ci	if (!dentry->d_inode) {
425162306a36Sopenharmony_ci		error = -ENOENT;
425262306a36Sopenharmony_ci		goto exit4;
425362306a36Sopenharmony_ci	}
425462306a36Sopenharmony_ci	error = security_path_rmdir(&path, dentry);
425562306a36Sopenharmony_ci	if (error)
425662306a36Sopenharmony_ci		goto exit4;
425762306a36Sopenharmony_ci	error = vfs_rmdir(mnt_idmap(path.mnt), path.dentry->d_inode, dentry);
425862306a36Sopenharmony_ciexit4:
425962306a36Sopenharmony_ci	dput(dentry);
426062306a36Sopenharmony_ciexit3:
426162306a36Sopenharmony_ci	inode_unlock(path.dentry->d_inode);
426262306a36Sopenharmony_ci	mnt_drop_write(path.mnt);
426362306a36Sopenharmony_ciexit2:
426462306a36Sopenharmony_ci	path_put(&path);
426562306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags)) {
426662306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
426762306a36Sopenharmony_ci		goto retry;
426862306a36Sopenharmony_ci	}
426962306a36Sopenharmony_ciexit1:
427062306a36Sopenharmony_ci	putname(name);
427162306a36Sopenharmony_ci	return error;
427262306a36Sopenharmony_ci}
427362306a36Sopenharmony_ci
427462306a36Sopenharmony_ciSYSCALL_DEFINE1(rmdir, const char __user *, pathname)
427562306a36Sopenharmony_ci{
427662306a36Sopenharmony_ci	return do_rmdir(AT_FDCWD, getname(pathname));
427762306a36Sopenharmony_ci}
427862306a36Sopenharmony_ci
427962306a36Sopenharmony_ci/**
428062306a36Sopenharmony_ci * vfs_unlink - unlink a filesystem object
428162306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
428262306a36Sopenharmony_ci * @dir:	parent directory
428362306a36Sopenharmony_ci * @dentry:	victim
428462306a36Sopenharmony_ci * @delegated_inode: returns victim inode, if the inode is delegated.
428562306a36Sopenharmony_ci *
428662306a36Sopenharmony_ci * The caller must hold dir->i_mutex.
428762306a36Sopenharmony_ci *
428862306a36Sopenharmony_ci * If vfs_unlink discovers a delegation, it will return -EWOULDBLOCK and
428962306a36Sopenharmony_ci * return a reference to the inode in delegated_inode.  The caller
429062306a36Sopenharmony_ci * should then break the delegation on that inode and retry.  Because
429162306a36Sopenharmony_ci * breaking a delegation may take a long time, the caller should drop
429262306a36Sopenharmony_ci * dir->i_mutex before doing so.
429362306a36Sopenharmony_ci *
429462306a36Sopenharmony_ci * Alternatively, a caller may pass NULL for delegated_inode.  This may
429562306a36Sopenharmony_ci * be appropriate for callers that expect the underlying filesystem not
429662306a36Sopenharmony_ci * to be NFS exported.
429762306a36Sopenharmony_ci *
429862306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
429962306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
430062306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
430162306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
430262306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
430362306a36Sopenharmony_ci */
430462306a36Sopenharmony_ciint vfs_unlink(struct mnt_idmap *idmap, struct inode *dir,
430562306a36Sopenharmony_ci	       struct dentry *dentry, struct inode **delegated_inode)
430662306a36Sopenharmony_ci{
430762306a36Sopenharmony_ci	struct inode *target = dentry->d_inode;
430862306a36Sopenharmony_ci	int error = may_delete(idmap, dir, dentry, 0);
430962306a36Sopenharmony_ci
431062306a36Sopenharmony_ci	if (error)
431162306a36Sopenharmony_ci		return error;
431262306a36Sopenharmony_ci
431362306a36Sopenharmony_ci	if (!dir->i_op->unlink)
431462306a36Sopenharmony_ci		return -EPERM;
431562306a36Sopenharmony_ci
431662306a36Sopenharmony_ci	inode_lock(target);
431762306a36Sopenharmony_ci	if (IS_SWAPFILE(target))
431862306a36Sopenharmony_ci		error = -EPERM;
431962306a36Sopenharmony_ci	else if (is_local_mountpoint(dentry))
432062306a36Sopenharmony_ci		error = -EBUSY;
432162306a36Sopenharmony_ci	else {
432262306a36Sopenharmony_ci		error = security_inode_unlink(dir, dentry);
432362306a36Sopenharmony_ci		if (!error) {
432462306a36Sopenharmony_ci			error = try_break_deleg(target, delegated_inode);
432562306a36Sopenharmony_ci			if (error)
432662306a36Sopenharmony_ci				goto out;
432762306a36Sopenharmony_ci			error = dir->i_op->unlink(dir, dentry);
432862306a36Sopenharmony_ci			if (!error) {
432962306a36Sopenharmony_ci				dont_mount(dentry);
433062306a36Sopenharmony_ci				detach_mounts(dentry);
433162306a36Sopenharmony_ci			}
433262306a36Sopenharmony_ci		}
433362306a36Sopenharmony_ci	}
433462306a36Sopenharmony_ciout:
433562306a36Sopenharmony_ci	inode_unlock(target);
433662306a36Sopenharmony_ci
433762306a36Sopenharmony_ci	/* We don't d_delete() NFS sillyrenamed files--they still exist. */
433862306a36Sopenharmony_ci	if (!error && dentry->d_flags & DCACHE_NFSFS_RENAMED) {
433962306a36Sopenharmony_ci		fsnotify_unlink(dir, dentry);
434062306a36Sopenharmony_ci	} else if (!error) {
434162306a36Sopenharmony_ci		fsnotify_link_count(target);
434262306a36Sopenharmony_ci		d_delete_notify(dir, dentry);
434362306a36Sopenharmony_ci	}
434462306a36Sopenharmony_ci
434562306a36Sopenharmony_ci	return error;
434662306a36Sopenharmony_ci}
434762306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_unlink);
434862306a36Sopenharmony_ci
434962306a36Sopenharmony_ci/*
435062306a36Sopenharmony_ci * Make sure that the actual truncation of the file will occur outside its
435162306a36Sopenharmony_ci * directory's i_mutex.  Truncate can take a long time if there is a lot of
435262306a36Sopenharmony_ci * writeout happening, and we don't want to prevent access to the directory
435362306a36Sopenharmony_ci * while waiting on the I/O.
435462306a36Sopenharmony_ci */
435562306a36Sopenharmony_ciint do_unlinkat(int dfd, struct filename *name)
435662306a36Sopenharmony_ci{
435762306a36Sopenharmony_ci	int error;
435862306a36Sopenharmony_ci	struct dentry *dentry;
435962306a36Sopenharmony_ci	struct path path;
436062306a36Sopenharmony_ci	struct qstr last;
436162306a36Sopenharmony_ci	int type;
436262306a36Sopenharmony_ci	struct inode *inode = NULL;
436362306a36Sopenharmony_ci	struct inode *delegated_inode = NULL;
436462306a36Sopenharmony_ci	unsigned int lookup_flags = 0;
436562306a36Sopenharmony_ciretry:
436662306a36Sopenharmony_ci	error = filename_parentat(dfd, name, lookup_flags, &path, &last, &type);
436762306a36Sopenharmony_ci	if (error)
436862306a36Sopenharmony_ci		goto exit1;
436962306a36Sopenharmony_ci
437062306a36Sopenharmony_ci	error = -EISDIR;
437162306a36Sopenharmony_ci	if (type != LAST_NORM)
437262306a36Sopenharmony_ci		goto exit2;
437362306a36Sopenharmony_ci
437462306a36Sopenharmony_ci	error = mnt_want_write(path.mnt);
437562306a36Sopenharmony_ci	if (error)
437662306a36Sopenharmony_ci		goto exit2;
437762306a36Sopenharmony_ciretry_deleg:
437862306a36Sopenharmony_ci	inode_lock_nested(path.dentry->d_inode, I_MUTEX_PARENT);
437962306a36Sopenharmony_ci	dentry = lookup_one_qstr_excl(&last, path.dentry, lookup_flags);
438062306a36Sopenharmony_ci	error = PTR_ERR(dentry);
438162306a36Sopenharmony_ci	if (!IS_ERR(dentry)) {
438262306a36Sopenharmony_ci
438362306a36Sopenharmony_ci		/* Why not before? Because we want correct error value */
438462306a36Sopenharmony_ci		if (last.name[last.len])
438562306a36Sopenharmony_ci			goto slashes;
438662306a36Sopenharmony_ci		inode = dentry->d_inode;
438762306a36Sopenharmony_ci		if (d_is_negative(dentry))
438862306a36Sopenharmony_ci			goto slashes;
438962306a36Sopenharmony_ci		ihold(inode);
439062306a36Sopenharmony_ci		error = security_path_unlink(&path, dentry);
439162306a36Sopenharmony_ci		if (error)
439262306a36Sopenharmony_ci			goto exit3;
439362306a36Sopenharmony_ci		error = vfs_unlink(mnt_idmap(path.mnt), path.dentry->d_inode,
439462306a36Sopenharmony_ci				   dentry, &delegated_inode);
439562306a36Sopenharmony_ciexit3:
439662306a36Sopenharmony_ci		dput(dentry);
439762306a36Sopenharmony_ci	}
439862306a36Sopenharmony_ci	inode_unlock(path.dentry->d_inode);
439962306a36Sopenharmony_ci	if (inode)
440062306a36Sopenharmony_ci		iput(inode);	/* truncate the inode here */
440162306a36Sopenharmony_ci	inode = NULL;
440262306a36Sopenharmony_ci	if (delegated_inode) {
440362306a36Sopenharmony_ci		error = break_deleg_wait(&delegated_inode);
440462306a36Sopenharmony_ci		if (!error)
440562306a36Sopenharmony_ci			goto retry_deleg;
440662306a36Sopenharmony_ci	}
440762306a36Sopenharmony_ci	mnt_drop_write(path.mnt);
440862306a36Sopenharmony_ciexit2:
440962306a36Sopenharmony_ci	path_put(&path);
441062306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags)) {
441162306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
441262306a36Sopenharmony_ci		inode = NULL;
441362306a36Sopenharmony_ci		goto retry;
441462306a36Sopenharmony_ci	}
441562306a36Sopenharmony_ciexit1:
441662306a36Sopenharmony_ci	putname(name);
441762306a36Sopenharmony_ci	return error;
441862306a36Sopenharmony_ci
441962306a36Sopenharmony_cislashes:
442062306a36Sopenharmony_ci	if (d_is_negative(dentry))
442162306a36Sopenharmony_ci		error = -ENOENT;
442262306a36Sopenharmony_ci	else if (d_is_dir(dentry))
442362306a36Sopenharmony_ci		error = -EISDIR;
442462306a36Sopenharmony_ci	else
442562306a36Sopenharmony_ci		error = -ENOTDIR;
442662306a36Sopenharmony_ci	goto exit3;
442762306a36Sopenharmony_ci}
442862306a36Sopenharmony_ci
442962306a36Sopenharmony_ciSYSCALL_DEFINE3(unlinkat, int, dfd, const char __user *, pathname, int, flag)
443062306a36Sopenharmony_ci{
443162306a36Sopenharmony_ci	if ((flag & ~AT_REMOVEDIR) != 0)
443262306a36Sopenharmony_ci		return -EINVAL;
443362306a36Sopenharmony_ci
443462306a36Sopenharmony_ci	if (flag & AT_REMOVEDIR)
443562306a36Sopenharmony_ci		return do_rmdir(dfd, getname(pathname));
443662306a36Sopenharmony_ci	return do_unlinkat(dfd, getname(pathname));
443762306a36Sopenharmony_ci}
443862306a36Sopenharmony_ci
443962306a36Sopenharmony_ciSYSCALL_DEFINE1(unlink, const char __user *, pathname)
444062306a36Sopenharmony_ci{
444162306a36Sopenharmony_ci	return do_unlinkat(AT_FDCWD, getname(pathname));
444262306a36Sopenharmony_ci}
444362306a36Sopenharmony_ci
444462306a36Sopenharmony_ci/**
444562306a36Sopenharmony_ci * vfs_symlink - create symlink
444662306a36Sopenharmony_ci * @idmap:	idmap of the mount the inode was found from
444762306a36Sopenharmony_ci * @dir:	inode of @dentry
444862306a36Sopenharmony_ci * @dentry:	pointer to dentry of the base directory
444962306a36Sopenharmony_ci * @oldname:	name of the file to link to
445062306a36Sopenharmony_ci *
445162306a36Sopenharmony_ci * Create a symlink.
445262306a36Sopenharmony_ci *
445362306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
445462306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
445562306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
445662306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
445762306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
445862306a36Sopenharmony_ci */
445962306a36Sopenharmony_ciint vfs_symlink(struct mnt_idmap *idmap, struct inode *dir,
446062306a36Sopenharmony_ci		struct dentry *dentry, const char *oldname)
446162306a36Sopenharmony_ci{
446262306a36Sopenharmony_ci	int error;
446362306a36Sopenharmony_ci
446462306a36Sopenharmony_ci	error = may_create(idmap, dir, dentry);
446562306a36Sopenharmony_ci	if (error)
446662306a36Sopenharmony_ci		return error;
446762306a36Sopenharmony_ci
446862306a36Sopenharmony_ci	if (!dir->i_op->symlink)
446962306a36Sopenharmony_ci		return -EPERM;
447062306a36Sopenharmony_ci
447162306a36Sopenharmony_ci	error = security_inode_symlink(dir, dentry, oldname);
447262306a36Sopenharmony_ci	if (error)
447362306a36Sopenharmony_ci		return error;
447462306a36Sopenharmony_ci
447562306a36Sopenharmony_ci	error = dir->i_op->symlink(idmap, dir, dentry, oldname);
447662306a36Sopenharmony_ci	if (!error)
447762306a36Sopenharmony_ci		fsnotify_create(dir, dentry);
447862306a36Sopenharmony_ci	return error;
447962306a36Sopenharmony_ci}
448062306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_symlink);
448162306a36Sopenharmony_ci
448262306a36Sopenharmony_ciint do_symlinkat(struct filename *from, int newdfd, struct filename *to)
448362306a36Sopenharmony_ci{
448462306a36Sopenharmony_ci	int error;
448562306a36Sopenharmony_ci	struct dentry *dentry;
448662306a36Sopenharmony_ci	struct path path;
448762306a36Sopenharmony_ci	unsigned int lookup_flags = 0;
448862306a36Sopenharmony_ci
448962306a36Sopenharmony_ci	if (IS_ERR(from)) {
449062306a36Sopenharmony_ci		error = PTR_ERR(from);
449162306a36Sopenharmony_ci		goto out_putnames;
449262306a36Sopenharmony_ci	}
449362306a36Sopenharmony_ciretry:
449462306a36Sopenharmony_ci	dentry = filename_create(newdfd, to, &path, lookup_flags);
449562306a36Sopenharmony_ci	error = PTR_ERR(dentry);
449662306a36Sopenharmony_ci	if (IS_ERR(dentry))
449762306a36Sopenharmony_ci		goto out_putnames;
449862306a36Sopenharmony_ci
449962306a36Sopenharmony_ci	error = security_path_symlink(&path, dentry, from->name);
450062306a36Sopenharmony_ci	if (!error)
450162306a36Sopenharmony_ci		error = vfs_symlink(mnt_idmap(path.mnt), path.dentry->d_inode,
450262306a36Sopenharmony_ci				    dentry, from->name);
450362306a36Sopenharmony_ci	done_path_create(&path, dentry);
450462306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags)) {
450562306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
450662306a36Sopenharmony_ci		goto retry;
450762306a36Sopenharmony_ci	}
450862306a36Sopenharmony_ciout_putnames:
450962306a36Sopenharmony_ci	putname(to);
451062306a36Sopenharmony_ci	putname(from);
451162306a36Sopenharmony_ci	return error;
451262306a36Sopenharmony_ci}
451362306a36Sopenharmony_ci
451462306a36Sopenharmony_ciSYSCALL_DEFINE3(symlinkat, const char __user *, oldname,
451562306a36Sopenharmony_ci		int, newdfd, const char __user *, newname)
451662306a36Sopenharmony_ci{
451762306a36Sopenharmony_ci	return do_symlinkat(getname(oldname), newdfd, getname(newname));
451862306a36Sopenharmony_ci}
451962306a36Sopenharmony_ci
452062306a36Sopenharmony_ciSYSCALL_DEFINE2(symlink, const char __user *, oldname, const char __user *, newname)
452162306a36Sopenharmony_ci{
452262306a36Sopenharmony_ci	return do_symlinkat(getname(oldname), AT_FDCWD, getname(newname));
452362306a36Sopenharmony_ci}
452462306a36Sopenharmony_ci
452562306a36Sopenharmony_ci/**
452662306a36Sopenharmony_ci * vfs_link - create a new link
452762306a36Sopenharmony_ci * @old_dentry:	object to be linked
452862306a36Sopenharmony_ci * @idmap:	idmap of the mount
452962306a36Sopenharmony_ci * @dir:	new parent
453062306a36Sopenharmony_ci * @new_dentry:	where to create the new link
453162306a36Sopenharmony_ci * @delegated_inode: returns inode needing a delegation break
453262306a36Sopenharmony_ci *
453362306a36Sopenharmony_ci * The caller must hold dir->i_mutex
453462306a36Sopenharmony_ci *
453562306a36Sopenharmony_ci * If vfs_link discovers a delegation on the to-be-linked file in need
453662306a36Sopenharmony_ci * of breaking, it will return -EWOULDBLOCK and return a reference to the
453762306a36Sopenharmony_ci * inode in delegated_inode.  The caller should then break the delegation
453862306a36Sopenharmony_ci * and retry.  Because breaking a delegation may take a long time, the
453962306a36Sopenharmony_ci * caller should drop the i_mutex before doing so.
454062306a36Sopenharmony_ci *
454162306a36Sopenharmony_ci * Alternatively, a caller may pass NULL for delegated_inode.  This may
454262306a36Sopenharmony_ci * be appropriate for callers that expect the underlying filesystem not
454362306a36Sopenharmony_ci * to be NFS exported.
454462306a36Sopenharmony_ci *
454562306a36Sopenharmony_ci * If the inode has been found through an idmapped mount the idmap of
454662306a36Sopenharmony_ci * the vfsmount must be passed through @idmap. This function will then take
454762306a36Sopenharmony_ci * care to map the inode according to @idmap before checking permissions.
454862306a36Sopenharmony_ci * On non-idmapped mounts or if permission checking is to be performed on the
454962306a36Sopenharmony_ci * raw inode simply passs @nop_mnt_idmap.
455062306a36Sopenharmony_ci */
455162306a36Sopenharmony_ciint vfs_link(struct dentry *old_dentry, struct mnt_idmap *idmap,
455262306a36Sopenharmony_ci	     struct inode *dir, struct dentry *new_dentry,
455362306a36Sopenharmony_ci	     struct inode **delegated_inode)
455462306a36Sopenharmony_ci{
455562306a36Sopenharmony_ci	struct inode *inode = old_dentry->d_inode;
455662306a36Sopenharmony_ci	unsigned max_links = dir->i_sb->s_max_links;
455762306a36Sopenharmony_ci	int error;
455862306a36Sopenharmony_ci
455962306a36Sopenharmony_ci	if (!inode)
456062306a36Sopenharmony_ci		return -ENOENT;
456162306a36Sopenharmony_ci
456262306a36Sopenharmony_ci	error = may_create(idmap, dir, new_dentry);
456362306a36Sopenharmony_ci	if (error)
456462306a36Sopenharmony_ci		return error;
456562306a36Sopenharmony_ci
456662306a36Sopenharmony_ci	if (dir->i_sb != inode->i_sb)
456762306a36Sopenharmony_ci		return -EXDEV;
456862306a36Sopenharmony_ci
456962306a36Sopenharmony_ci	/*
457062306a36Sopenharmony_ci	 * A link to an append-only or immutable file cannot be created.
457162306a36Sopenharmony_ci	 */
457262306a36Sopenharmony_ci	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
457362306a36Sopenharmony_ci		return -EPERM;
457462306a36Sopenharmony_ci	/*
457562306a36Sopenharmony_ci	 * Updating the link count will likely cause i_uid and i_gid to
457662306a36Sopenharmony_ci	 * be writen back improperly if their true value is unknown to
457762306a36Sopenharmony_ci	 * the vfs.
457862306a36Sopenharmony_ci	 */
457962306a36Sopenharmony_ci	if (HAS_UNMAPPED_ID(idmap, inode))
458062306a36Sopenharmony_ci		return -EPERM;
458162306a36Sopenharmony_ci	if (!dir->i_op->link)
458262306a36Sopenharmony_ci		return -EPERM;
458362306a36Sopenharmony_ci	if (S_ISDIR(inode->i_mode))
458462306a36Sopenharmony_ci		return -EPERM;
458562306a36Sopenharmony_ci
458662306a36Sopenharmony_ci	error = security_inode_link(old_dentry, dir, new_dentry);
458762306a36Sopenharmony_ci	if (error)
458862306a36Sopenharmony_ci		return error;
458962306a36Sopenharmony_ci
459062306a36Sopenharmony_ci	inode_lock(inode);
459162306a36Sopenharmony_ci	/* Make sure we don't allow creating hardlink to an unlinked file */
459262306a36Sopenharmony_ci	if (inode->i_nlink == 0 && !(inode->i_state & I_LINKABLE))
459362306a36Sopenharmony_ci		error =  -ENOENT;
459462306a36Sopenharmony_ci	else if (max_links && inode->i_nlink >= max_links)
459562306a36Sopenharmony_ci		error = -EMLINK;
459662306a36Sopenharmony_ci	else {
459762306a36Sopenharmony_ci		error = try_break_deleg(inode, delegated_inode);
459862306a36Sopenharmony_ci		if (!error)
459962306a36Sopenharmony_ci			error = dir->i_op->link(old_dentry, dir, new_dentry);
460062306a36Sopenharmony_ci	}
460162306a36Sopenharmony_ci
460262306a36Sopenharmony_ci	if (!error && (inode->i_state & I_LINKABLE)) {
460362306a36Sopenharmony_ci		spin_lock(&inode->i_lock);
460462306a36Sopenharmony_ci		inode->i_state &= ~I_LINKABLE;
460562306a36Sopenharmony_ci		spin_unlock(&inode->i_lock);
460662306a36Sopenharmony_ci	}
460762306a36Sopenharmony_ci	inode_unlock(inode);
460862306a36Sopenharmony_ci	if (!error)
460962306a36Sopenharmony_ci		fsnotify_link(dir, inode, new_dentry);
461062306a36Sopenharmony_ci	return error;
461162306a36Sopenharmony_ci}
461262306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_link);
461362306a36Sopenharmony_ci
461462306a36Sopenharmony_ci/*
461562306a36Sopenharmony_ci * Hardlinks are often used in delicate situations.  We avoid
461662306a36Sopenharmony_ci * security-related surprises by not following symlinks on the
461762306a36Sopenharmony_ci * newname.  --KAB
461862306a36Sopenharmony_ci *
461962306a36Sopenharmony_ci * We don't follow them on the oldname either to be compatible
462062306a36Sopenharmony_ci * with linux 2.0, and to avoid hard-linking to directories
462162306a36Sopenharmony_ci * and other special files.  --ADM
462262306a36Sopenharmony_ci */
462362306a36Sopenharmony_ciint do_linkat(int olddfd, struct filename *old, int newdfd,
462462306a36Sopenharmony_ci	      struct filename *new, int flags)
462562306a36Sopenharmony_ci{
462662306a36Sopenharmony_ci	struct mnt_idmap *idmap;
462762306a36Sopenharmony_ci	struct dentry *new_dentry;
462862306a36Sopenharmony_ci	struct path old_path, new_path;
462962306a36Sopenharmony_ci	struct inode *delegated_inode = NULL;
463062306a36Sopenharmony_ci	int how = 0;
463162306a36Sopenharmony_ci	int error;
463262306a36Sopenharmony_ci
463362306a36Sopenharmony_ci	if ((flags & ~(AT_SYMLINK_FOLLOW | AT_EMPTY_PATH)) != 0) {
463462306a36Sopenharmony_ci		error = -EINVAL;
463562306a36Sopenharmony_ci		goto out_putnames;
463662306a36Sopenharmony_ci	}
463762306a36Sopenharmony_ci	/*
463862306a36Sopenharmony_ci	 * To use null names we require CAP_DAC_READ_SEARCH
463962306a36Sopenharmony_ci	 * This ensures that not everyone will be able to create
464062306a36Sopenharmony_ci	 * handlink using the passed filedescriptor.
464162306a36Sopenharmony_ci	 */
464262306a36Sopenharmony_ci	if (flags & AT_EMPTY_PATH && !capable(CAP_DAC_READ_SEARCH)) {
464362306a36Sopenharmony_ci		error = -ENOENT;
464462306a36Sopenharmony_ci		goto out_putnames;
464562306a36Sopenharmony_ci	}
464662306a36Sopenharmony_ci
464762306a36Sopenharmony_ci	if (flags & AT_SYMLINK_FOLLOW)
464862306a36Sopenharmony_ci		how |= LOOKUP_FOLLOW;
464962306a36Sopenharmony_ciretry:
465062306a36Sopenharmony_ci	error = filename_lookup(olddfd, old, how, &old_path, NULL);
465162306a36Sopenharmony_ci	if (error)
465262306a36Sopenharmony_ci		goto out_putnames;
465362306a36Sopenharmony_ci
465462306a36Sopenharmony_ci	new_dentry = filename_create(newdfd, new, &new_path,
465562306a36Sopenharmony_ci					(how & LOOKUP_REVAL));
465662306a36Sopenharmony_ci	error = PTR_ERR(new_dentry);
465762306a36Sopenharmony_ci	if (IS_ERR(new_dentry))
465862306a36Sopenharmony_ci		goto out_putpath;
465962306a36Sopenharmony_ci
466062306a36Sopenharmony_ci	error = -EXDEV;
466162306a36Sopenharmony_ci	if (old_path.mnt != new_path.mnt)
466262306a36Sopenharmony_ci		goto out_dput;
466362306a36Sopenharmony_ci	idmap = mnt_idmap(new_path.mnt);
466462306a36Sopenharmony_ci	error = may_linkat(idmap, &old_path);
466562306a36Sopenharmony_ci	if (unlikely(error))
466662306a36Sopenharmony_ci		goto out_dput;
466762306a36Sopenharmony_ci	error = security_path_link(old_path.dentry, &new_path, new_dentry);
466862306a36Sopenharmony_ci	if (error)
466962306a36Sopenharmony_ci		goto out_dput;
467062306a36Sopenharmony_ci	error = vfs_link(old_path.dentry, idmap, new_path.dentry->d_inode,
467162306a36Sopenharmony_ci			 new_dentry, &delegated_inode);
467262306a36Sopenharmony_ciout_dput:
467362306a36Sopenharmony_ci	done_path_create(&new_path, new_dentry);
467462306a36Sopenharmony_ci	if (delegated_inode) {
467562306a36Sopenharmony_ci		error = break_deleg_wait(&delegated_inode);
467662306a36Sopenharmony_ci		if (!error) {
467762306a36Sopenharmony_ci			path_put(&old_path);
467862306a36Sopenharmony_ci			goto retry;
467962306a36Sopenharmony_ci		}
468062306a36Sopenharmony_ci	}
468162306a36Sopenharmony_ci	if (retry_estale(error, how)) {
468262306a36Sopenharmony_ci		path_put(&old_path);
468362306a36Sopenharmony_ci		how |= LOOKUP_REVAL;
468462306a36Sopenharmony_ci		goto retry;
468562306a36Sopenharmony_ci	}
468662306a36Sopenharmony_ciout_putpath:
468762306a36Sopenharmony_ci	path_put(&old_path);
468862306a36Sopenharmony_ciout_putnames:
468962306a36Sopenharmony_ci	putname(old);
469062306a36Sopenharmony_ci	putname(new);
469162306a36Sopenharmony_ci
469262306a36Sopenharmony_ci	return error;
469362306a36Sopenharmony_ci}
469462306a36Sopenharmony_ci
469562306a36Sopenharmony_ciSYSCALL_DEFINE5(linkat, int, olddfd, const char __user *, oldname,
469662306a36Sopenharmony_ci		int, newdfd, const char __user *, newname, int, flags)
469762306a36Sopenharmony_ci{
469862306a36Sopenharmony_ci	return do_linkat(olddfd, getname_uflags(oldname, flags),
469962306a36Sopenharmony_ci		newdfd, getname(newname), flags);
470062306a36Sopenharmony_ci}
470162306a36Sopenharmony_ci
470262306a36Sopenharmony_ciSYSCALL_DEFINE2(link, const char __user *, oldname, const char __user *, newname)
470362306a36Sopenharmony_ci{
470462306a36Sopenharmony_ci	return do_linkat(AT_FDCWD, getname(oldname), AT_FDCWD, getname(newname), 0);
470562306a36Sopenharmony_ci}
470662306a36Sopenharmony_ci
470762306a36Sopenharmony_ci/**
470862306a36Sopenharmony_ci * vfs_rename - rename a filesystem object
470962306a36Sopenharmony_ci * @rd:		pointer to &struct renamedata info
471062306a36Sopenharmony_ci *
471162306a36Sopenharmony_ci * The caller must hold multiple mutexes--see lock_rename()).
471262306a36Sopenharmony_ci *
471362306a36Sopenharmony_ci * If vfs_rename discovers a delegation in need of breaking at either
471462306a36Sopenharmony_ci * the source or destination, it will return -EWOULDBLOCK and return a
471562306a36Sopenharmony_ci * reference to the inode in delegated_inode.  The caller should then
471662306a36Sopenharmony_ci * break the delegation and retry.  Because breaking a delegation may
471762306a36Sopenharmony_ci * take a long time, the caller should drop all locks before doing
471862306a36Sopenharmony_ci * so.
471962306a36Sopenharmony_ci *
472062306a36Sopenharmony_ci * Alternatively, a caller may pass NULL for delegated_inode.  This may
472162306a36Sopenharmony_ci * be appropriate for callers that expect the underlying filesystem not
472262306a36Sopenharmony_ci * to be NFS exported.
472362306a36Sopenharmony_ci *
472462306a36Sopenharmony_ci * The worst of all namespace operations - renaming directory. "Perverted"
472562306a36Sopenharmony_ci * doesn't even start to describe it. Somebody in UCB had a heck of a trip...
472662306a36Sopenharmony_ci * Problems:
472762306a36Sopenharmony_ci *
472862306a36Sopenharmony_ci *	a) we can get into loop creation.
472962306a36Sopenharmony_ci *	b) race potential - two innocent renames can create a loop together.
473062306a36Sopenharmony_ci *	   That's where 4.4BSD screws up. Current fix: serialization on
473162306a36Sopenharmony_ci *	   sb->s_vfs_rename_mutex. We might be more accurate, but that's another
473262306a36Sopenharmony_ci *	   story.
473362306a36Sopenharmony_ci *	c) we may have to lock up to _four_ objects - parents and victim (if it exists),
473462306a36Sopenharmony_ci *	   and source (if it's a non-directory or a subdirectory that moves to
473562306a36Sopenharmony_ci *	   different parent).
473662306a36Sopenharmony_ci *	   And that - after we got ->i_mutex on parents (until then we don't know
473762306a36Sopenharmony_ci *	   whether the target exists).  Solution: try to be smart with locking
473862306a36Sopenharmony_ci *	   order for inodes.  We rely on the fact that tree topology may change
473962306a36Sopenharmony_ci *	   only under ->s_vfs_rename_mutex _and_ that parent of the object we
474062306a36Sopenharmony_ci *	   move will be locked.  Thus we can rank directories by the tree
474162306a36Sopenharmony_ci *	   (ancestors first) and rank all non-directories after them.
474262306a36Sopenharmony_ci *	   That works since everybody except rename does "lock parent, lookup,
474362306a36Sopenharmony_ci *	   lock child" and rename is under ->s_vfs_rename_mutex.
474462306a36Sopenharmony_ci *	   HOWEVER, it relies on the assumption that any object with ->lookup()
474562306a36Sopenharmony_ci *	   has no more than 1 dentry.  If "hybrid" objects will ever appear,
474662306a36Sopenharmony_ci *	   we'd better make sure that there's no link(2) for them.
474762306a36Sopenharmony_ci *	d) conversion from fhandle to dentry may come in the wrong moment - when
474862306a36Sopenharmony_ci *	   we are removing the target. Solution: we will have to grab ->i_mutex
474962306a36Sopenharmony_ci *	   in the fhandle_to_dentry code. [FIXME - current nfsfh.c relies on
475062306a36Sopenharmony_ci *	   ->i_mutex on parents, which works but leads to some truly excessive
475162306a36Sopenharmony_ci *	   locking].
475262306a36Sopenharmony_ci */
475362306a36Sopenharmony_ciint vfs_rename(struct renamedata *rd)
475462306a36Sopenharmony_ci{
475562306a36Sopenharmony_ci	int error;
475662306a36Sopenharmony_ci	struct inode *old_dir = rd->old_dir, *new_dir = rd->new_dir;
475762306a36Sopenharmony_ci	struct dentry *old_dentry = rd->old_dentry;
475862306a36Sopenharmony_ci	struct dentry *new_dentry = rd->new_dentry;
475962306a36Sopenharmony_ci	struct inode **delegated_inode = rd->delegated_inode;
476062306a36Sopenharmony_ci	unsigned int flags = rd->flags;
476162306a36Sopenharmony_ci	bool is_dir = d_is_dir(old_dentry);
476262306a36Sopenharmony_ci	struct inode *source = old_dentry->d_inode;
476362306a36Sopenharmony_ci	struct inode *target = new_dentry->d_inode;
476462306a36Sopenharmony_ci	bool new_is_dir = false;
476562306a36Sopenharmony_ci	unsigned max_links = new_dir->i_sb->s_max_links;
476662306a36Sopenharmony_ci	struct name_snapshot old_name;
476762306a36Sopenharmony_ci	bool lock_old_subdir, lock_new_subdir;
476862306a36Sopenharmony_ci
476962306a36Sopenharmony_ci	if (source == target)
477062306a36Sopenharmony_ci		return 0;
477162306a36Sopenharmony_ci
477262306a36Sopenharmony_ci	error = may_delete(rd->old_mnt_idmap, old_dir, old_dentry, is_dir);
477362306a36Sopenharmony_ci	if (error)
477462306a36Sopenharmony_ci		return error;
477562306a36Sopenharmony_ci
477662306a36Sopenharmony_ci	if (!target) {
477762306a36Sopenharmony_ci		error = may_create(rd->new_mnt_idmap, new_dir, new_dentry);
477862306a36Sopenharmony_ci	} else {
477962306a36Sopenharmony_ci		new_is_dir = d_is_dir(new_dentry);
478062306a36Sopenharmony_ci
478162306a36Sopenharmony_ci		if (!(flags & RENAME_EXCHANGE))
478262306a36Sopenharmony_ci			error = may_delete(rd->new_mnt_idmap, new_dir,
478362306a36Sopenharmony_ci					   new_dentry, is_dir);
478462306a36Sopenharmony_ci		else
478562306a36Sopenharmony_ci			error = may_delete(rd->new_mnt_idmap, new_dir,
478662306a36Sopenharmony_ci					   new_dentry, new_is_dir);
478762306a36Sopenharmony_ci	}
478862306a36Sopenharmony_ci	if (error)
478962306a36Sopenharmony_ci		return error;
479062306a36Sopenharmony_ci
479162306a36Sopenharmony_ci	if (!old_dir->i_op->rename)
479262306a36Sopenharmony_ci		return -EPERM;
479362306a36Sopenharmony_ci
479462306a36Sopenharmony_ci	/*
479562306a36Sopenharmony_ci	 * If we are going to change the parent - check write permissions,
479662306a36Sopenharmony_ci	 * we'll need to flip '..'.
479762306a36Sopenharmony_ci	 */
479862306a36Sopenharmony_ci	if (new_dir != old_dir) {
479962306a36Sopenharmony_ci		if (is_dir) {
480062306a36Sopenharmony_ci			error = inode_permission(rd->old_mnt_idmap, source,
480162306a36Sopenharmony_ci						 MAY_WRITE);
480262306a36Sopenharmony_ci			if (error)
480362306a36Sopenharmony_ci				return error;
480462306a36Sopenharmony_ci		}
480562306a36Sopenharmony_ci		if ((flags & RENAME_EXCHANGE) && new_is_dir) {
480662306a36Sopenharmony_ci			error = inode_permission(rd->new_mnt_idmap, target,
480762306a36Sopenharmony_ci						 MAY_WRITE);
480862306a36Sopenharmony_ci			if (error)
480962306a36Sopenharmony_ci				return error;
481062306a36Sopenharmony_ci		}
481162306a36Sopenharmony_ci	}
481262306a36Sopenharmony_ci
481362306a36Sopenharmony_ci	error = security_inode_rename(old_dir, old_dentry, new_dir, new_dentry,
481462306a36Sopenharmony_ci				      flags);
481562306a36Sopenharmony_ci	if (error)
481662306a36Sopenharmony_ci		return error;
481762306a36Sopenharmony_ci
481862306a36Sopenharmony_ci	take_dentry_name_snapshot(&old_name, old_dentry);
481962306a36Sopenharmony_ci	dget(new_dentry);
482062306a36Sopenharmony_ci	/*
482162306a36Sopenharmony_ci	 * Lock children.
482262306a36Sopenharmony_ci	 * The source subdirectory needs to be locked on cross-directory
482362306a36Sopenharmony_ci	 * rename or cross-directory exchange since its parent changes.
482462306a36Sopenharmony_ci	 * The target subdirectory needs to be locked on cross-directory
482562306a36Sopenharmony_ci	 * exchange due to parent change and on any rename due to becoming
482662306a36Sopenharmony_ci	 * a victim.
482762306a36Sopenharmony_ci	 * Non-directories need locking in all cases (for NFS reasons);
482862306a36Sopenharmony_ci	 * they get locked after any subdirectories (in inode address order).
482962306a36Sopenharmony_ci	 *
483062306a36Sopenharmony_ci	 * NOTE: WE ONLY LOCK UNRELATED DIRECTORIES IN CROSS-DIRECTORY CASE.
483162306a36Sopenharmony_ci	 * NEVER, EVER DO THAT WITHOUT ->s_vfs_rename_mutex.
483262306a36Sopenharmony_ci	 */
483362306a36Sopenharmony_ci	lock_old_subdir = new_dir != old_dir;
483462306a36Sopenharmony_ci	lock_new_subdir = new_dir != old_dir || !(flags & RENAME_EXCHANGE);
483562306a36Sopenharmony_ci	if (is_dir) {
483662306a36Sopenharmony_ci		if (lock_old_subdir)
483762306a36Sopenharmony_ci			inode_lock_nested(source, I_MUTEX_CHILD);
483862306a36Sopenharmony_ci		if (target && (!new_is_dir || lock_new_subdir))
483962306a36Sopenharmony_ci			inode_lock(target);
484062306a36Sopenharmony_ci	} else if (new_is_dir) {
484162306a36Sopenharmony_ci		if (lock_new_subdir)
484262306a36Sopenharmony_ci			inode_lock_nested(target, I_MUTEX_CHILD);
484362306a36Sopenharmony_ci		inode_lock(source);
484462306a36Sopenharmony_ci	} else {
484562306a36Sopenharmony_ci		lock_two_nondirectories(source, target);
484662306a36Sopenharmony_ci	}
484762306a36Sopenharmony_ci
484862306a36Sopenharmony_ci	error = -EPERM;
484962306a36Sopenharmony_ci	if (IS_SWAPFILE(source) || (target && IS_SWAPFILE(target)))
485062306a36Sopenharmony_ci		goto out;
485162306a36Sopenharmony_ci
485262306a36Sopenharmony_ci	error = -EBUSY;
485362306a36Sopenharmony_ci	if (is_local_mountpoint(old_dentry) || is_local_mountpoint(new_dentry))
485462306a36Sopenharmony_ci		goto out;
485562306a36Sopenharmony_ci
485662306a36Sopenharmony_ci	if (max_links && new_dir != old_dir) {
485762306a36Sopenharmony_ci		error = -EMLINK;
485862306a36Sopenharmony_ci		if (is_dir && !new_is_dir && new_dir->i_nlink >= max_links)
485962306a36Sopenharmony_ci			goto out;
486062306a36Sopenharmony_ci		if ((flags & RENAME_EXCHANGE) && !is_dir && new_is_dir &&
486162306a36Sopenharmony_ci		    old_dir->i_nlink >= max_links)
486262306a36Sopenharmony_ci			goto out;
486362306a36Sopenharmony_ci	}
486462306a36Sopenharmony_ci	if (!is_dir) {
486562306a36Sopenharmony_ci		error = try_break_deleg(source, delegated_inode);
486662306a36Sopenharmony_ci		if (error)
486762306a36Sopenharmony_ci			goto out;
486862306a36Sopenharmony_ci	}
486962306a36Sopenharmony_ci	if (target && !new_is_dir) {
487062306a36Sopenharmony_ci		error = try_break_deleg(target, delegated_inode);
487162306a36Sopenharmony_ci		if (error)
487262306a36Sopenharmony_ci			goto out;
487362306a36Sopenharmony_ci	}
487462306a36Sopenharmony_ci	error = old_dir->i_op->rename(rd->new_mnt_idmap, old_dir, old_dentry,
487562306a36Sopenharmony_ci				      new_dir, new_dentry, flags);
487662306a36Sopenharmony_ci	if (error)
487762306a36Sopenharmony_ci		goto out;
487862306a36Sopenharmony_ci
487962306a36Sopenharmony_ci	if (!(flags & RENAME_EXCHANGE) && target) {
488062306a36Sopenharmony_ci		if (is_dir) {
488162306a36Sopenharmony_ci			shrink_dcache_parent(new_dentry);
488262306a36Sopenharmony_ci			target->i_flags |= S_DEAD;
488362306a36Sopenharmony_ci		}
488462306a36Sopenharmony_ci		dont_mount(new_dentry);
488562306a36Sopenharmony_ci		detach_mounts(new_dentry);
488662306a36Sopenharmony_ci	}
488762306a36Sopenharmony_ci	if (!(old_dir->i_sb->s_type->fs_flags & FS_RENAME_DOES_D_MOVE)) {
488862306a36Sopenharmony_ci		if (!(flags & RENAME_EXCHANGE))
488962306a36Sopenharmony_ci			d_move(old_dentry, new_dentry);
489062306a36Sopenharmony_ci		else
489162306a36Sopenharmony_ci			d_exchange(old_dentry, new_dentry);
489262306a36Sopenharmony_ci	}
489362306a36Sopenharmony_ciout:
489462306a36Sopenharmony_ci	if (!is_dir || lock_old_subdir)
489562306a36Sopenharmony_ci		inode_unlock(source);
489662306a36Sopenharmony_ci	if (target && (!new_is_dir || lock_new_subdir))
489762306a36Sopenharmony_ci		inode_unlock(target);
489862306a36Sopenharmony_ci	dput(new_dentry);
489962306a36Sopenharmony_ci	if (!error) {
490062306a36Sopenharmony_ci		fsnotify_move(old_dir, new_dir, &old_name.name, is_dir,
490162306a36Sopenharmony_ci			      !(flags & RENAME_EXCHANGE) ? target : NULL, old_dentry);
490262306a36Sopenharmony_ci		if (flags & RENAME_EXCHANGE) {
490362306a36Sopenharmony_ci			fsnotify_move(new_dir, old_dir, &old_dentry->d_name,
490462306a36Sopenharmony_ci				      new_is_dir, NULL, new_dentry);
490562306a36Sopenharmony_ci		}
490662306a36Sopenharmony_ci	}
490762306a36Sopenharmony_ci	release_dentry_name_snapshot(&old_name);
490862306a36Sopenharmony_ci
490962306a36Sopenharmony_ci	return error;
491062306a36Sopenharmony_ci}
491162306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_rename);
491262306a36Sopenharmony_ci
491362306a36Sopenharmony_ciint do_renameat2(int olddfd, struct filename *from, int newdfd,
491462306a36Sopenharmony_ci		 struct filename *to, unsigned int flags)
491562306a36Sopenharmony_ci{
491662306a36Sopenharmony_ci	struct renamedata rd;
491762306a36Sopenharmony_ci	struct dentry *old_dentry, *new_dentry;
491862306a36Sopenharmony_ci	struct dentry *trap;
491962306a36Sopenharmony_ci	struct path old_path, new_path;
492062306a36Sopenharmony_ci	struct qstr old_last, new_last;
492162306a36Sopenharmony_ci	int old_type, new_type;
492262306a36Sopenharmony_ci	struct inode *delegated_inode = NULL;
492362306a36Sopenharmony_ci	unsigned int lookup_flags = 0, target_flags = LOOKUP_RENAME_TARGET;
492462306a36Sopenharmony_ci	bool should_retry = false;
492562306a36Sopenharmony_ci	int error = -EINVAL;
492662306a36Sopenharmony_ci
492762306a36Sopenharmony_ci	if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE | RENAME_WHITEOUT))
492862306a36Sopenharmony_ci		goto put_names;
492962306a36Sopenharmony_ci
493062306a36Sopenharmony_ci	if ((flags & (RENAME_NOREPLACE | RENAME_WHITEOUT)) &&
493162306a36Sopenharmony_ci	    (flags & RENAME_EXCHANGE))
493262306a36Sopenharmony_ci		goto put_names;
493362306a36Sopenharmony_ci
493462306a36Sopenharmony_ci	if (flags & RENAME_EXCHANGE)
493562306a36Sopenharmony_ci		target_flags = 0;
493662306a36Sopenharmony_ci
493762306a36Sopenharmony_ciretry:
493862306a36Sopenharmony_ci	error = filename_parentat(olddfd, from, lookup_flags, &old_path,
493962306a36Sopenharmony_ci				  &old_last, &old_type);
494062306a36Sopenharmony_ci	if (error)
494162306a36Sopenharmony_ci		goto put_names;
494262306a36Sopenharmony_ci
494362306a36Sopenharmony_ci	error = filename_parentat(newdfd, to, lookup_flags, &new_path, &new_last,
494462306a36Sopenharmony_ci				  &new_type);
494562306a36Sopenharmony_ci	if (error)
494662306a36Sopenharmony_ci		goto exit1;
494762306a36Sopenharmony_ci
494862306a36Sopenharmony_ci	error = -EXDEV;
494962306a36Sopenharmony_ci	if (old_path.mnt != new_path.mnt)
495062306a36Sopenharmony_ci		goto exit2;
495162306a36Sopenharmony_ci
495262306a36Sopenharmony_ci	error = -EBUSY;
495362306a36Sopenharmony_ci	if (old_type != LAST_NORM)
495462306a36Sopenharmony_ci		goto exit2;
495562306a36Sopenharmony_ci
495662306a36Sopenharmony_ci	if (flags & RENAME_NOREPLACE)
495762306a36Sopenharmony_ci		error = -EEXIST;
495862306a36Sopenharmony_ci	if (new_type != LAST_NORM)
495962306a36Sopenharmony_ci		goto exit2;
496062306a36Sopenharmony_ci
496162306a36Sopenharmony_ci	error = mnt_want_write(old_path.mnt);
496262306a36Sopenharmony_ci	if (error)
496362306a36Sopenharmony_ci		goto exit2;
496462306a36Sopenharmony_ci
496562306a36Sopenharmony_ciretry_deleg:
496662306a36Sopenharmony_ci	trap = lock_rename(new_path.dentry, old_path.dentry);
496762306a36Sopenharmony_ci
496862306a36Sopenharmony_ci	old_dentry = lookup_one_qstr_excl(&old_last, old_path.dentry,
496962306a36Sopenharmony_ci					  lookup_flags);
497062306a36Sopenharmony_ci	error = PTR_ERR(old_dentry);
497162306a36Sopenharmony_ci	if (IS_ERR(old_dentry))
497262306a36Sopenharmony_ci		goto exit3;
497362306a36Sopenharmony_ci	/* source must exist */
497462306a36Sopenharmony_ci	error = -ENOENT;
497562306a36Sopenharmony_ci	if (d_is_negative(old_dentry))
497662306a36Sopenharmony_ci		goto exit4;
497762306a36Sopenharmony_ci	new_dentry = lookup_one_qstr_excl(&new_last, new_path.dentry,
497862306a36Sopenharmony_ci					  lookup_flags | target_flags);
497962306a36Sopenharmony_ci	error = PTR_ERR(new_dentry);
498062306a36Sopenharmony_ci	if (IS_ERR(new_dentry))
498162306a36Sopenharmony_ci		goto exit4;
498262306a36Sopenharmony_ci	error = -EEXIST;
498362306a36Sopenharmony_ci	if ((flags & RENAME_NOREPLACE) && d_is_positive(new_dentry))
498462306a36Sopenharmony_ci		goto exit5;
498562306a36Sopenharmony_ci	if (flags & RENAME_EXCHANGE) {
498662306a36Sopenharmony_ci		error = -ENOENT;
498762306a36Sopenharmony_ci		if (d_is_negative(new_dentry))
498862306a36Sopenharmony_ci			goto exit5;
498962306a36Sopenharmony_ci
499062306a36Sopenharmony_ci		if (!d_is_dir(new_dentry)) {
499162306a36Sopenharmony_ci			error = -ENOTDIR;
499262306a36Sopenharmony_ci			if (new_last.name[new_last.len])
499362306a36Sopenharmony_ci				goto exit5;
499462306a36Sopenharmony_ci		}
499562306a36Sopenharmony_ci	}
499662306a36Sopenharmony_ci	/* unless the source is a directory trailing slashes give -ENOTDIR */
499762306a36Sopenharmony_ci	if (!d_is_dir(old_dentry)) {
499862306a36Sopenharmony_ci		error = -ENOTDIR;
499962306a36Sopenharmony_ci		if (old_last.name[old_last.len])
500062306a36Sopenharmony_ci			goto exit5;
500162306a36Sopenharmony_ci		if (!(flags & RENAME_EXCHANGE) && new_last.name[new_last.len])
500262306a36Sopenharmony_ci			goto exit5;
500362306a36Sopenharmony_ci	}
500462306a36Sopenharmony_ci	/* source should not be ancestor of target */
500562306a36Sopenharmony_ci	error = -EINVAL;
500662306a36Sopenharmony_ci	if (old_dentry == trap)
500762306a36Sopenharmony_ci		goto exit5;
500862306a36Sopenharmony_ci	/* target should not be an ancestor of source */
500962306a36Sopenharmony_ci	if (!(flags & RENAME_EXCHANGE))
501062306a36Sopenharmony_ci		error = -ENOTEMPTY;
501162306a36Sopenharmony_ci	if (new_dentry == trap)
501262306a36Sopenharmony_ci		goto exit5;
501362306a36Sopenharmony_ci
501462306a36Sopenharmony_ci	error = security_path_rename(&old_path, old_dentry,
501562306a36Sopenharmony_ci				     &new_path, new_dentry, flags);
501662306a36Sopenharmony_ci	if (error)
501762306a36Sopenharmony_ci		goto exit5;
501862306a36Sopenharmony_ci
501962306a36Sopenharmony_ci	rd.old_dir	   = old_path.dentry->d_inode;
502062306a36Sopenharmony_ci	rd.old_dentry	   = old_dentry;
502162306a36Sopenharmony_ci	rd.old_mnt_idmap   = mnt_idmap(old_path.mnt);
502262306a36Sopenharmony_ci	rd.new_dir	   = new_path.dentry->d_inode;
502362306a36Sopenharmony_ci	rd.new_dentry	   = new_dentry;
502462306a36Sopenharmony_ci	rd.new_mnt_idmap   = mnt_idmap(new_path.mnt);
502562306a36Sopenharmony_ci	rd.delegated_inode = &delegated_inode;
502662306a36Sopenharmony_ci	rd.flags	   = flags;
502762306a36Sopenharmony_ci	error = vfs_rename(&rd);
502862306a36Sopenharmony_ciexit5:
502962306a36Sopenharmony_ci	dput(new_dentry);
503062306a36Sopenharmony_ciexit4:
503162306a36Sopenharmony_ci	dput(old_dentry);
503262306a36Sopenharmony_ciexit3:
503362306a36Sopenharmony_ci	unlock_rename(new_path.dentry, old_path.dentry);
503462306a36Sopenharmony_ci	if (delegated_inode) {
503562306a36Sopenharmony_ci		error = break_deleg_wait(&delegated_inode);
503662306a36Sopenharmony_ci		if (!error)
503762306a36Sopenharmony_ci			goto retry_deleg;
503862306a36Sopenharmony_ci	}
503962306a36Sopenharmony_ci	mnt_drop_write(old_path.mnt);
504062306a36Sopenharmony_ciexit2:
504162306a36Sopenharmony_ci	if (retry_estale(error, lookup_flags))
504262306a36Sopenharmony_ci		should_retry = true;
504362306a36Sopenharmony_ci	path_put(&new_path);
504462306a36Sopenharmony_ciexit1:
504562306a36Sopenharmony_ci	path_put(&old_path);
504662306a36Sopenharmony_ci	if (should_retry) {
504762306a36Sopenharmony_ci		should_retry = false;
504862306a36Sopenharmony_ci		lookup_flags |= LOOKUP_REVAL;
504962306a36Sopenharmony_ci		goto retry;
505062306a36Sopenharmony_ci	}
505162306a36Sopenharmony_ciput_names:
505262306a36Sopenharmony_ci	putname(from);
505362306a36Sopenharmony_ci	putname(to);
505462306a36Sopenharmony_ci	return error;
505562306a36Sopenharmony_ci}
505662306a36Sopenharmony_ci
505762306a36Sopenharmony_ciSYSCALL_DEFINE5(renameat2, int, olddfd, const char __user *, oldname,
505862306a36Sopenharmony_ci		int, newdfd, const char __user *, newname, unsigned int, flags)
505962306a36Sopenharmony_ci{
506062306a36Sopenharmony_ci	return do_renameat2(olddfd, getname(oldname), newdfd, getname(newname),
506162306a36Sopenharmony_ci				flags);
506262306a36Sopenharmony_ci}
506362306a36Sopenharmony_ci
506462306a36Sopenharmony_ciSYSCALL_DEFINE4(renameat, int, olddfd, const char __user *, oldname,
506562306a36Sopenharmony_ci		int, newdfd, const char __user *, newname)
506662306a36Sopenharmony_ci{
506762306a36Sopenharmony_ci	return do_renameat2(olddfd, getname(oldname), newdfd, getname(newname),
506862306a36Sopenharmony_ci				0);
506962306a36Sopenharmony_ci}
507062306a36Sopenharmony_ci
507162306a36Sopenharmony_ciSYSCALL_DEFINE2(rename, const char __user *, oldname, const char __user *, newname)
507262306a36Sopenharmony_ci{
507362306a36Sopenharmony_ci	return do_renameat2(AT_FDCWD, getname(oldname), AT_FDCWD,
507462306a36Sopenharmony_ci				getname(newname), 0);
507562306a36Sopenharmony_ci}
507662306a36Sopenharmony_ci
507762306a36Sopenharmony_ciint readlink_copy(char __user *buffer, int buflen, const char *link)
507862306a36Sopenharmony_ci{
507962306a36Sopenharmony_ci	int len = PTR_ERR(link);
508062306a36Sopenharmony_ci	if (IS_ERR(link))
508162306a36Sopenharmony_ci		goto out;
508262306a36Sopenharmony_ci
508362306a36Sopenharmony_ci	len = strlen(link);
508462306a36Sopenharmony_ci	if (len > (unsigned) buflen)
508562306a36Sopenharmony_ci		len = buflen;
508662306a36Sopenharmony_ci	if (copy_to_user(buffer, link, len))
508762306a36Sopenharmony_ci		len = -EFAULT;
508862306a36Sopenharmony_ciout:
508962306a36Sopenharmony_ci	return len;
509062306a36Sopenharmony_ci}
509162306a36Sopenharmony_ci
509262306a36Sopenharmony_ci/**
509362306a36Sopenharmony_ci * vfs_readlink - copy symlink body into userspace buffer
509462306a36Sopenharmony_ci * @dentry: dentry on which to get symbolic link
509562306a36Sopenharmony_ci * @buffer: user memory pointer
509662306a36Sopenharmony_ci * @buflen: size of buffer
509762306a36Sopenharmony_ci *
509862306a36Sopenharmony_ci * Does not touch atime.  That's up to the caller if necessary
509962306a36Sopenharmony_ci *
510062306a36Sopenharmony_ci * Does not call security hook.
510162306a36Sopenharmony_ci */
510262306a36Sopenharmony_ciint vfs_readlink(struct dentry *dentry, char __user *buffer, int buflen)
510362306a36Sopenharmony_ci{
510462306a36Sopenharmony_ci	struct inode *inode = d_inode(dentry);
510562306a36Sopenharmony_ci	DEFINE_DELAYED_CALL(done);
510662306a36Sopenharmony_ci	const char *link;
510762306a36Sopenharmony_ci	int res;
510862306a36Sopenharmony_ci
510962306a36Sopenharmony_ci	if (unlikely(!(inode->i_opflags & IOP_DEFAULT_READLINK))) {
511062306a36Sopenharmony_ci		if (unlikely(inode->i_op->readlink))
511162306a36Sopenharmony_ci			return inode->i_op->readlink(dentry, buffer, buflen);
511262306a36Sopenharmony_ci
511362306a36Sopenharmony_ci		if (!d_is_symlink(dentry))
511462306a36Sopenharmony_ci			return -EINVAL;
511562306a36Sopenharmony_ci
511662306a36Sopenharmony_ci		spin_lock(&inode->i_lock);
511762306a36Sopenharmony_ci		inode->i_opflags |= IOP_DEFAULT_READLINK;
511862306a36Sopenharmony_ci		spin_unlock(&inode->i_lock);
511962306a36Sopenharmony_ci	}
512062306a36Sopenharmony_ci
512162306a36Sopenharmony_ci	link = READ_ONCE(inode->i_link);
512262306a36Sopenharmony_ci	if (!link) {
512362306a36Sopenharmony_ci		link = inode->i_op->get_link(dentry, inode, &done);
512462306a36Sopenharmony_ci		if (IS_ERR(link))
512562306a36Sopenharmony_ci			return PTR_ERR(link);
512662306a36Sopenharmony_ci	}
512762306a36Sopenharmony_ci	res = readlink_copy(buffer, buflen, link);
512862306a36Sopenharmony_ci	do_delayed_call(&done);
512962306a36Sopenharmony_ci	return res;
513062306a36Sopenharmony_ci}
513162306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_readlink);
513262306a36Sopenharmony_ci
513362306a36Sopenharmony_ci/**
513462306a36Sopenharmony_ci * vfs_get_link - get symlink body
513562306a36Sopenharmony_ci * @dentry: dentry on which to get symbolic link
513662306a36Sopenharmony_ci * @done: caller needs to free returned data with this
513762306a36Sopenharmony_ci *
513862306a36Sopenharmony_ci * Calls security hook and i_op->get_link() on the supplied inode.
513962306a36Sopenharmony_ci *
514062306a36Sopenharmony_ci * It does not touch atime.  That's up to the caller if necessary.
514162306a36Sopenharmony_ci *
514262306a36Sopenharmony_ci * Does not work on "special" symlinks like /proc/$$/fd/N
514362306a36Sopenharmony_ci */
514462306a36Sopenharmony_ciconst char *vfs_get_link(struct dentry *dentry, struct delayed_call *done)
514562306a36Sopenharmony_ci{
514662306a36Sopenharmony_ci	const char *res = ERR_PTR(-EINVAL);
514762306a36Sopenharmony_ci	struct inode *inode = d_inode(dentry);
514862306a36Sopenharmony_ci
514962306a36Sopenharmony_ci	if (d_is_symlink(dentry)) {
515062306a36Sopenharmony_ci		res = ERR_PTR(security_inode_readlink(dentry));
515162306a36Sopenharmony_ci		if (!res)
515262306a36Sopenharmony_ci			res = inode->i_op->get_link(dentry, inode, done);
515362306a36Sopenharmony_ci	}
515462306a36Sopenharmony_ci	return res;
515562306a36Sopenharmony_ci}
515662306a36Sopenharmony_ciEXPORT_SYMBOL(vfs_get_link);
515762306a36Sopenharmony_ci
515862306a36Sopenharmony_ci/* get the link contents into pagecache */
515962306a36Sopenharmony_ciconst char *page_get_link(struct dentry *dentry, struct inode *inode,
516062306a36Sopenharmony_ci			  struct delayed_call *callback)
516162306a36Sopenharmony_ci{
516262306a36Sopenharmony_ci	char *kaddr;
516362306a36Sopenharmony_ci	struct page *page;
516462306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
516562306a36Sopenharmony_ci
516662306a36Sopenharmony_ci	if (!dentry) {
516762306a36Sopenharmony_ci		page = find_get_page(mapping, 0);
516862306a36Sopenharmony_ci		if (!page)
516962306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
517062306a36Sopenharmony_ci		if (!PageUptodate(page)) {
517162306a36Sopenharmony_ci			put_page(page);
517262306a36Sopenharmony_ci			return ERR_PTR(-ECHILD);
517362306a36Sopenharmony_ci		}
517462306a36Sopenharmony_ci	} else {
517562306a36Sopenharmony_ci		page = read_mapping_page(mapping, 0, NULL);
517662306a36Sopenharmony_ci		if (IS_ERR(page))
517762306a36Sopenharmony_ci			return (char*)page;
517862306a36Sopenharmony_ci	}
517962306a36Sopenharmony_ci	set_delayed_call(callback, page_put_link, page);
518062306a36Sopenharmony_ci	BUG_ON(mapping_gfp_mask(mapping) & __GFP_HIGHMEM);
518162306a36Sopenharmony_ci	kaddr = page_address(page);
518262306a36Sopenharmony_ci	nd_terminate_link(kaddr, inode->i_size, PAGE_SIZE - 1);
518362306a36Sopenharmony_ci	return kaddr;
518462306a36Sopenharmony_ci}
518562306a36Sopenharmony_ci
518662306a36Sopenharmony_ciEXPORT_SYMBOL(page_get_link);
518762306a36Sopenharmony_ci
518862306a36Sopenharmony_civoid page_put_link(void *arg)
518962306a36Sopenharmony_ci{
519062306a36Sopenharmony_ci	put_page(arg);
519162306a36Sopenharmony_ci}
519262306a36Sopenharmony_ciEXPORT_SYMBOL(page_put_link);
519362306a36Sopenharmony_ci
519462306a36Sopenharmony_ciint page_readlink(struct dentry *dentry, char __user *buffer, int buflen)
519562306a36Sopenharmony_ci{
519662306a36Sopenharmony_ci	DEFINE_DELAYED_CALL(done);
519762306a36Sopenharmony_ci	int res = readlink_copy(buffer, buflen,
519862306a36Sopenharmony_ci				page_get_link(dentry, d_inode(dentry),
519962306a36Sopenharmony_ci					      &done));
520062306a36Sopenharmony_ci	do_delayed_call(&done);
520162306a36Sopenharmony_ci	return res;
520262306a36Sopenharmony_ci}
520362306a36Sopenharmony_ciEXPORT_SYMBOL(page_readlink);
520462306a36Sopenharmony_ci
520562306a36Sopenharmony_ciint page_symlink(struct inode *inode, const char *symname, int len)
520662306a36Sopenharmony_ci{
520762306a36Sopenharmony_ci	struct address_space *mapping = inode->i_mapping;
520862306a36Sopenharmony_ci	const struct address_space_operations *aops = mapping->a_ops;
520962306a36Sopenharmony_ci	bool nofs = !mapping_gfp_constraint(mapping, __GFP_FS);
521062306a36Sopenharmony_ci	struct page *page;
521162306a36Sopenharmony_ci	void *fsdata = NULL;
521262306a36Sopenharmony_ci	int err;
521362306a36Sopenharmony_ci	unsigned int flags;
521462306a36Sopenharmony_ci
521562306a36Sopenharmony_ciretry:
521662306a36Sopenharmony_ci	if (nofs)
521762306a36Sopenharmony_ci		flags = memalloc_nofs_save();
521862306a36Sopenharmony_ci	err = aops->write_begin(NULL, mapping, 0, len-1, &page, &fsdata);
521962306a36Sopenharmony_ci	if (nofs)
522062306a36Sopenharmony_ci		memalloc_nofs_restore(flags);
522162306a36Sopenharmony_ci	if (err)
522262306a36Sopenharmony_ci		goto fail;
522362306a36Sopenharmony_ci
522462306a36Sopenharmony_ci	memcpy(page_address(page), symname, len-1);
522562306a36Sopenharmony_ci
522662306a36Sopenharmony_ci	err = aops->write_end(NULL, mapping, 0, len-1, len-1,
522762306a36Sopenharmony_ci							page, fsdata);
522862306a36Sopenharmony_ci	if (err < 0)
522962306a36Sopenharmony_ci		goto fail;
523062306a36Sopenharmony_ci	if (err < len-1)
523162306a36Sopenharmony_ci		goto retry;
523262306a36Sopenharmony_ci
523362306a36Sopenharmony_ci	mark_inode_dirty(inode);
523462306a36Sopenharmony_ci	return 0;
523562306a36Sopenharmony_cifail:
523662306a36Sopenharmony_ci	return err;
523762306a36Sopenharmony_ci}
523862306a36Sopenharmony_ciEXPORT_SYMBOL(page_symlink);
523962306a36Sopenharmony_ci
524062306a36Sopenharmony_ciconst struct inode_operations page_symlink_inode_operations = {
524162306a36Sopenharmony_ci	.get_link	= page_get_link,
524262306a36Sopenharmony_ci};
524362306a36Sopenharmony_ciEXPORT_SYMBOL(page_symlink_inode_operations);
5244