| .. | .. | 
|---|
 | 1 | +// SPDX-License-Identifier: GPL-2.0-only  | 
|---|
| 1 | 2 |  /* | 
|---|
| 2 | 3 |   * This file is part of UBIFS. | 
|---|
| 3 | 4 |   * | 
|---|
| 4 | 5 |   * Copyright (C) 2006-2008 Nokia Corporation. | 
|---|
| 5 | 6 |   * Copyright (C) 2006, 2007 University of Szeged, Hungary | 
|---|
| 6 |  | - *  | 
|---|
| 7 |  | - * This program is free software; you can redistribute it and/or modify it  | 
|---|
| 8 |  | - * under the terms of the GNU General Public License version 2 as published by  | 
|---|
| 9 |  | - * the Free Software Foundation.  | 
|---|
| 10 |  | - *  | 
|---|
| 11 |  | - * This program is distributed in the hope that it will be useful, but WITHOUT  | 
|---|
| 12 |  | - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or  | 
|---|
| 13 |  | - * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for  | 
|---|
| 14 |  | - * more details.  | 
|---|
| 15 |  | - *  | 
|---|
| 16 |  | - * You should have received a copy of the GNU General Public License along with  | 
|---|
| 17 |  | - * this program; if not, write to the Free Software Foundation, Inc., 51  | 
|---|
| 18 |  | - * Franklin St, Fifth Floor, Boston, MA 02110-1301 USA  | 
|---|
| 19 | 7 |   * | 
|---|
| 20 | 8 |   * Authors: Zoltan Sogor | 
|---|
| 21 | 9 |   *          Artem Bityutskiy (Битюцкий Артём) | 
|---|
| .. | .. | 
|---|
| 29 | 17 |  #include "ubifs.h" | 
|---|
| 30 | 18 |   | 
|---|
| 31 | 19 |  /* Need to be kept consistent with checked flags in ioctl2ubifs() */ | 
|---|
| 32 |  | -#define UBIFS_SUPPORTED_IOCTL_FLAGS \  | 
|---|
 | 20 | +#define UBIFS_SETTABLE_IOCTL_FLAGS \  | 
|---|
| 33 | 21 |  	(FS_COMPR_FL | FS_SYNC_FL | FS_APPEND_FL | \ | 
|---|
| 34 | 22 |  	 FS_IMMUTABLE_FL | FS_DIRSYNC_FL) | 
|---|
 | 23 | +  | 
|---|
 | 24 | +/* Need to be kept consistent with checked flags in ubifs2ioctl() */  | 
|---|
 | 25 | +#define UBIFS_GETTABLE_IOCTL_FLAGS \  | 
|---|
 | 26 | +	(UBIFS_SETTABLE_IOCTL_FLAGS | FS_ENCRYPT_FL)  | 
|---|
| 35 | 27 |   | 
|---|
| 36 | 28 |  /** | 
|---|
| 37 | 29 |   * ubifs_set_inode_flags - set VFS inode flags. | 
|---|
| .. | .. | 
|---|
| 103 | 95 |  		ioctl_flags |= FS_IMMUTABLE_FL; | 
|---|
| 104 | 96 |  	if (ubifs_flags & UBIFS_DIRSYNC_FL) | 
|---|
| 105 | 97 |  		ioctl_flags |= FS_DIRSYNC_FL; | 
|---|
 | 98 | +	if (ubifs_flags & UBIFS_CRYPT_FL)  | 
|---|
 | 99 | +		ioctl_flags |= FS_ENCRYPT_FL;  | 
|---|
| 106 | 100 |   | 
|---|
| 107 | 101 |  	return ioctl_flags; | 
|---|
| 108 | 102 |  } | 
|---|
| .. | .. | 
|---|
| 113 | 107 |  	struct ubifs_inode *ui = ubifs_inode(inode); | 
|---|
| 114 | 108 |  	struct ubifs_info *c = inode->i_sb->s_fs_info; | 
|---|
| 115 | 109 |  	struct ubifs_budget_req req = { .dirtied_ino = 1, | 
|---|
| 116 |  | -					.dirtied_ino_d = ui->data_len };  | 
|---|
 | 110 | +			.dirtied_ino_d = ALIGN(ui->data_len, 8) };  | 
|---|
| 117 | 111 |   | 
|---|
| 118 | 112 |  	err = ubifs_budget_space(c, &req); | 
|---|
| 119 | 113 |  	if (err) | 
|---|
| 120 | 114 |  		return err; | 
|---|
| 121 | 115 |   | 
|---|
| 122 |  | -	/*  | 
|---|
| 123 |  | -	 * The IMMUTABLE and APPEND_ONLY flags can only be changed by  | 
|---|
| 124 |  | -	 * the relevant capability.  | 
|---|
| 125 |  | -	 */  | 
|---|
| 126 | 116 |  	mutex_lock(&ui->ui_mutex); | 
|---|
| 127 | 117 |  	oldflags = ubifs2ioctl(ui->flags); | 
|---|
| 128 |  | -	if ((flags ^ oldflags) & (FS_APPEND_FL | FS_IMMUTABLE_FL)) {  | 
|---|
| 129 |  | -		if (!capable(CAP_LINUX_IMMUTABLE)) {  | 
|---|
| 130 |  | -			err = -EPERM;  | 
|---|
| 131 |  | -			goto out_unlock;  | 
|---|
| 132 |  | -		}  | 
|---|
| 133 |  | -	}  | 
|---|
 | 118 | +	err = vfs_ioc_setflags_prepare(inode, oldflags, flags);  | 
