summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2016-10-20 10:47:56 -0400
committerRichard Weinberger <richard@nod.at>2016-12-12 17:07:38 -0500
commitd475a507457b5cafa428871a473d0dcc828c5f68 (patch)
tree7f6608195cfc421e6d3d7975cc8b916a55e4a914
parent6a5e98ab7d8665d2faddbd91a8a2bf9addb79aff (diff)
ubifs: Add skeleton for fscrypto
This is the first building block to provide file level encryption on UBIFS. Signed-off-by: Richard Weinberger <richard@nod.at>
-rw-r--r--fs/ubifs/Kconfig11
-rw-r--r--fs/ubifs/Makefile1
-rw-r--r--fs/ubifs/crypto.c46
-rw-r--r--fs/ubifs/dir.c28
-rw-r--r--fs/ubifs/ioctl.c35
-rw-r--r--fs/ubifs/super.c10
-rw-r--r--fs/ubifs/ubifs-media.h2
-rw-r--r--fs/ubifs/ubifs.h37
-rw-r--r--fs/ubifs/xattr.c10
9 files changed, 178 insertions, 2 deletions
diff --git a/fs/ubifs/Kconfig b/fs/ubifs/Kconfig
index 7ff7712f284e..0a908ae7af13 100644
--- a/fs/ubifs/Kconfig
+++ b/fs/ubifs/Kconfig
@@ -50,3 +50,14 @@ config UBIFS_ATIME_SUPPORT
50 strictatime is the "heavy", relatime is "lighter", etc. 50 strictatime is the "heavy", relatime is "lighter", etc.
51 51
52 If unsure, say 'N' 52 If unsure, say 'N'
53
54config UBIFS_FS_ENCRYPTION
55 bool "UBIFS Encryption"
56 depends on UBIFS_FS
57 select FS_ENCRYPTION
58 default n
59 help
60 Enable encryption of UBIFS files and directories. This
61 feature is similar to ecryptfs, but it is more memory
62 efficient since it avoids caching the encrypted and
63 decrypted pages in the page cache.
diff --git a/fs/ubifs/Makefile b/fs/ubifs/Makefile
index c54a24360f85..6f3251c2bf08 100644
--- a/fs/ubifs/Makefile
+++ b/fs/ubifs/Makefile
@@ -5,3 +5,4 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
5ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o 5ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
6ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o 6ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
7ubifs-y += misc.o 7ubifs-y += misc.o
8ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o
diff --git a/fs/ubifs/crypto.c b/fs/ubifs/crypto.c
new file mode 100644
index 000000000000..12a0072bddd3
--- /dev/null
+++ b/fs/ubifs/crypto.c
@@ -0,0 +1,46 @@
1#include "ubifs.h"
2
3static int ubifs_crypt_get_context(struct inode *inode, void *ctx, size_t len)
4{
5 return ubifs_xattr_get(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
6 ctx, len);
7}
8
9static int ubifs_crypt_set_context(struct inode *inode, const void *ctx,
10 size_t len, void *fs_data)
11{
12 return ubifs_xattr_set(inode, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT,
13 ctx, len, 0);
14}
15
16static bool ubifs_crypt_empty_dir(struct inode *inode)
17{
18 return ubifs_check_dir_empty(inode) == 0;
19}
20
21static unsigned int ubifs_crypt_max_namelen(struct inode *inode)
22{
23 if (S_ISLNK(inode->i_mode))
24 return UBIFS_MAX_INO_DATA;
25 else
26 return UBIFS_MAX_NLEN;
27}
28
29static int ubifs_key_prefix(struct inode *inode, u8 **key)
30{
31 static char prefix[] = "ubifs:";
32
33 *key = prefix;
34
35 return sizeof(prefix) - 1;
36}
37
38struct fscrypt_operations ubifs_crypt_operations = {
39 .flags = FS_CFLG_INPLACE_ENCRYPTION,
40 .get_context = ubifs_crypt_get_context,
41 .set_context = ubifs_crypt_set_context,
42 .is_encrypted = ubifs_crypt_is_encrypted,
43 .empty_dir = ubifs_crypt_empty_dir,
44 .max_namelen = ubifs_crypt_max_namelen,
45 .key_prefix = ubifs_key_prefix,
46};
diff --git a/fs/ubifs/dir.c b/fs/ubifs/dir.c
index 14a226d47f4c..2315cb864c39 100644
--- a/fs/ubifs/dir.c
+++ b/fs/ubifs/dir.c
@@ -85,11 +85,26 @@ static int inherit_flags(const struct inode *dir, umode_t mode)
85 * initializes it. Returns new inode in case of success and an error code in 85 * initializes it. Returns new inode in case of success and an error code in
86 * case of failure. 86 * case of failure.
87 */ 87 */
88struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, 88struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
89 umode_t mode) 89 umode_t mode)
90{ 90{
91 int err;
91 struct inode *inode; 92 struct inode *inode;
92 struct ubifs_inode *ui; 93 struct ubifs_inode *ui;
94 bool encrypted = false;
95
96 if (ubifs_crypt_is_encrypted(dir)) {
97 err = fscrypt_get_encryption_info(dir);
98 if (err) {
99 ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err);
100 return ERR_PTR(err);
101 }
102
103 if (!fscrypt_has_encryption_key(dir))
104 return ERR_PTR(-EPERM);
105
106 encrypted = true;
107 }
93 108
94 inode = new_inode(c->vfs_sb); 109 inode = new_inode(c->vfs_sb);
95 ui = ubifs_inode(inode); 110 ui = ubifs_inode(inode);
@@ -165,6 +180,17 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
165 */ 180 */
166 ui->creat_sqnum = ++c->max_sqnum; 181 ui->creat_sqnum = ++c->max_sqnum;
167 spin_unlock(&c->cnt_lock); 182 spin_unlock(&c->cnt_lock);
183
184 if (encrypted) {
185 err = fscrypt_inherit_context(dir, inode, &encrypted, true);
186 if (err) {
187 ubifs_err(c, "fscrypt_inherit_context failed: %i", err);
188 make_bad_inode(inode);
189 iput(inode);
190 return ERR_PTR(err);
191 }
192 }
193
168 return inode; 194 return inode;
169} 195}
170 196
diff --git a/fs/ubifs/ioctl.c b/fs/ubifs/ioctl.c
index 3c7b29de0ca7..6bb5b35050de 100644
--- a/fs/ubifs/ioctl.c
+++ b/fs/ubifs/ioctl.c
@@ -181,6 +181,41 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
181 mnt_drop_write_file(file); 181 mnt_drop_write_file(file);
182 return err; 182 return err;
183 } 183 }
184 case FS_IOC_SET_ENCRYPTION_POLICY: {
185#ifdef CONFIG_UBIFS_FS_ENCRYPTION
186 struct fscrypt_policy policy;
187
188 if (copy_from_user(&policy,
189 (struct fscrypt_policy __user *)arg,
190 sizeof(policy)))
191 return -EFAULT;
192
193 err = fscrypt_process_policy(file, &policy);
194
195 return err;
196#else
197 return -EOPNOTSUPP;
198#endif
199 }
200 case FS_IOC_GET_ENCRYPTION_POLICY: {
201#ifdef CONFIG_UBIFS_FS_ENCRYPTION
202 struct fscrypt_policy policy;
203
204 if (!ubifs_crypt_is_encrypted(inode))
205 return -ENOENT;
206
207 err = fscrypt_get_policy(inode, &policy);
208 if (err)
209 return err;
210
211 if (copy_to_user((void __user *)arg, &policy, sizeof(policy)))
212 return -EFAULT;
213
214 return 0;
215#else
216 return -EOPNOTSUPP;
217#endif
218 }
184 219
185 default: 220 default:
186 return -ENOTTY; 221 return -ENOTTY;
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c
index 4ec051089186..e85d5a47aeac 100644
--- a/fs/ubifs/super.c
+++ b/fs/ubifs/super.c
@@ -380,6 +380,9 @@ out:
380 } 380 }
381done: 381done:
382 clear_inode(inode); 382 clear_inode(inode);
383#ifdef CONFIG_UBIFS_FS_ENCRYPTION
384 fscrypt_put_encryption_info(inode, NULL);
385#endif
383} 386}
384 387
385static void ubifs_dirty_inode(struct inode *inode, int flags) 388static void ubifs_dirty_inode(struct inode *inode, int flags)
@@ -1995,6 +1998,12 @@ static struct ubifs_info *alloc_ubifs_info(struct ubi_volume_desc *ubi)
1995 return c; 1998 return c;
1996} 1999}
1997 2000
2001#ifndef CONFIG_UBIFS_FS_ENCRYPTION
2002struct fscrypt_operations ubifs_crypt_operations = {
2003 .is_encrypted = ubifs_crypt_is_encrypted,
2004};
2005#endif
2006
1998static int ubifs_fill_super(struct super_block *sb, void *data, int silent) 2007static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
1999{ 2008{
2000 struct ubifs_info *c = sb->s_fs_info; 2009 struct ubifs_info *c = sb->s_fs_info;
@@ -2041,6 +2050,7 @@ static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
2041 sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE; 2050 sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
2042 sb->s_op = &ubifs_super_operations; 2051 sb->s_op = &ubifs_super_operations;
2043 sb->s_xattr = ubifs_xattr_handlers; 2052 sb->s_xattr = ubifs_xattr_handlers;
2053 sb->s_cop = &ubifs_crypt_operations;
2044 2054
2045 mutex_lock(&c->umount_mutex); 2055 mutex_lock(&c->umount_mutex);
2046 err = mount_ubifs(c); 2056 err = mount_ubifs(c);
diff --git a/fs/ubifs/ubifs-media.h b/fs/ubifs/ubifs-media.h
index d47e9569b3de..aa302b11aec8 100644
--- a/fs/ubifs/ubifs-media.h
+++ b/fs/ubifs/ubifs-media.h
@@ -316,6 +316,7 @@ enum {
316 * UBIFS_APPEND_FL: writes to the inode may only append data 316 * UBIFS_APPEND_FL: writes to the inode may only append data
317 * UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous 317 * UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous
318 * UBIFS_XATTR_FL: this inode is the inode for an extended attribute value 318 * UBIFS_XATTR_FL: this inode is the inode for an extended attribute value
319 * UBIFS_CRYPT_FL: use encryption for this inode
319 * 320 *
320 * Note, these are on-flash flags which correspond to ioctl flags 321 * Note, these are on-flash flags which correspond to ioctl flags
321 * (@FS_COMPR_FL, etc). They have the same values now, but generally, do not 322 * (@FS_COMPR_FL, etc). They have the same values now, but generally, do not
@@ -328,6 +329,7 @@ enum {
328 UBIFS_APPEND_FL = 0x08, 329 UBIFS_APPEND_FL = 0x08,
329 UBIFS_DIRSYNC_FL = 0x10, 330 UBIFS_DIRSYNC_FL = 0x10,
330 UBIFS_XATTR_FL = 0x20, 331 UBIFS_XATTR_FL = 0x20,
332 UBIFS_CRYPT_FL = 0x40,
331}; 333};
332 334
333/* Inode flag bits used by UBIFS */ 335/* Inode flag bits used by UBIFS */
diff --git a/fs/ubifs/ubifs.h b/fs/ubifs/ubifs.h
index 0f8a3ec6a7fe..27a85015e3ff 100644
--- a/fs/ubifs/ubifs.h
+++ b/fs/ubifs/ubifs.h
@@ -38,6 +38,7 @@
38#include <linux/backing-dev.h> 38#include <linux/backing-dev.h>
39#include <linux/security.h> 39#include <linux/security.h>
40#include <linux/xattr.h> 40#include <linux/xattr.h>
41#include <linux/fscrypto.h>
41#include "ubifs-media.h" 42#include "ubifs-media.h"
42 43
43/* Version of this UBIFS implementation */ 44/* Version of this UBIFS implementation */
@@ -1724,7 +1725,7 @@ int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
1724#endif 1725#endif
1725 1726
1726/* dir.c */ 1727/* dir.c */
1727struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir, 1728struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
1728 umode_t mode); 1729 umode_t mode);
1729int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry, 1730int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
1730 struct kstat *stat); 1731 struct kstat *stat);
@@ -1773,10 +1774,44 @@ void ubifs_compress(const struct ubifs_info *c, const void *in_buf, int in_len,
1773int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len, 1774int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
1774 void *out, int *out_len, int compr_type); 1775 void *out, int *out_len, int compr_type);
1775 1776
1777extern struct fscrypt_operations ubifs_crypt_operations;
1778
1776#include "debug.h" 1779#include "debug.h"
1777#include "misc.h" 1780#include "misc.h"
1778#include "key.h" 1781#include "key.h"
1779 1782
1783#ifndef CONFIG_UBIFS_FS_ENCRYPTION
1784#define fscrypt_set_d_op(i)
1785#define fscrypt_get_ctx fscrypt_notsupp_get_ctx
1786#define fscrypt_release_ctx fscrypt_notsupp_release_ctx
1787#define fscrypt_encrypt_page fscrypt_notsupp_encrypt_page
1788#define fscrypt_decrypt_page fscrypt_notsupp_decrypt_page
1789#define fscrypt_decrypt_bio_pages fscrypt_notsupp_decrypt_bio_pages
1790#define fscrypt_pullback_bio_page fscrypt_notsupp_pullback_bio_page
1791#define fscrypt_restore_control_page fscrypt_notsupp_restore_control_page
1792#define fscrypt_zeroout_range fscrypt_notsupp_zeroout_range
1793#define fscrypt_process_policy fscrypt_notsupp_process_policy
1794#define fscrypt_get_policy fscrypt_notsupp_get_policy
1795#define fscrypt_has_permitted_context fscrypt_notsupp_has_permitted_context
1796#define fscrypt_inherit_context fscrypt_notsupp_inherit_context
1797#define fscrypt_get_encryption_info fscrypt_notsupp_get_encryption_info
1798#define fscrypt_put_encryption_info fscrypt_notsupp_put_encryption_info
1799#define fscrypt_setup_filename fscrypt_notsupp_setup_filename
1800#define fscrypt_free_filename fscrypt_notsupp_free_filename
1801#define fscrypt_fname_encrypted_size fscrypt_notsupp_fname_encrypted_size
1802#define fscrypt_fname_alloc_buffer fscrypt_notsupp_fname_alloc_buffer
1803#define fscrypt_fname_free_buffer fscrypt_notsupp_fname_free_buffer
1804#define fscrypt_fname_disk_to_usr fscrypt_notsupp_fname_disk_to_usr
1805#define fscrypt_fname_usr_to_disk fscrypt_notsupp_fname_usr_to_disk
1806#endif
1807
1808static inline bool ubifs_crypt_is_encrypted(struct inode *inode)
1809{
1810 struct ubifs_inode *ui = ubifs_inode(inode);
1811
1812 return ui->flags & UBIFS_CRYPT_FL;
1813}
1814
1780/* Normal UBIFS messages */ 1815/* Normal UBIFS messages */
1781__printf(2, 3) 1816__printf(2, 3)
1782void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...); 1817void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...);
diff --git a/fs/ubifs/xattr.c b/fs/ubifs/xattr.c
index 2d09dbeecd58..95a16028bbdb 100644
--- a/fs/ubifs/xattr.c
+++ b/fs/ubifs/xattr.c
@@ -158,6 +158,15 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
158 host_ui->xattr_size += CALC_XATTR_BYTES(size); 158 host_ui->xattr_size += CALC_XATTR_BYTES(size);
159 host_ui->xattr_names += nm->len; 159 host_ui->xattr_names += nm->len;
160 160
161 /*
162 * We handle UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT here because we
163 * have to set the UBIFS_CRYPT_FL flag on the host inode.
164 * To avoid multiple updates of the same inode in the same operation,
165 * let's do it here.
166 */
167 if (strcmp(nm->name, UBIFS_XATTR_NAME_ENCRYPTION_CONTEXT) == 0)
168 host_ui->flags |= UBIFS_CRYPT_FL;
169
161 err = ubifs_jnl_update(c, host, nm, inode, 0, 1); 170 err = ubifs_jnl_update(c, host, nm, inode, 0, 1);
162 if (err) 171 if (err)
163 goto out_cancel; 172 goto out_cancel;
@@ -173,6 +182,7 @@ out_cancel:
173 host_ui->xattr_size -= CALC_DENT_SIZE(nm->len); 182 host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
174 host_ui->xattr_size -= CALC_XATTR_BYTES(size); 183 host_ui->xattr_size -= CALC_XATTR_BYTES(size);
175 host_ui->xattr_names -= nm->len; 184 host_ui->xattr_names -= nm->len;
185 host_ui->flags &= ~UBIFS_CRYPT_FL;
176 mutex_unlock(&host_ui->ui_mutex); 186 mutex_unlock(&host_ui->ui_mutex);
177out_free: 187out_free:
178 make_bad_inode(inode); 188 make_bad_inode(inode);