Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4

Pull fscrypto fixes fromTed Ts'o:
"Fix some brown-paper-bag bugs for fscrypto, including one one which
allows a malicious user to set an encryption policy on an empty
directory which they do not own"

* tag 'for_linus_stable' of git://git.kernel.org/pub/scm/linux/kernel/git/tytso/ext4:
fscrypto: require write access to mount to set encryption policy
fscrypto: only allow setting encryption policy on directories
fscrypto: add authorization check for setting encryption policy

+33 -24
+29 -12
fs/crypto/policy.c
··· 11 11 #include <linux/random.h> 12 12 #include <linux/string.h> 13 13 #include <linux/fscrypto.h> 14 + #include <linux/mount.h> 14 15 15 16 static int inode_has_encryption_context(struct inode *inode) 16 17 { ··· 93 92 return inode->i_sb->s_cop->set_context(inode, &ctx, sizeof(ctx), NULL); 94 93 } 95 94 96 - int fscrypt_process_policy(struct inode *inode, 95 + int fscrypt_process_policy(struct file *filp, 97 96 const struct fscrypt_policy *policy) 98 97 { 98 + struct inode *inode = file_inode(filp); 99 + int ret; 100 + 101 + if (!inode_owner_or_capable(inode)) 102 + return -EACCES; 103 + 99 104 if (policy->version != 0) 100 105 return -EINVAL; 101 106 107 + ret = mnt_want_write_file(filp); 108 + if (ret) 109 + return ret; 110 + 102 111 if (!inode_has_encryption_context(inode)) { 103 - if (!inode->i_sb->s_cop->empty_dir) 104 - return -EOPNOTSUPP; 105 - if (!inode->i_sb->s_cop->empty_dir(inode)) 106 - return -ENOTEMPTY; 107 - return create_encryption_context_from_policy(inode, policy); 112 + if (!S_ISDIR(inode->i_mode)) 113 + ret = -EINVAL; 114 + else if (!inode->i_sb->s_cop->empty_dir) 115 + ret = -EOPNOTSUPP; 116 + else if (!inode->i_sb->s_cop->empty_dir(inode)) 117 + ret = -ENOTEMPTY; 118 + else 119 + ret = create_encryption_context_from_policy(inode, 120 + policy); 121 + } else if (!is_encryption_context_consistent_with_policy(inode, 122 + policy)) { 123 + printk(KERN_WARNING 124 + "%s: Policy inconsistent with encryption context\n", 125 + __func__); 126 + ret = -EINVAL; 108 127 } 109 128 110 - if (is_encryption_context_consistent_with_policy(inode, policy)) 111 - return 0; 112 - 113 - printk(KERN_WARNING "%s: Policy inconsistent with encryption context\n", 114 - __func__); 115 - return -EINVAL; 129 + mnt_drop_write_file(filp); 130 + return ret; 116 131 } 117 132 EXPORT_SYMBOL(fscrypt_process_policy); 118 133
+1 -1
fs/ext4/ioctl.c
··· 776 776 (struct fscrypt_policy __user *)arg, 777 777 sizeof(policy))) 778 778 return -EFAULT; 779 - return fscrypt_process_policy(inode, &policy); 779 + return fscrypt_process_policy(filp, &policy); 780 780 #else 781 781 return -EOPNOTSUPP; 782 782 #endif
+1 -8
fs/f2fs/file.c
··· 1757 1757 { 1758 1758 struct fscrypt_policy policy; 1759 1759 struct inode *inode = file_inode(filp); 1760 - int ret; 1761 1760 1762 1761 if (copy_from_user(&policy, (struct fscrypt_policy __user *)arg, 1763 1762 sizeof(policy))) 1764 1763 return -EFAULT; 1765 1764 1766 - ret = mnt_want_write_file(filp); 1767 - if (ret) 1768 - return ret; 1769 - 1770 1765 f2fs_update_time(F2FS_I_SB(inode), REQ_TIME); 1771 - ret = fscrypt_process_policy(inode, &policy); 1772 1766 1773 - mnt_drop_write_file(filp); 1774 - return ret; 1767 + return fscrypt_process_policy(filp, &policy); 1775 1768 } 1776 1769 1777 1770 static int f2fs_ioc_get_encryption_policy(struct file *filp, unsigned long arg)
+2 -3
include/linux/fscrypto.h
··· 274 274 extern int fscrypt_zeroout_range(struct inode *, pgoff_t, sector_t, 275 275 unsigned int); 276 276 /* policy.c */ 277 - extern int fscrypt_process_policy(struct inode *, 278 - const struct fscrypt_policy *); 277 + extern int fscrypt_process_policy(struct file *, const struct fscrypt_policy *); 279 278 extern int fscrypt_get_policy(struct inode *, struct fscrypt_policy *); 280 279 extern int fscrypt_has_permitted_context(struct inode *, struct inode *); 281 280 extern int fscrypt_inherit_context(struct inode *, struct inode *, ··· 344 345 } 345 346 346 347 /* policy.c */ 347 - static inline int fscrypt_notsupp_process_policy(struct inode *i, 348 + static inline int fscrypt_notsupp_process_policy(struct file *f, 348 349 const struct fscrypt_policy *p) 349 350 { 350 351 return -EOPNOTSUPP;