|---|
 | 119 | +	if (err)  | 
|---|
 | 120 | +		goto out_unlock;  | 
|---|
| 134 | 121 |   | 
|---|
| 135 |  | -	ui->flags &= ~ioctl2ubifs(UBIFS_SUPPORTED_IOCTL_FLAGS);  | 
|---|
 | 122 | +	ui->flags &= ~ioctl2ubifs(UBIFS_SETTABLE_IOCTL_FLAGS);  | 
|---|
| 136 | 123 |  	ui->flags |= ioctl2ubifs(flags); | 
|---|
| 137 | 124 |  	ubifs_set_inode_flags(inode); | 
|---|
| 138 | 125 |  	inode->i_ctime = current_time(inode); | 
|---|
| .. | .. | 
|---|
| 147 | 134 |  	return err; | 
|---|
| 148 | 135 |   | 
|---|
| 149 | 136 |  out_unlock: | 
|---|
| 150 |  | -	ubifs_err(c, "can't modify inode %lu attributes", inode->i_ino);  | 
|---|
| 151 | 137 |  	mutex_unlock(&ui->ui_mutex); | 
|---|
| 152 | 138 |  	ubifs_release_budget(c, &req); | 
|---|
| 153 | 139 |  	return err; | 
|---|
| .. | .. | 
|---|
| 175 | 161 |  		if (get_user(flags, (int __user *) arg)) | 
|---|
| 176 | 162 |  			return -EFAULT; | 
|---|
| 177 | 163 |   | 
|---|
| 178 |  | -		if (flags & ~UBIFS_SUPPORTED_IOCTL_FLAGS)  | 
|---|
 | 164 | +		if (flags & ~UBIFS_GETTABLE_IOCTL_FLAGS)  | 
|---|
| 179 | 165 |  			return -EOPNOTSUPP; | 
|---|
 | 166 | +		flags &= UBIFS_SETTABLE_IOCTL_FLAGS;  | 
|---|
| 180 | 167 |   | 
|---|
| 181 | 168 |  		if (!S_ISDIR(inode->i_mode)) | 
|---|
| 182 | 169 |  			flags &= ~FS_DIRSYNC_FL; | 
|---|
| .. | .. | 
|---|
| 194 | 181 |  		return err; | 
|---|
| 195 | 182 |  	} | 
|---|
| 196 | 183 |  	case FS_IOC_SET_ENCRYPTION_POLICY: { | 
|---|
| 197 |  | -#ifdef CONFIG_FS_ENCRYPTION  | 
|---|
| 198 | 184 |  		struct ubifs_info *c = inode->i_sb->s_fs_info; | 
|---|
| 199 | 185 |   | 
|---|
| 200 | 186 |  		err = ubifs_enable_encryption(c); | 
|---|
| .. | .. | 
|---|
| 202 | 188 |  			return err; | 
|---|
| 203 | 189 |   | 
|---|
| 204 | 190 |  		return fscrypt_ioctl_set_policy(file, (const void __user *)arg); | 
|---|
| 205 |  | -#else  | 
|---|
| 206 |  | -		return -EOPNOTSUPP;  | 
|---|
| 207 |  | -#endif  | 
|---|
| 208 | 191 |  	} | 
|---|
| 209 |  | -	case FS_IOC_GET_ENCRYPTION_POLICY: {  | 
|---|
| 210 |  | -#ifdef CONFIG_FS_ENCRYPTION  | 
|---|
 | 192 | +	case FS_IOC_GET_ENCRYPTION_POLICY:  | 
|---|
| 211 | 193 |  		return fscrypt_ioctl_get_policy(file, (void __user *)arg); | 
|---|
| 212 |  | -#else  | 
|---|
| 213 |  | -		return -EOPNOTSUPP;  | 
|---|
| 214 |  | -#endif  | 
|---|
| 215 |  | -	}  | 
|---|
| 216 | 194 |   | 
|---|
| 217 | 195 |  	case FS_IOC_GET_ENCRYPTION_POLICY_EX: | 
|---|
| 218 | 196 |  		return fscrypt_ioctl_get_policy_ex(file, (void __user *)arg); | 
|---|