Skip to content

Commit d475a50

Browse files
ubifs: Add skeleton for fscrypto
This is the first building block to provide file level encryption on UBIFS. Signed-off-by: Richard Weinberger <[email protected]>
1 parent 6a5e98a commit d475a50

File tree

9 files changed

+178
-2
lines changed

9 files changed

+178
-2
lines changed

fs/ubifs/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,14 @@ config UBIFS_ATIME_SUPPORT
5050
strictatime is the "heavy", relatime is "lighter", etc.
5151

5252
If unsure, say 'N'
53+
54+
config 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.

fs/ubifs/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ ubifs-y += tnc.o master.o scan.o replay.o log.o commit.o gc.o orphan.o
55
ubifs-y += budget.o find.o tnc_commit.o compress.o lpt.o lprops.o
66
ubifs-y += recovery.o ioctl.o lpt_commit.o tnc_misc.o xattr.o debug.o
77
ubifs-y += misc.o
8+
ubifs-$(CONFIG_UBIFS_FS_ENCRYPTION) += crypto.o

fs/ubifs/crypto.c

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#include "ubifs.h"
2+
3+
static 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+
9+
static 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+
16+
static bool ubifs_crypt_empty_dir(struct inode *inode)
17+
{
18+
return ubifs_check_dir_empty(inode) == 0;
19+
}
20+
21+
static 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+
29+
static 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+
38+
struct 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+
};

fs/ubifs/dir.c

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,11 +85,26 @@ static int inherit_flags(const struct inode *dir, umode_t mode)
8585
* initializes it. Returns new inode in case of success and an error code in
8686
* case of failure.
8787
*/
88-
struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
88+
struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
8989
umode_t mode)
9090
{
91+
int err;
9192
struct inode *inode;
9293
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+
}
93108

94109
inode = new_inode(c->vfs_sb);
95110
ui = ubifs_inode(inode);
@@ -165,6 +180,17 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
165180
*/
166181
ui->creat_sqnum = ++c->max_sqnum;
167182
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+
168194
return inode;
169195
}
170196

fs/ubifs/ioctl.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,41 @@ long ubifs_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
181181
mnt_drop_write_file(file);
182182
return err;
183183
}
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+
}
184219

185220
default:
186221
return -ENOTTY;

fs/ubifs/super.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -380,6 +380,9 @@ static void ubifs_evict_inode(struct inode *inode)
380380
}
381381
done:
382382
clear_inode(inode);
383+
#ifdef CONFIG_UBIFS_FS_ENCRYPTION
384+
fscrypt_put_encryption_info(inode, NULL);
385+
#endif
383386
}
384387

385388
static 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)
19951998
return c;
19961999
}
19972000

2001+
#ifndef CONFIG_UBIFS_FS_ENCRYPTION
2002+
struct fscrypt_operations ubifs_crypt_operations = {
2003+
.is_encrypted = ubifs_crypt_is_encrypted,
2004+
};
2005+
#endif
2006+
19982007
static int ubifs_fill_super(struct super_block *sb, void *data, int silent)
19992008
{
20002009
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)
20412050
sb->s_maxbytes = c->max_inode_sz = MAX_LFS_FILESIZE;
20422051
sb->s_op = &ubifs_super_operations;
20432052
sb->s_xattr = ubifs_xattr_handlers;
2053+
sb->s_cop = &ubifs_crypt_operations;
20442054

20452055
mutex_lock(&c->umount_mutex);
20462056
err = mount_ubifs(c);

fs/ubifs/ubifs-media.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ enum {
316316
* UBIFS_APPEND_FL: writes to the inode may only append data
317317
* UBIFS_DIRSYNC_FL: I/O on this directory inode has to be synchronous
318318
* UBIFS_XATTR_FL: this inode is the inode for an extended attribute value
319+
* UBIFS_CRYPT_FL: use encryption for this inode
319320
*
320321
* Note, these are on-flash flags which correspond to ioctl flags
321322
* (@FS_COMPR_FL, etc). They have the same values now, but generally, do not
@@ -328,6 +329,7 @@ enum {
328329
UBIFS_APPEND_FL = 0x08,
329330
UBIFS_DIRSYNC_FL = 0x10,
330331
UBIFS_XATTR_FL = 0x20,
332+
UBIFS_CRYPT_FL = 0x40,
331333
};
332334

333335
/* Inode flag bits used by UBIFS */

fs/ubifs/ubifs.h

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include <linux/backing-dev.h>
3939
#include <linux/security.h>
4040
#include <linux/xattr.h>
41+
#include <linux/fscrypto.h>
4142
#include "ubifs-media.h"
4243

4344
/* Version of this UBIFS implementation */
@@ -1724,7 +1725,7 @@ int ubifs_update_time(struct inode *inode, struct timespec *time, int flags);
17241725
#endif
17251726

17261727
/* dir.c */
1727-
struct inode *ubifs_new_inode(struct ubifs_info *c, const struct inode *dir,
1728+
struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
17281729
umode_t mode);
17291730
int ubifs_getattr(struct vfsmount *mnt, struct dentry *dentry,
17301731
struct kstat *stat);
@@ -1773,10 +1774,44 @@ void ubifs_compress(const struct ubifs_info *c, const void *in_buf, int in_len,
17731774
int ubifs_decompress(const struct ubifs_info *c, const void *buf, int len,
17741775
void *out, int *out_len, int compr_type);
17751776

1777+
extern struct fscrypt_operations ubifs_crypt_operations;
1778+
17761779
#include "debug.h"
17771780
#include "misc.h"
17781781
#include "key.h"
17791782

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+
1808+
static 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+
17801815
/* Normal UBIFS messages */
17811816
__printf(2, 3)
17821817
void ubifs_msg(const struct ubifs_info *c, const char *fmt, ...);

fs/ubifs/xattr.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
158158
host_ui->xattr_size += CALC_XATTR_BYTES(size);
159159
host_ui->xattr_names += nm->len;
160160

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+
161170
err = ubifs_jnl_update(c, host, nm, inode, 0, 1);
162171
if (err)
163172
goto out_cancel;
@@ -173,6 +182,7 @@ static int create_xattr(struct ubifs_info *c, struct inode *host,
173182
host_ui->xattr_size -= CALC_DENT_SIZE(nm->len);
174183
host_ui->xattr_size -= CALC_XATTR_BYTES(size);
175184
host_ui->xattr_names -= nm->len;
185+
host_ui->flags &= ~UBIFS_CRYPT_FL;
176186
mutex_unlock(&host_ui->ui_mutex);
177187
out_free:
178188
make_bad_inode(inode);

0 commit comments

Comments
 (0)