1313#include <linux/mount.h>
1414#include "fscrypt_private.h"
1515
16- static int inode_has_encryption_context (struct inode * inode )
17- {
18- if (!inode -> i_sb -> s_cop -> get_context )
19- return 0 ;
20- return (inode -> i_sb -> s_cop -> get_context (inode , NULL , 0L ) > 0 );
21- }
22-
2316/*
24- * check whether the policy is consistent with the encryption context
25- * for the inode
17+ * check whether an encryption policy is consistent with an encryption context
2618 */
27- static int is_encryption_context_consistent_with_policy (struct inode * inode ,
19+ static bool is_encryption_context_consistent_with_policy (
20+ const struct fscrypt_context * ctx ,
2821 const struct fscrypt_policy * policy )
2922{
30- struct fscrypt_context ctx ;
31- int res ;
32-
33- if (!inode -> i_sb -> s_cop -> get_context )
34- return 0 ;
35-
36- res = inode -> i_sb -> s_cop -> get_context (inode , & ctx , sizeof (ctx ));
37- if (res != sizeof (ctx ))
38- return 0 ;
39-
40- return (memcmp (ctx .master_key_descriptor , policy -> master_key_descriptor ,
41- FS_KEY_DESCRIPTOR_SIZE ) == 0 &&
42- (ctx .flags == policy -> flags ) &&
43- (ctx .contents_encryption_mode ==
44- policy -> contents_encryption_mode ) &&
45- (ctx .filenames_encryption_mode ==
46- policy -> filenames_encryption_mode ));
23+ return memcmp (ctx -> master_key_descriptor , policy -> master_key_descriptor ,
24+ FS_KEY_DESCRIPTOR_SIZE ) == 0 &&
25+ (ctx -> flags == policy -> flags ) &&
26+ (ctx -> contents_encryption_mode ==
27+ policy -> contents_encryption_mode ) &&
28+ (ctx -> filenames_encryption_mode ==
29+ policy -> filenames_encryption_mode );
4730}
4831
4932static int create_encryption_context_from_policy (struct inode * inode ,
@@ -90,6 +73,7 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
9073 struct fscrypt_policy policy ;
9174 struct inode * inode = file_inode (filp );
9275 int ret ;
76+ struct fscrypt_context ctx ;
9377
9478 if (copy_from_user (& policy , arg , sizeof (policy )))
9579 return - EFAULT ;
@@ -106,7 +90,8 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
10690
10791 inode_lock (inode );
10892
109- if (!inode_has_encryption_context (inode )) {
93+ ret = inode -> i_sb -> s_cop -> get_context (inode , & ctx , sizeof (ctx ));
94+ if (ret == - ENODATA ) {
11095 if (!S_ISDIR (inode -> i_mode ))
11196 ret = - ENOTDIR ;
11297 else if (!inode -> i_sb -> s_cop -> empty_dir )
@@ -116,8 +101,13 @@ int fscrypt_ioctl_set_policy(struct file *filp, const void __user *arg)
116101 else
117102 ret = create_encryption_context_from_policy (inode ,
118103 & policy );
119- } else if (!is_encryption_context_consistent_with_policy (inode ,
120- & policy )) {
104+ } else if (ret == sizeof (ctx ) &&
105+ is_encryption_context_consistent_with_policy (& ctx ,
106+ & policy )) {
107+ /* The file already uses the same encryption policy. */
108+ ret = 0 ;
109+ } else if (ret >= 0 || ret == - ERANGE ) {
110+ /* The file already uses a different encryption policy. */
121111 ret = - EEXIST ;
122112 }
123113
@@ -140,8 +130,10 @@ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
140130 return - ENODATA ;
141131
142132 res = inode -> i_sb -> s_cop -> get_context (inode , & ctx , sizeof (ctx ));
133+ if (res < 0 && res != - ERANGE )
134+ return res ;
143135 if (res != sizeof (ctx ))
144- return - ENODATA ;
136+ return - EINVAL ;
145137 if (ctx .format != FS_ENCRYPTION_CONTEXT_FORMAT_V1 )
146138 return - EINVAL ;
147139
0 commit comments