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

ioctl.c (3840B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * linux/fs/ext2/ioctl.c
      4 *
      5 * Copyright (C) 1993, 1994, 1995
      6 * Remy Card (card@masi.ibp.fr)
      7 * Laboratoire MASI - Institut Blaise Pascal
      8 * Universite Pierre et Marie Curie (Paris VI)
      9 */
     10
     11#include "ext2.h"
     12#include <linux/capability.h>
     13#include <linux/time.h>
     14#include <linux/sched.h>
     15#include <linux/compat.h>
     16#include <linux/mount.h>
     17#include <asm/current.h>
     18#include <linux/uaccess.h>
     19#include <linux/fileattr.h>
     20
     21int ext2_fileattr_get(struct dentry *dentry, struct fileattr *fa)
     22{
     23	struct ext2_inode_info *ei = EXT2_I(d_inode(dentry));
     24
     25	fileattr_fill_flags(fa, ei->i_flags & EXT2_FL_USER_VISIBLE);
     26
     27	return 0;
     28}
     29
     30int ext2_fileattr_set(struct user_namespace *mnt_userns,
     31		      struct dentry *dentry, struct fileattr *fa)
     32{
     33	struct inode *inode = d_inode(dentry);
     34	struct ext2_inode_info *ei = EXT2_I(inode);
     35
     36	if (fileattr_has_fsx(fa))
     37		return -EOPNOTSUPP;
     38
     39	/* Is it quota file? Do not allow user to mess with it */
     40	if (IS_NOQUOTA(inode))
     41		return -EPERM;
     42
     43	ei->i_flags = (ei->i_flags & ~EXT2_FL_USER_MODIFIABLE) |
     44		(fa->flags & EXT2_FL_USER_MODIFIABLE);
     45
     46	ext2_set_inode_flags(inode);
     47	inode->i_ctime = current_time(inode);
     48	mark_inode_dirty(inode);
     49
     50	return 0;
     51}
     52
     53
     54long ext2_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
     55{
     56	struct inode *inode = file_inode(filp);
     57	struct ext2_inode_info *ei = EXT2_I(inode);
     58	unsigned short rsv_window_size;
     59	int ret;
     60
     61	ext2_debug ("cmd = %u, arg = %lu\n", cmd, arg);
     62
     63	switch (cmd) {
     64	case EXT2_IOC_GETVERSION:
     65		return put_user(inode->i_generation, (int __user *) arg);
     66	case EXT2_IOC_SETVERSION: {
     67		__u32 generation;
     68
     69		if (!inode_owner_or_capable(&init_user_ns, inode))
     70			return -EPERM;
     71		ret = mnt_want_write_file(filp);
     72		if (ret)
     73			return ret;
     74		if (get_user(generation, (int __user *) arg)) {
     75			ret = -EFAULT;
     76			goto setversion_out;
     77		}
     78
     79		inode_lock(inode);
     80		inode->i_ctime = current_time(inode);
     81		inode->i_generation = generation;
     82		inode_unlock(inode);
     83
     84		mark_inode_dirty(inode);
     85setversion_out:
     86		mnt_drop_write_file(filp);
     87		return ret;
     88	}
     89	case EXT2_IOC_GETRSVSZ:
     90		if (test_opt(inode->i_sb, RESERVATION)
     91			&& S_ISREG(inode->i_mode)
     92			&& ei->i_block_alloc_info) {
     93			rsv_window_size = ei->i_block_alloc_info->rsv_window_node.rsv_goal_size;
     94			return put_user(rsv_window_size, (int __user *)arg);
     95		}
     96		return -ENOTTY;
     97	case EXT2_IOC_SETRSVSZ: {
     98
     99		if (!test_opt(inode->i_sb, RESERVATION) ||!S_ISREG(inode->i_mode))
    100			return -ENOTTY;
    101
    102		if (!inode_owner_or_capable(&init_user_ns, inode))
    103			return -EACCES;
    104
    105		if (get_user(rsv_window_size, (int __user *)arg))
    106			return -EFAULT;
    107
    108		ret = mnt_want_write_file(filp);
    109		if (ret)
    110			return ret;
    111
    112		if (rsv_window_size > EXT2_MAX_RESERVE_BLOCKS)
    113			rsv_window_size = EXT2_MAX_RESERVE_BLOCKS;
    114
    115		/*
    116		 * need to allocate reservation structure for this inode
    117		 * before set the window size
    118		 */
    119		/*
    120		 * XXX What lock should protect the rsv_goal_size?
    121		 * Accessed in ext2_get_block only.  ext3 uses i_truncate.
    122		 */
    123		mutex_lock(&ei->truncate_mutex);
    124		if (!ei->i_block_alloc_info)
    125			ext2_init_block_alloc_info(inode);
    126
    127		if (ei->i_block_alloc_info){
    128			struct ext2_reserve_window_node *rsv = &ei->i_block_alloc_info->rsv_window_node;
    129			rsv->rsv_goal_size = rsv_window_size;
    130		} else {
    131			ret = -ENOMEM;
    132		}
    133
    134		mutex_unlock(&ei->truncate_mutex);
    135		mnt_drop_write_file(filp);
    136		return ret;
    137	}
    138	default:
    139		return -ENOTTY;
    140	}
    141}
    142
    143#ifdef CONFIG_COMPAT
    144long ext2_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
    145{
    146	/* These are just misnamed, they actually get/put from/to user an int */
    147	switch (cmd) {
    148	case EXT2_IOC32_GETVERSION:
    149		cmd = EXT2_IOC_GETVERSION;
    150		break;
    151	case EXT2_IOC32_SETVERSION:
    152		cmd = EXT2_IOC_SETVERSION;
    153		break;
    154	default:
    155		return -ENOIOCTLCMD;
    156	}
    157	return ext2_ioctl(file, cmd, (unsigned long) compat_ptr(arg));
    158}
    159#endif