cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode.c (11126B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * fs/kernfs/inode.c - kernfs inode implementation
      4 *
      5 * Copyright (c) 2001-3 Patrick Mochel
      6 * Copyright (c) 2007 SUSE Linux Products GmbH
      7 * Copyright (c) 2007, 2013 Tejun Heo <tj@kernel.org>
      8 */
      9
     10#include <linux/pagemap.h>
     11#include <linux/backing-dev.h>
     12#include <linux/capability.h>
     13#include <linux/errno.h>
     14#include <linux/slab.h>
     15#include <linux/xattr.h>
     16#include <linux/security.h>
     17
     18#include "kernfs-internal.h"
     19
     20static const struct inode_operations kernfs_iops = {
     21	.permission	= kernfs_iop_permission,
     22	.setattr	= kernfs_iop_setattr,
     23	.getattr	= kernfs_iop_getattr,
     24	.listxattr	= kernfs_iop_listxattr,
     25};
     26
     27static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, int alloc)
     28{
     29	static DEFINE_MUTEX(iattr_mutex);
     30	struct kernfs_iattrs *ret;
     31
     32	mutex_lock(&iattr_mutex);
     33
     34	if (kn->iattr || !alloc)
     35		goto out_unlock;
     36
     37	kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL);
     38	if (!kn->iattr)
     39		goto out_unlock;
     40
     41	/* assign default attributes */
     42	kn->iattr->ia_uid = GLOBAL_ROOT_UID;
     43	kn->iattr->ia_gid = GLOBAL_ROOT_GID;
     44
     45	ktime_get_real_ts64(&kn->iattr->ia_atime);
     46	kn->iattr->ia_mtime = kn->iattr->ia_atime;
     47	kn->iattr->ia_ctime = kn->iattr->ia_atime;
     48
     49	simple_xattrs_init(&kn->iattr->xattrs);
     50	atomic_set(&kn->iattr->nr_user_xattrs, 0);
     51	atomic_set(&kn->iattr->user_xattr_size, 0);
     52out_unlock:
     53	ret = kn->iattr;
     54	mutex_unlock(&iattr_mutex);
     55	return ret;
     56}
     57
     58static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
     59{
     60	return __kernfs_iattrs(kn, 1);
     61}
     62
     63static struct kernfs_iattrs *kernfs_iattrs_noalloc(struct kernfs_node *kn)
     64{
     65	return __kernfs_iattrs(kn, 0);
     66}
     67
     68int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
     69{
     70	struct kernfs_iattrs *attrs;
     71	unsigned int ia_valid = iattr->ia_valid;
     72
     73	attrs = kernfs_iattrs(kn);
     74	if (!attrs)
     75		return -ENOMEM;
     76
     77	if (ia_valid & ATTR_UID)
     78		attrs->ia_uid = iattr->ia_uid;
     79	if (ia_valid & ATTR_GID)
     80		attrs->ia_gid = iattr->ia_gid;
     81	if (ia_valid & ATTR_ATIME)
     82		attrs->ia_atime = iattr->ia_atime;
     83	if (ia_valid & ATTR_MTIME)
     84		attrs->ia_mtime = iattr->ia_mtime;
     85	if (ia_valid & ATTR_CTIME)
     86		attrs->ia_ctime = iattr->ia_ctime;
     87	if (ia_valid & ATTR_MODE)
     88		kn->mode = iattr->ia_mode;
     89	return 0;
     90}
     91
     92/**
     93 * kernfs_setattr - set iattr on a node
     94 * @kn: target node
     95 * @iattr: iattr to set
     96 *
     97 * Returns 0 on success, -errno on failure.
     98 */
     99int kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
    100{
    101	int ret;
    102	struct kernfs_root *root = kernfs_root(kn);
    103
    104	down_write(&root->kernfs_rwsem);
    105	ret = __kernfs_setattr(kn, iattr);
    106	up_write(&root->kernfs_rwsem);
    107	return ret;
    108}
    109
    110int kernfs_iop_setattr(struct user_namespace *mnt_userns, struct dentry *dentry,
    111		       struct iattr *iattr)
    112{
    113	struct inode *inode = d_inode(dentry);
    114	struct kernfs_node *kn = inode->i_private;
    115	struct kernfs_root *root;
    116	int error;
    117
    118	if (!kn)
    119		return -EINVAL;
    120
    121	root = kernfs_root(kn);
    122	down_write(&root->kernfs_rwsem);
    123	error = setattr_prepare(&init_user_ns, dentry, iattr);
    124	if (error)
    125		goto out;
    126
    127	error = __kernfs_setattr(kn, iattr);
    128	if (error)
    129		goto out;
    130
    131	/* this ignores size changes */
    132	setattr_copy(&init_user_ns, inode, iattr);
    133
    134out:
    135	up_write(&root->kernfs_rwsem);
    136	return error;
    137}
    138
    139ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size)
    140{
    141	struct kernfs_node *kn = kernfs_dentry_node(dentry);
    142	struct kernfs_iattrs *attrs;
    143
    144	attrs = kernfs_iattrs(kn);
    145	if (!attrs)
    146		return -ENOMEM;
    147
    148	return simple_xattr_list(d_inode(dentry), &attrs->xattrs, buf, size);
    149}
    150
    151static inline void set_default_inode_attr(struct inode *inode, umode_t mode)
    152{
    153	inode->i_mode = mode;
    154	inode->i_atime = inode->i_mtime =
    155		inode->i_ctime = current_time(inode);
    156}
    157
    158static inline void set_inode_attr(struct inode *inode,
    159				  struct kernfs_iattrs *attrs)
    160{
    161	inode->i_uid = attrs->ia_uid;
    162	inode->i_gid = attrs->ia_gid;
    163	inode->i_atime = attrs->ia_atime;
    164	inode->i_mtime = attrs->ia_mtime;
    165	inode->i_ctime = attrs->ia_ctime;
    166}
    167
    168static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode)
    169{
    170	struct kernfs_iattrs *attrs = kn->iattr;
    171
    172	inode->i_mode = kn->mode;
    173	if (attrs)
    174		/*
    175		 * kernfs_node has non-default attributes get them from
    176		 * persistent copy in kernfs_node.
    177		 */
    178		set_inode_attr(inode, attrs);
    179
    180	if (kernfs_type(kn) == KERNFS_DIR)
    181		set_nlink(inode, kn->dir.subdirs + 2);
    182}
    183
    184int kernfs_iop_getattr(struct user_namespace *mnt_userns,
    185		       const struct path *path, struct kstat *stat,
    186		       u32 request_mask, unsigned int query_flags)
    187{
    188	struct inode *inode = d_inode(path->dentry);
    189	struct kernfs_node *kn = inode->i_private;
    190	struct kernfs_root *root = kernfs_root(kn);
    191
    192	down_read(&root->kernfs_rwsem);
    193	spin_lock(&inode->i_lock);
    194	kernfs_refresh_inode(kn, inode);
    195	generic_fillattr(&init_user_ns, inode, stat);
    196	spin_unlock(&inode->i_lock);
    197	up_read(&root->kernfs_rwsem);
    198
    199	return 0;
    200}
    201
    202static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode)
    203{
    204	kernfs_get(kn);
    205	inode->i_private = kn;
    206	inode->i_mapping->a_ops = &ram_aops;
    207	inode->i_op = &kernfs_iops;
    208	inode->i_generation = kernfs_gen(kn);
    209
    210	set_default_inode_attr(inode, kn->mode);
    211	kernfs_refresh_inode(kn, inode);
    212
    213	/* initialize inode according to type */
    214	switch (kernfs_type(kn)) {
    215	case KERNFS_DIR:
    216		inode->i_op = &kernfs_dir_iops;
    217		inode->i_fop = &kernfs_dir_fops;
    218		if (kn->flags & KERNFS_EMPTY_DIR)
    219			make_empty_dir_inode(inode);
    220		break;
    221	case KERNFS_FILE:
    222		inode->i_size = kn->attr.size;
    223		inode->i_fop = &kernfs_file_fops;
    224		break;
    225	case KERNFS_LINK:
    226		inode->i_op = &kernfs_symlink_iops;
    227		break;
    228	default:
    229		BUG();
    230	}
    231
    232	unlock_new_inode(inode);
    233}
    234
    235/**
    236 *	kernfs_get_inode - get inode for kernfs_node
    237 *	@sb: super block
    238 *	@kn: kernfs_node to allocate inode for
    239 *
    240 *	Get inode for @kn.  If such inode doesn't exist, a new inode is
    241 *	allocated and basics are initialized.  New inode is returned
    242 *	locked.
    243 *
    244 *	LOCKING:
    245 *	Kernel thread context (may sleep).
    246 *
    247 *	RETURNS:
    248 *	Pointer to allocated inode on success, NULL on failure.
    249 */
    250struct inode *kernfs_get_inode(struct super_block *sb, struct kernfs_node *kn)
    251{
    252	struct inode *inode;
    253
    254	inode = iget_locked(sb, kernfs_ino(kn));
    255	if (inode && (inode->i_state & I_NEW))
    256		kernfs_init_inode(kn, inode);
    257
    258	return inode;
    259}
    260
    261/*
    262 * The kernfs_node serves as both an inode and a directory entry for
    263 * kernfs.  To prevent the kernfs inode numbers from being freed
    264 * prematurely we take a reference to kernfs_node from the kernfs inode.  A
    265 * super_operations.evict_inode() implementation is needed to drop that
    266 * reference upon inode destruction.
    267 */
    268void kernfs_evict_inode(struct inode *inode)
    269{
    270	struct kernfs_node *kn = inode->i_private;
    271
    272	truncate_inode_pages_final(&inode->i_data);
    273	clear_inode(inode);
    274	kernfs_put(kn);
    275}
    276
    277int kernfs_iop_permission(struct user_namespace *mnt_userns,
    278			  struct inode *inode, int mask)
    279{
    280	struct kernfs_node *kn;
    281	struct kernfs_root *root;
    282	int ret;
    283
    284	if (mask & MAY_NOT_BLOCK)
    285		return -ECHILD;
    286
    287	kn = inode->i_private;
    288	root = kernfs_root(kn);
    289
    290	down_read(&root->kernfs_rwsem);
    291	spin_lock(&inode->i_lock);
    292	kernfs_refresh_inode(kn, inode);
    293	ret = generic_permission(&init_user_ns, inode, mask);
    294	spin_unlock(&inode->i_lock);
    295	up_read(&root->kernfs_rwsem);
    296
    297	return ret;
    298}
    299
    300int kernfs_xattr_get(struct kernfs_node *kn, const char *name,
    301		     void *value, size_t size)
    302{
    303	struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn);
    304	if (!attrs)
    305		return -ENODATA;
    306
    307	return simple_xattr_get(&attrs->xattrs, name, value, size);
    308}
    309
    310int kernfs_xattr_set(struct kernfs_node *kn, const char *name,
    311		     const void *value, size_t size, int flags)
    312{
    313	struct kernfs_iattrs *attrs = kernfs_iattrs(kn);
    314	if (!attrs)
    315		return -ENOMEM;
    316
    317	return simple_xattr_set(&attrs->xattrs, name, value, size, flags, NULL);
    318}
    319
    320static int kernfs_vfs_xattr_get(const struct xattr_handler *handler,
    321				struct dentry *unused, struct inode *inode,
    322				const char *suffix, void *value, size_t size)
    323{
    324	const char *name = xattr_full_name(handler, suffix);
    325	struct kernfs_node *kn = inode->i_private;
    326
    327	return kernfs_xattr_get(kn, name, value, size);
    328}
    329
    330static int kernfs_vfs_xattr_set(const struct xattr_handler *handler,
    331				struct user_namespace *mnt_userns,
    332				struct dentry *unused, struct inode *inode,
    333				const char *suffix, const void *value,
    334				size_t size, int flags)
    335{
    336	const char *name = xattr_full_name(handler, suffix);
    337	struct kernfs_node *kn = inode->i_private;
    338
    339	return kernfs_xattr_set(kn, name, value, size, flags);
    340}
    341
    342static int kernfs_vfs_user_xattr_add(struct kernfs_node *kn,
    343				     const char *full_name,
    344				     struct simple_xattrs *xattrs,
    345				     const void *value, size_t size, int flags)
    346{
    347	atomic_t *sz = &kn->iattr->user_xattr_size;
    348	atomic_t *nr = &kn->iattr->nr_user_xattrs;
    349	ssize_t removed_size;
    350	int ret;
    351
    352	if (atomic_inc_return(nr) > KERNFS_MAX_USER_XATTRS) {
    353		ret = -ENOSPC;
    354		goto dec_count_out;
    355	}
    356
    357	if (atomic_add_return(size, sz) > KERNFS_USER_XATTR_SIZE_LIMIT) {
    358		ret = -ENOSPC;
    359		goto dec_size_out;
    360	}
    361
    362	ret = simple_xattr_set(xattrs, full_name, value, size, flags,
    363			       &removed_size);
    364
    365	if (!ret && removed_size >= 0)
    366		size = removed_size;
    367	else if (!ret)
    368		return 0;
    369dec_size_out:
    370	atomic_sub(size, sz);
    371dec_count_out:
    372	atomic_dec(nr);
    373	return ret;
    374}
    375
    376static int kernfs_vfs_user_xattr_rm(struct kernfs_node *kn,
    377				    const char *full_name,
    378				    struct simple_xattrs *xattrs,
    379				    const void *value, size_t size, int flags)
    380{
    381	atomic_t *sz = &kn->iattr->user_xattr_size;
    382	atomic_t *nr = &kn->iattr->nr_user_xattrs;
    383	ssize_t removed_size;
    384	int ret;
    385
    386	ret = simple_xattr_set(xattrs, full_name, value, size, flags,
    387			       &removed_size);
    388
    389	if (removed_size >= 0) {
    390		atomic_sub(removed_size, sz);
    391		atomic_dec(nr);
    392	}
    393
    394	return ret;
    395}
    396
    397static int kernfs_vfs_user_xattr_set(const struct xattr_handler *handler,
    398				     struct user_namespace *mnt_userns,
    399				     struct dentry *unused, struct inode *inode,
    400				     const char *suffix, const void *value,
    401				     size_t size, int flags)
    402{
    403	const char *full_name = xattr_full_name(handler, suffix);
    404	struct kernfs_node *kn = inode->i_private;
    405	struct kernfs_iattrs *attrs;
    406
    407	if (!(kernfs_root(kn)->flags & KERNFS_ROOT_SUPPORT_USER_XATTR))
    408		return -EOPNOTSUPP;
    409
    410	attrs = kernfs_iattrs(kn);
    411	if (!attrs)
    412		return -ENOMEM;
    413
    414	if (value)
    415		return kernfs_vfs_user_xattr_add(kn, full_name, &attrs->xattrs,
    416						 value, size, flags);
    417	else
    418		return kernfs_vfs_user_xattr_rm(kn, full_name, &attrs->xattrs,
    419						value, size, flags);
    420
    421}
    422
    423static const struct xattr_handler kernfs_trusted_xattr_handler = {
    424	.prefix = XATTR_TRUSTED_PREFIX,
    425	.get = kernfs_vfs_xattr_get,
    426	.set = kernfs_vfs_xattr_set,
    427};
    428
    429static const struct xattr_handler kernfs_security_xattr_handler = {
    430	.prefix = XATTR_SECURITY_PREFIX,
    431	.get = kernfs_vfs_xattr_get,
    432	.set = kernfs_vfs_xattr_set,
    433};
    434
    435static const struct xattr_handler kernfs_user_xattr_handler = {
    436	.prefix = XATTR_USER_PREFIX,
    437	.get = kernfs_vfs_xattr_get,
    438	.set = kernfs_vfs_user_xattr_set,
    439};
    440
    441const struct xattr_handler *kernfs_xattr_handlers[] = {
    442	&kernfs_trusted_xattr_handler,
    443	&kernfs_security_xattr_handler,
    444	&kernfs_user_xattr_handler,
    445	NULL
    446};