Merge 6f5032a852 ("Merge tag 'fscrypt-for-linus' of git://git.kernel.org/pub/scm/fs/fscrypt/fscrypt") into android-mainline

Steps on the way to 5.10-rc1

Change-Id: Ifceecc1b9f94ea893484002c69aeb7b82d246f64
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Greg Kroah-Hartman 2020-10-23 11:56:31 +02:00
commit 9d77f49849
23 changed files with 537 additions and 447 deletions

View File

@ -351,9 +351,11 @@ void fscrypt_msg(const struct inode *inode, const char *level,
va_start(args, fmt); va_start(args, fmt);
vaf.fmt = fmt; vaf.fmt = fmt;
vaf.va = &args; vaf.va = &args;
if (inode) if (inode && inode->i_ino)
printk("%sfscrypt (%s, inode %lu): %pV\n", printk("%sfscrypt (%s, inode %lu): %pV\n",
level, inode->i_sb->s_id, inode->i_ino, &vaf); level, inode->i_sb->s_id, inode->i_ino, &vaf);
else if (inode)
printk("%sfscrypt (%s): %pV\n", level, inode->i_sb->s_id, &vaf);
else else
printk("%sfscrypt: %pV\n", level, &vaf); printk("%sfscrypt: %pV\n", level, &vaf);
va_end(args); va_end(args);

View File

@ -61,15 +61,6 @@ struct fscrypt_nokey_name {
*/ */
#define FSCRYPT_NOKEY_NAME_MAX offsetofend(struct fscrypt_nokey_name, sha256) #define FSCRYPT_NOKEY_NAME_MAX offsetofend(struct fscrypt_nokey_name, sha256)
static void fscrypt_do_sha256(const u8 *data, unsigned int data_len, u8 *result)
{
struct sha256_state sctx;
sha256_init(&sctx);
sha256_update(&sctx, data, data_len);
sha256_final(&sctx, result);
}
static inline bool fscrypt_is_dot_dotdot(const struct qstr *str) static inline bool fscrypt_is_dot_dotdot(const struct qstr *str)
{ {
if (str->len == 1 && str->name[0] == '.') if (str->len == 1 && str->name[0] == '.')
@ -242,11 +233,11 @@ static int base64_decode(const char *src, int len, u8 *dst)
return cp - dst; return cp - dst;
} }
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
u32 max_len, u32 *encrypted_len_ret) u32 orig_len, u32 max_len,
u32 *encrypted_len_ret)
{ {
const struct fscrypt_info *ci = inode->i_crypt_info; int padding = 4 << (fscrypt_policy_flags(policy) &
int padding = 4 << (fscrypt_policy_flags(&ci->ci_policy) &
FSCRYPT_POLICY_FLAGS_PAD_MASK); FSCRYPT_POLICY_FLAGS_PAD_MASK);
u32 encrypted_len; u32 encrypted_len;
@ -260,8 +251,6 @@ bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
/** /**
* fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames * fscrypt_fname_alloc_buffer() - allocate a buffer for presented filenames
* @inode: inode of the parent directory (for regular filenames)
* or of the symlink (for symlink targets)
* @max_encrypted_len: maximum length of encrypted filenames the buffer will be * @max_encrypted_len: maximum length of encrypted filenames the buffer will be
* used to present * used to present
* @crypto_str: (output) buffer to allocate * @crypto_str: (output) buffer to allocate
@ -271,8 +260,7 @@ bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
* *
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
int fscrypt_fname_alloc_buffer(const struct inode *inode, int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
u32 max_encrypted_len,
struct fscrypt_str *crypto_str) struct fscrypt_str *crypto_str)
{ {
const u32 max_encoded_len = BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX); const u32 max_encoded_len = BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX);
@ -369,9 +357,9 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
} else { } else {
memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes)); memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes));
/* Compute strong hash of remaining part of name. */ /* Compute strong hash of remaining part of name. */
fscrypt_do_sha256(&iname->name[sizeof(nokey_name.bytes)], sha256(&iname->name[sizeof(nokey_name.bytes)],
iname->len - sizeof(nokey_name.bytes), iname->len - sizeof(nokey_name.bytes),
nokey_name.sha256); nokey_name.sha256);
size = FSCRYPT_NOKEY_NAME_MAX; size = FSCRYPT_NOKEY_NAME_MAX;
} }
oname->len = base64_encode((const u8 *)&nokey_name, size, oname->name); oname->len = base64_encode((const u8 *)&nokey_name, size, oname->name);
@ -394,9 +382,9 @@ EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
* directory's encryption key, then @iname is the plaintext, so we encrypt it to * directory's encryption key, then @iname is the plaintext, so we encrypt it to
* get the disk_name. * get the disk_name.
* *
* Else, for keyless @lookup operations, @iname is the presented ciphertext, so * Else, for keyless @lookup operations, @iname should be a no-key name, so we
* we decode it to get the fscrypt_nokey_name. Non-@lookup operations will be * decode it to get the struct fscrypt_nokey_name. Non-@lookup operations will
* impossible in this case, so we fail them with ENOKEY. * be impossible in this case, so we fail them with ENOKEY.
* *
* If successful, fscrypt_free_filename() must be called later to clean up. * If successful, fscrypt_free_filename() must be called later to clean up.
* *
@ -421,7 +409,8 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
return ret; return ret;
if (fscrypt_has_encryption_key(dir)) { if (fscrypt_has_encryption_key(dir)) {
if (!fscrypt_fname_encrypted_size(dir, iname->len, if (!fscrypt_fname_encrypted_size(&dir->i_crypt_info->ci_policy,
iname->len,
dir->i_sb->s_cop->max_namelen, dir->i_sb->s_cop->max_namelen,
&fname->crypto_buf.len)) &fname->crypto_buf.len))
return -ENAMETOOLONG; return -ENAMETOOLONG;
@ -440,7 +429,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
} }
if (!lookup) if (!lookup)
return -ENOKEY; return -ENOKEY;
fname->is_ciphertext_name = true; fname->is_nokey_name = true;
/* /*
* We don't have the key and we are doing a lookup; decode the * We don't have the key and we are doing a lookup; decode the
@ -499,7 +488,7 @@ bool fscrypt_match_name(const struct fscrypt_name *fname,
{ {
const struct fscrypt_nokey_name *nokey_name = const struct fscrypt_nokey_name *nokey_name =
(const void *)fname->crypto_buf.name; (const void *)fname->crypto_buf.name;
u8 sha256[SHA256_DIGEST_SIZE]; u8 digest[SHA256_DIGEST_SIZE];
if (likely(fname->disk_name.name)) { if (likely(fname->disk_name.name)) {
if (de_name_len != fname->disk_name.len) if (de_name_len != fname->disk_name.len)
@ -510,9 +499,9 @@ bool fscrypt_match_name(const struct fscrypt_name *fname,
return false; return false;
if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes))) if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes)))
return false; return false;
fscrypt_do_sha256(&de_name[sizeof(nokey_name->bytes)], sha256(&de_name[sizeof(nokey_name->bytes)],
de_name_len - sizeof(nokey_name->bytes), sha256); de_name_len - sizeof(nokey_name->bytes), digest);
return !memcmp(sha256, nokey_name->sha256, sizeof(sha256)); return !memcmp(digest, nokey_name->sha256, sizeof(digest));
} }
EXPORT_SYMBOL_GPL(fscrypt_match_name); EXPORT_SYMBOL_GPL(fscrypt_match_name);
@ -549,17 +538,17 @@ int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags)
/* /*
* Plaintext names are always valid, since fscrypt doesn't support * Plaintext names are always valid, since fscrypt doesn't support
* reverting to ciphertext names without evicting the directory's inode * reverting to no-key names without evicting the directory's inode
* -- which implies eviction of the dentries in the directory. * -- which implies eviction of the dentries in the directory.
*/ */
if (!(dentry->d_flags & DCACHE_ENCRYPTED_NAME)) if (!(dentry->d_flags & DCACHE_NOKEY_NAME))
return 1; return 1;
/* /*
* Ciphertext name; valid if the directory's key is still unavailable. * No-key name; valid if the directory's key is still unavailable.
* *
* Although fscrypt forbids rename() on ciphertext names, we still must * Although fscrypt forbids rename() on no-key names, we still must use
* use dget_parent() here rather than use ->d_parent directly. That's * dget_parent() here rather than use ->d_parent directly. That's
* because a corrupted fs image may contain directory hard links, which * because a corrupted fs image may contain directory hard links, which
* the VFS handles by moving the directory's dentry tree in the dcache * the VFS handles by moving the directory's dentry tree in the dcache
* each time ->lookup() finds the directory and it already has a dentry * each time ->lookup() finds the directory and it already has a dentry

View File

@ -99,7 +99,6 @@ static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx)
return NULL; return NULL;
} }
#undef fscrypt_policy
union fscrypt_policy { union fscrypt_policy {
u8 version; u8 version;
struct fscrypt_policy_v1 v1; struct fscrypt_policy_v1 v1;
@ -294,8 +293,9 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
/* fname.c */ /* fname.c */
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname, int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
u8 *out, unsigned int olen); u8 *out, unsigned int olen);
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len, bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
u32 max_len, u32 *encrypted_len_ret); u32 orig_len, u32 max_len,
u32 *encrypted_len_ret);
/* hkdf.c */ /* hkdf.c */
@ -603,6 +603,9 @@ int fscrypt_set_per_file_enc_key(struct fscrypt_info *ci, const u8 *raw_key);
int fscrypt_derive_dirhash_key(struct fscrypt_info *ci, int fscrypt_derive_dirhash_key(struct fscrypt_info *ci,
const struct fscrypt_master_key *mk); const struct fscrypt_master_key *mk);
void fscrypt_hash_inode_number(struct fscrypt_info *ci,
const struct fscrypt_master_key *mk);
/* keysetup_v1.c */ /* keysetup_v1.c */
void fscrypt_put_direct_key(struct fscrypt_direct_key *dk); void fscrypt_put_direct_key(struct fscrypt_direct_key *dk);
@ -621,5 +624,6 @@ bool fscrypt_supported_policy(const union fscrypt_policy *policy_u,
int fscrypt_policy_from_context(union fscrypt_policy *policy_u, int fscrypt_policy_from_context(union fscrypt_policy *policy_u,
const union fscrypt_context *ctx_u, const union fscrypt_context *ctx_u,
int ctx_size); int ctx_size);
const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir);
#endif /* _FSCRYPT_PRIVATE_H */ #endif /* _FSCRYPT_PRIVATE_H */

View File

@ -60,8 +60,8 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
if (err) if (err)
return err; return err;
/* ... in case we looked up ciphertext name before key was added */ /* ... in case we looked up no-key name before key was added */
if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) if (dentry->d_flags & DCACHE_NOKEY_NAME)
return -ENOKEY; return -ENOKEY;
if (!fscrypt_has_permitted_context(dir, inode)) if (!fscrypt_has_permitted_context(dir, inode))
@ -85,9 +85,8 @@ int __fscrypt_prepare_rename(struct inode *old_dir, struct dentry *old_dentry,
if (err) if (err)
return err; return err;
/* ... in case we looked up ciphertext name(s) before key was added */ /* ... in case we looked up no-key name(s) before key was added */
if ((old_dentry->d_flags | new_dentry->d_flags) & if ((old_dentry->d_flags | new_dentry->d_flags) & DCACHE_NOKEY_NAME)
DCACHE_ENCRYPTED_NAME)
return -ENOKEY; return -ENOKEY;
if (old_dir != new_dir) { if (old_dir != new_dir) {
@ -114,9 +113,9 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
if (err && err != -ENOENT) if (err && err != -ENOENT)
return err; return err;
if (fname->is_ciphertext_name) { if (fname->is_nokey_name) {
spin_lock(&dentry->d_lock); spin_lock(&dentry->d_lock);
dentry->d_flags |= DCACHE_ENCRYPTED_NAME; dentry->d_flags |= DCACHE_NOKEY_NAME;
spin_unlock(&dentry->d_lock); spin_unlock(&dentry->d_lock);
} }
return err; return err;
@ -165,26 +164,51 @@ int fscrypt_prepare_setflags(struct inode *inode,
return 0; return 0;
} }
int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, /**
unsigned int max_len, * fscrypt_prepare_symlink() - prepare to create a possibly-encrypted symlink
struct fscrypt_str *disk_link) * @dir: directory in which the symlink is being created
* @target: plaintext symlink target
* @len: length of @target excluding null terminator
* @max_len: space the filesystem has available to store the symlink target
* @disk_link: (out) the on-disk symlink target being prepared
*
* This function computes the size the symlink target will require on-disk,
* stores it in @disk_link->len, and validates it against @max_len. An
* encrypted symlink may be longer than the original.
*
* Additionally, @disk_link->name is set to @target if the symlink will be
* unencrypted, but left NULL if the symlink will be encrypted. For encrypted
* symlinks, the filesystem must call fscrypt_encrypt_symlink() to create the
* on-disk target later. (The reason for the two-step process is that some
* filesystems need to know the size of the symlink target before creating the
* inode, e.g. to determine whether it will be a "fast" or "slow" symlink.)
*
* Return: 0 on success, -ENAMETOOLONG if the symlink target is too long,
* -ENOKEY if the encryption key is missing, or another -errno code if a problem
* occurred while setting up the encryption key.
*/
int fscrypt_prepare_symlink(struct inode *dir, const char *target,
unsigned int len, unsigned int max_len,
struct fscrypt_str *disk_link)
{ {
int err; const union fscrypt_policy *policy;
/* /*
* To calculate the size of the encrypted symlink target we need to know * To calculate the size of the encrypted symlink target we need to know
* the amount of NUL padding, which is determined by the flags set in * the amount of NUL padding, which is determined by the flags set in
* the encryption policy which will be inherited from the directory. * the encryption policy which will be inherited from the directory.
* The easiest way to get access to this is to just load the directory's
* fscrypt_info, since we'll need it to create the dir_entry anyway.
*
* Note: in test_dummy_encryption mode, @dir may be unencrypted.
*/ */
err = fscrypt_get_encryption_info(dir); policy = fscrypt_policy_to_inherit(dir);
if (err) if (policy == NULL) {
return err; /* Not encrypted */
if (!fscrypt_has_encryption_key(dir)) disk_link->name = (unsigned char *)target;
return -ENOKEY; disk_link->len = len + 1;
if (disk_link->len > max_len)
return -ENAMETOOLONG;
return 0;
}
if (IS_ERR(policy))
return PTR_ERR(policy);
/* /*
* Calculate the size of the encrypted symlink and verify it won't * Calculate the size of the encrypted symlink and verify it won't
@ -197,7 +221,7 @@ int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
* counting it (even though it is meaningless for ciphertext) is simpler * counting it (even though it is meaningless for ciphertext) is simpler
* for now since filesystems will assume it is there and subtract it. * for now since filesystems will assume it is there and subtract it.
*/ */
if (!fscrypt_fname_encrypted_size(dir, len, if (!fscrypt_fname_encrypted_size(policy, len,
max_len - sizeof(struct fscrypt_symlink_data), max_len - sizeof(struct fscrypt_symlink_data),
&disk_link->len)) &disk_link->len))
return -ENAMETOOLONG; return -ENAMETOOLONG;
@ -206,7 +230,7 @@ int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
disk_link->name = NULL; disk_link->name = NULL;
return 0; return 0;
} }
EXPORT_SYMBOL_GPL(__fscrypt_prepare_symlink); EXPORT_SYMBOL_GPL(fscrypt_prepare_symlink);
int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
unsigned int len, struct fscrypt_str *disk_link) unsigned int len, struct fscrypt_str *disk_link)
@ -216,9 +240,13 @@ int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
struct fscrypt_symlink_data *sd; struct fscrypt_symlink_data *sd;
unsigned int ciphertext_len; unsigned int ciphertext_len;
err = fscrypt_require_key(inode); /*
if (err) * fscrypt_prepare_new_inode() should have already set up the new
return err; * symlink inode's encryption key. We don't wait until now to do it,
* since we may be in a filesystem transaction now.
*/
if (WARN_ON_ONCE(!fscrypt_has_encryption_key(inode)))
return -ENOKEY;
if (disk_link->name) { if (disk_link->name) {
/* filesystem-provided buffer */ /* filesystem-provided buffer */
@ -318,7 +346,7 @@ const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
if (cstr.len + sizeof(*sd) - 1 > max_size) if (cstr.len + sizeof(*sd) - 1 > max_size)
return ERR_PTR(-EUCLEAN); return ERR_PTR(-EUCLEAN);
err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr); err = fscrypt_fname_alloc_buffer(cstr.len, &pstr);
if (err) if (err)
return ERR_PTR(err); return ERR_PTR(err);

View File

@ -110,7 +110,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci,
crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci); crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci);
crypto_cfg.is_hw_wrapped = is_hw_wrapped_key; crypto_cfg.is_hw_wrapped = is_hw_wrapped_key;
num_devs = fscrypt_get_num_devices(sb); num_devs = fscrypt_get_num_devices(sb);
devs = kmalloc_array(num_devs, sizeof(*devs), GFP_NOFS); devs = kmalloc_array(num_devs, sizeof(*devs), GFP_KERNEL);
if (!devs) if (!devs)
return -ENOMEM; return -ENOMEM;
fscrypt_get_devices(sb, num_devs, devs); fscrypt_get_devices(sb, num_devs, devs);
@ -141,9 +141,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
struct fscrypt_blk_crypto_key *blk_key; struct fscrypt_blk_crypto_key *blk_key;
int err; int err;
int i; int i;
unsigned int flags;
blk_key = kzalloc(struct_size(blk_key, devs, num_devs), GFP_NOFS); blk_key = kzalloc(struct_size(blk_key, devs, num_devs), GFP_KERNEL);
if (!blk_key) if (!blk_key)
return -ENOMEM; return -ENOMEM;
@ -176,10 +175,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
} }
queue_refs++; queue_refs++;
flags = memalloc_nofs_save();
err = blk_crypto_start_using_key(&blk_key->base, err = blk_crypto_start_using_key(&blk_key->base,
blk_key->devs[i]); blk_key->devs[i]);
memalloc_nofs_restore(flags);
if (err) { if (err) {
fscrypt_err(inode, fscrypt_err(inode,
"error %d starting to use blk-crypto", err); "error %d starting to use blk-crypto", err);

View File

@ -847,6 +847,7 @@ static int check_for_busy_inodes(struct super_block *sb,
struct list_head *pos; struct list_head *pos;
size_t busy_count = 0; size_t busy_count = 0;
unsigned long ino; unsigned long ino;
char ino_str[50] = "";
spin_lock(&mk->mk_decrypted_inodes_lock); spin_lock(&mk->mk_decrypted_inodes_lock);
@ -868,11 +869,15 @@ static int check_for_busy_inodes(struct super_block *sb,
} }
spin_unlock(&mk->mk_decrypted_inodes_lock); spin_unlock(&mk->mk_decrypted_inodes_lock);
/* If the inode is currently being created, ino may still be 0. */
if (ino)
snprintf(ino_str, sizeof(ino_str), ", including ino %lu", ino);
fscrypt_warn(NULL, fscrypt_warn(NULL,
"%s: %zu inode(s) still busy after removing key with %s %*phN, including ino %lu", "%s: %zu inode(s) still busy after removing key with %s %*phN%s",
sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec), sb->s_id, busy_count, master_key_spec_type(&mk->mk_spec),
master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u, master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u,
ino); ino_str);
return -EBUSY; return -EBUSY;
} }

View File

@ -10,6 +10,7 @@
#include <crypto/skcipher.h> #include <crypto/skcipher.h>
#include <linux/key.h> #include <linux/key.h>
#include <linux/random.h>
#include "fscrypt_private.h" #include "fscrypt_private.h"
@ -253,6 +254,16 @@ int fscrypt_derive_dirhash_key(struct fscrypt_info *ci,
return 0; return 0;
} }
void fscrypt_hash_inode_number(struct fscrypt_info *ci,
const struct fscrypt_master_key *mk)
{
WARN_ON(ci->ci_inode->i_ino == 0);
WARN_ON(!mk->mk_ino_hash_key_initialized);
ci->ci_hashed_ino = (u32)siphash_1u64(ci->ci_inode->i_ino,
&mk->mk_ino_hash_key);
}
static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci, static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci,
struct fscrypt_master_key *mk) struct fscrypt_master_key *mk)
{ {
@ -285,13 +296,20 @@ static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci,
return err; return err;
} }
ci->ci_hashed_ino = (u32)siphash_1u64(ci->ci_inode->i_ino, /*
&mk->mk_ino_hash_key); * New inodes may not have an inode number assigned yet.
* Hashing their inode number is delayed until later.
*/
if (ci->ci_inode->i_ino == 0)
WARN_ON(!(ci->ci_inode->i_state & I_CREATING));
else
fscrypt_hash_inode_number(ci, mk);
return 0; return 0;
} }
static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci, static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci,
struct fscrypt_master_key *mk) struct fscrypt_master_key *mk,
bool need_dirhash_key)
{ {
int err; int err;
@ -345,7 +363,7 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci,
return err; return err;
/* Derive a secret dirhash key for directories that need it. */ /* Derive a secret dirhash key for directories that need it. */
if (S_ISDIR(ci->ci_inode->i_mode) && IS_CASEFOLDED(ci->ci_inode)) { if (need_dirhash_key) {
err = fscrypt_derive_dirhash_key(ci, mk); err = fscrypt_derive_dirhash_key(ci, mk);
if (err) if (err)
return err; return err;
@ -365,6 +383,7 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci,
* key being removed with a new inode starting to use it. * key being removed with a new inode starting to use it.
*/ */
static int setup_file_encryption_key(struct fscrypt_info *ci, static int setup_file_encryption_key(struct fscrypt_info *ci,
bool need_dirhash_key,
struct key **master_key_ret) struct key **master_key_ret)
{ {
struct key *key; struct key *key;
@ -443,7 +462,7 @@ static int setup_file_encryption_key(struct fscrypt_info *ci,
err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw); err = fscrypt_setup_v1_file_key(ci, mk->mk_secret.raw);
break; break;
case FSCRYPT_POLICY_V2: case FSCRYPT_POLICY_V2:
err = fscrypt_setup_v2_file_key(ci, mk); err = fscrypt_setup_v2_file_key(ci, mk, need_dirhash_key);
break; break;
default: default:
WARN_ON(1); WARN_ON(1);
@ -497,57 +516,28 @@ static void put_crypt_info(struct fscrypt_info *ci)
kmem_cache_free(fscrypt_info_cachep, ci); kmem_cache_free(fscrypt_info_cachep, ci);
} }
int fscrypt_get_encryption_info(struct inode *inode) static int
fscrypt_setup_encryption_info(struct inode *inode,
const union fscrypt_policy *policy,
const u8 nonce[FSCRYPT_FILE_NONCE_SIZE],
bool need_dirhash_key)
{ {
struct fscrypt_info *crypt_info; struct fscrypt_info *crypt_info;
union fscrypt_context ctx;
struct fscrypt_mode *mode; struct fscrypt_mode *mode;
struct key *master_key = NULL; struct key *master_key = NULL;
int res; int res;
if (fscrypt_has_encryption_key(inode))
return 0;
res = fscrypt_initialize(inode->i_sb->s_cop->flags); res = fscrypt_initialize(inode->i_sb->s_cop->flags);
if (res) if (res)
return res; return res;
res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx)); crypt_info = kmem_cache_zalloc(fscrypt_info_cachep, GFP_KERNEL);
if (res < 0) {
const union fscrypt_context *dummy_ctx =
fscrypt_get_dummy_context(inode->i_sb);
if (IS_ENCRYPTED(inode) || !dummy_ctx) {
fscrypt_warn(inode,
"Error %d getting encryption context",
res);
return res;
}
/* Fake up a context for an unencrypted directory */
res = fscrypt_context_size(dummy_ctx);
memcpy(&ctx, dummy_ctx, res);
}
crypt_info = kmem_cache_zalloc(fscrypt_info_cachep, GFP_NOFS);
if (!crypt_info) if (!crypt_info)
return -ENOMEM; return -ENOMEM;
crypt_info->ci_inode = inode; crypt_info->ci_inode = inode;
crypt_info->ci_policy = *policy;
res = fscrypt_policy_from_context(&crypt_info->ci_policy, &ctx, res); memcpy(crypt_info->ci_nonce, nonce, FSCRYPT_FILE_NONCE_SIZE);
if (res) {
fscrypt_warn(inode,
"Unrecognized or corrupt encryption context");
goto out;
}
memcpy(crypt_info->ci_nonce, fscrypt_context_nonce(&ctx),
FSCRYPT_FILE_NONCE_SIZE);
if (!fscrypt_supported_policy(&crypt_info->ci_policy, inode)) {
res = -EINVAL;
goto out;
}
mode = select_encryption_mode(&crypt_info->ci_policy, inode); mode = select_encryption_mode(&crypt_info->ci_policy, inode);
if (IS_ERR(mode)) { if (IS_ERR(mode)) {
@ -557,13 +547,14 @@ int fscrypt_get_encryption_info(struct inode *inode)
WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE); WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
crypt_info->ci_mode = mode; crypt_info->ci_mode = mode;
res = setup_file_encryption_key(crypt_info, &master_key); res = setup_file_encryption_key(crypt_info, need_dirhash_key,
&master_key);
if (res) if (res)
goto out; goto out;
/* /*
* Multiple tasks may race to set ->i_crypt_info, so use * For existing inodes, multiple tasks may race to set ->i_crypt_info.
* cmpxchg_release(). This pairs with the smp_load_acquire() in * So use cmpxchg_release(). This pairs with the smp_load_acquire() in
* fscrypt_get_info(). I.e., here we publish ->i_crypt_info with a * fscrypt_get_info(). I.e., here we publish ->i_crypt_info with a
* RELEASE barrier so that other tasks can ACQUIRE it. * RELEASE barrier so that other tasks can ACQUIRE it.
*/ */
@ -593,13 +584,112 @@ int fscrypt_get_encryption_info(struct inode *inode)
up_read(&mk->mk_secret_sem); up_read(&mk->mk_secret_sem);
key_put(master_key); key_put(master_key);
} }
if (res == -ENOKEY)
res = 0;
put_crypt_info(crypt_info); put_crypt_info(crypt_info);
return res; return res;
} }
/**
* fscrypt_get_encryption_info() - set up an inode's encryption key
* @inode: the inode to set up the key for. Must be encrypted.
*
* Set up ->i_crypt_info, if it hasn't already been done.
*
* Note: unless ->i_crypt_info is already set, this isn't %GFP_NOFS-safe. So
* generally this shouldn't be called from within a filesystem transaction.
*
* Return: 0 if ->i_crypt_info was set or was already set, *or* if the
* encryption key is unavailable. (Use fscrypt_has_encryption_key() to
* distinguish these cases.) Also can return another -errno code.
*/
int fscrypt_get_encryption_info(struct inode *inode)
{
int res;
union fscrypt_context ctx;
union fscrypt_policy policy;
if (fscrypt_has_encryption_key(inode))
return 0;
res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
if (res < 0) {
fscrypt_warn(inode, "Error %d getting encryption context", res);
return res;
}
res = fscrypt_policy_from_context(&policy, &ctx, res);
if (res) {
fscrypt_warn(inode,
"Unrecognized or corrupt encryption context");
return res;
}
if (!fscrypt_supported_policy(&policy, inode))
return -EINVAL;
res = fscrypt_setup_encryption_info(inode, &policy,
fscrypt_context_nonce(&ctx),
IS_CASEFOLDED(inode) &&
S_ISDIR(inode->i_mode));
if (res == -ENOKEY)
res = 0;
return res;
}
EXPORT_SYMBOL(fscrypt_get_encryption_info); EXPORT_SYMBOL(fscrypt_get_encryption_info);
/**
* fscrypt_prepare_new_inode() - prepare to create a new inode in a directory
* @dir: a possibly-encrypted directory
* @inode: the new inode. ->i_mode must be set already.
* ->i_ino doesn't need to be set yet.
* @encrypt_ret: (output) set to %true if the new inode will be encrypted
*
* If the directory is encrypted, set up its ->i_crypt_info in preparation for
* encrypting the name of the new file. Also, if the new inode will be
* encrypted, set up its ->i_crypt_info and set *encrypt_ret=true.
*
* This isn't %GFP_NOFS-safe, and therefore it should be called before starting
* any filesystem transaction to create the inode. For this reason, ->i_ino
* isn't required to be set yet, as the filesystem may not have set it yet.
*
* This doesn't persist the new inode's encryption context. That still needs to
* be done later by calling fscrypt_set_context().
*
* Return: 0 on success, -ENOKEY if the encryption key is missing, or another
* -errno code
*/
int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
bool *encrypt_ret)
{
const union fscrypt_policy *policy;
u8 nonce[FSCRYPT_FILE_NONCE_SIZE];
policy = fscrypt_policy_to_inherit(dir);
if (policy == NULL)
return 0;
if (IS_ERR(policy))
return PTR_ERR(policy);
if (WARN_ON_ONCE(inode->i_mode == 0))
return -EINVAL;
/*
* Only regular files, directories, and symlinks are encrypted.
* Special files like device nodes and named pipes aren't.
*/
if (!S_ISREG(inode->i_mode) &&
!S_ISDIR(inode->i_mode) &&
!S_ISLNK(inode->i_mode))
return 0;
*encrypt_ret = true;
get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE);
return fscrypt_setup_encryption_info(inode, policy, nonce,
IS_CASEFOLDED(dir) &&
S_ISDIR(inode->i_mode));
}
EXPORT_SYMBOL_GPL(fscrypt_prepare_new_inode);
/** /**
* fscrypt_put_encryption_info() - free most of an inode's fscrypt data * fscrypt_put_encryption_info() - free most of an inode's fscrypt data
* @inode: an inode being evicted * @inode: an inode being evicted

View File

@ -60,7 +60,7 @@ static int derive_key_aes(const u8 *master_key,
goto out; goto out;
} }
crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS); crypto_skcipher_set_flags(tfm, CRYPTO_TFM_REQ_FORBID_WEAK_KEYS);
req = skcipher_request_alloc(tfm, GFP_NOFS); req = skcipher_request_alloc(tfm, GFP_KERNEL);
if (!req) { if (!req) {
res = -ENOMEM; res = -ENOMEM;
goto out; goto out;
@ -99,7 +99,7 @@ find_and_lock_process_key(const char *prefix,
const struct user_key_payload *ukp; const struct user_key_payload *ukp;
const struct fscrypt_key *payload; const struct fscrypt_key *payload;
description = kasprintf(GFP_NOFS, "%s%*phN", prefix, description = kasprintf(GFP_KERNEL, "%s%*phN", prefix,
FSCRYPT_KEY_DESCRIPTOR_SIZE, descriptor); FSCRYPT_KEY_DESCRIPTOR_SIZE, descriptor);
if (!description) if (!description)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
@ -228,7 +228,7 @@ fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key)
return dk; return dk;
/* Nope, allocate one. */ /* Nope, allocate one. */
dk = kzalloc(sizeof(*dk), GFP_NOFS); dk = kzalloc(sizeof(*dk), GFP_KERNEL);
if (!dk) if (!dk)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
refcount_set(&dk->dk_refcount, 1); refcount_set(&dk->dk_refcount, 1);
@ -273,7 +273,7 @@ static int setup_v1_file_key_derived(struct fscrypt_info *ci,
* This cannot be a stack buffer because it will be passed to the * This cannot be a stack buffer because it will be passed to the
* scatterlist crypto API during derive_key_aes(). * scatterlist crypto API during derive_key_aes().
*/ */
derived_key = kmalloc(ci->ci_mode->keysize, GFP_NOFS); derived_key = kmalloc(ci->ci_mode->keysize, GFP_KERNEL);
if (!derived_key) if (!derived_key)
return -ENOMEM; return -ENOMEM;

View File

@ -32,6 +32,14 @@ bool fscrypt_policies_equal(const union fscrypt_policy *policy1,
return !memcmp(policy1, policy2, fscrypt_policy_size(policy1)); return !memcmp(policy1, policy2, fscrypt_policy_size(policy1));
} }
static const union fscrypt_policy *
fscrypt_get_dummy_policy(struct super_block *sb)
{
if (!sb->s_cop->get_dummy_policy)
return NULL;
return sb->s_cop->get_dummy_policy(sb);
}
static bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode) static bool fscrypt_valid_enc_modes(u32 contents_mode, u32 filenames_mode)
{ {
if (contents_mode == FSCRYPT_MODE_AES_256_XTS && if (contents_mode == FSCRYPT_MODE_AES_256_XTS &&
@ -192,10 +200,15 @@ static bool fscrypt_supported_v2_policy(const struct fscrypt_policy_v2 *policy,
32, 32)) 32, 32))
return false; return false;
/*
* IV_INO_LBLK_32 hashes the inode number, so in principle it can
* support any ino_bits. However, currently the inode number is gotten
* from inode::i_ino which is 'unsigned long'. So for now the
* implementation limit is 32 bits.
*/
if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) && if ((policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32) &&
/* This uses hashed inode numbers, so ino_bits doesn't matter. */
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32", !supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32",
INT_MAX, 32)) 32, 32))
return false; return false;
if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) { if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) {
@ -231,18 +244,19 @@ bool fscrypt_supported_policy(const union fscrypt_policy *policy_u,
} }
/** /**
* fscrypt_new_context_from_policy() - create a new fscrypt_context from * fscrypt_new_context() - create a new fscrypt_context
* an fscrypt_policy
* @ctx_u: output context * @ctx_u: output context
* @policy_u: input policy * @policy_u: input policy
* @nonce: nonce to use
* *
* Create an fscrypt_context for an inode that is being assigned the given * Create an fscrypt_context for an inode that is being assigned the given
* encryption policy. A new nonce is randomly generated. * encryption policy. @nonce must be a new random nonce.
* *
* Return: the size of the new context in bytes. * Return: the size of the new context in bytes.
*/ */
static int fscrypt_new_context_from_policy(union fscrypt_context *ctx_u, static int fscrypt_new_context(union fscrypt_context *ctx_u,
const union fscrypt_policy *policy_u) const union fscrypt_policy *policy_u,
const u8 nonce[FSCRYPT_FILE_NONCE_SIZE])
{ {
memset(ctx_u, 0, sizeof(*ctx_u)); memset(ctx_u, 0, sizeof(*ctx_u));
@ -260,7 +274,7 @@ static int fscrypt_new_context_from_policy(union fscrypt_context *ctx_u,
memcpy(ctx->master_key_descriptor, memcpy(ctx->master_key_descriptor,
policy->master_key_descriptor, policy->master_key_descriptor,
sizeof(ctx->master_key_descriptor)); sizeof(ctx->master_key_descriptor));
get_random_bytes(ctx->nonce, sizeof(ctx->nonce)); memcpy(ctx->nonce, nonce, FSCRYPT_FILE_NONCE_SIZE);
return sizeof(*ctx); return sizeof(*ctx);
} }
case FSCRYPT_POLICY_V2: { case FSCRYPT_POLICY_V2: {
@ -276,7 +290,7 @@ static int fscrypt_new_context_from_policy(union fscrypt_context *ctx_u,
memcpy(ctx->master_key_identifier, memcpy(ctx->master_key_identifier,
policy->master_key_identifier, policy->master_key_identifier,
sizeof(ctx->master_key_identifier)); sizeof(ctx->master_key_identifier));
get_random_bytes(ctx->nonce, sizeof(ctx->nonce)); memcpy(ctx->nonce, nonce, FSCRYPT_FILE_NONCE_SIZE);
return sizeof(*ctx); return sizeof(*ctx);
} }
} }
@ -372,6 +386,7 @@ static int fscrypt_get_policy(struct inode *inode, union fscrypt_policy *policy)
static int set_encryption_policy(struct inode *inode, static int set_encryption_policy(struct inode *inode,
const union fscrypt_policy *policy) const union fscrypt_policy *policy)
{ {
u8 nonce[FSCRYPT_FILE_NONCE_SIZE];
union fscrypt_context ctx; union fscrypt_context ctx;
int ctxsize; int ctxsize;
int err; int err;
@ -409,7 +424,8 @@ static int set_encryption_policy(struct inode *inode,
return -EINVAL; return -EINVAL;
} }
ctxsize = fscrypt_new_context_from_policy(&ctx, policy); get_random_bytes(nonce, FSCRYPT_FILE_NONCE_SIZE);
ctxsize = fscrypt_new_context(&ctx, policy, nonce);
return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, NULL); return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, NULL);
} }
@ -620,86 +636,99 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
} }
EXPORT_SYMBOL(fscrypt_has_permitted_context); EXPORT_SYMBOL(fscrypt_has_permitted_context);
/*
* Return the encryption policy that new files in the directory will inherit, or
* NULL if none, or an ERR_PTR() on error. If the directory is encrypted, also
* ensure that its key is set up, so that the new filename can be encrypted.
*/
const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir)
{
int err;
if (IS_ENCRYPTED(dir)) {
err = fscrypt_require_key(dir);
if (err)
return ERR_PTR(err);
return &dir->i_crypt_info->ci_policy;
}
return fscrypt_get_dummy_policy(dir->i_sb);
}
/** /**
* fscrypt_inherit_context() - Sets a child context from its parent * fscrypt_set_context() - Set the fscrypt context of a new inode
* @parent: Parent inode from which the context is inherited. * @inode: a new inode
* @child: Child inode that inherits the context from @parent. * @fs_data: private data given by FS and passed to ->set_context()
* @fs_data: private data given by FS. *
* @preload: preload child i_crypt_info if true * This should be called after fscrypt_prepare_new_inode(), generally during a
* filesystem transaction. Everything here must be %GFP_NOFS-safe.
* *
* Return: 0 on success, -errno on failure * Return: 0 on success, -errno on failure
*/ */
int fscrypt_inherit_context(struct inode *parent, struct inode *child, int fscrypt_set_context(struct inode *inode, void *fs_data)
void *fs_data, bool preload)
{ {
struct fscrypt_info *ci = inode->i_crypt_info;
union fscrypt_context ctx; union fscrypt_context ctx;
int ctxsize; int ctxsize;
struct fscrypt_info *ci;
int res;
res = fscrypt_get_encryption_info(parent); /* fscrypt_prepare_new_inode() should have set up the key already. */
if (res < 0) if (WARN_ON_ONCE(!ci))
return res;
ci = fscrypt_get_info(parent);
if (ci == NULL)
return -ENOKEY; return -ENOKEY;
ctxsize = fscrypt_new_context_from_policy(&ctx, &ci->ci_policy);
BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE); BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE);
res = parent->i_sb->s_cop->set_context(child, &ctx, ctxsize, fs_data); ctxsize = fscrypt_new_context(&ctx, &ci->ci_policy, ci->ci_nonce);
if (res)
return res; /*
return preload ? fscrypt_get_encryption_info(child): 0; * This may be the first time the inode number is available, so do any
* delayed key setup that requires the inode number.
*/
if (ci->ci_policy.version == FSCRYPT_POLICY_V2 &&
(ci->ci_policy.v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) {
const struct fscrypt_master_key *mk =
ci->ci_master_key->payload.data[0];
fscrypt_hash_inode_number(ci, mk);
}
return inode->i_sb->s_cop->set_context(inode, &ctx, ctxsize, fs_data);
} }
EXPORT_SYMBOL(fscrypt_inherit_context); EXPORT_SYMBOL_GPL(fscrypt_set_context);
/** /**
* fscrypt_set_test_dummy_encryption() - handle '-o test_dummy_encryption' * fscrypt_set_test_dummy_encryption() - handle '-o test_dummy_encryption'
* @sb: the filesystem on which test_dummy_encryption is being specified * @sb: the filesystem on which test_dummy_encryption is being specified
* @arg: the argument to the test_dummy_encryption option. * @arg: the argument to the test_dummy_encryption option. May be NULL.
* If no argument was specified, then @arg->from == NULL. * @dummy_policy: the filesystem's current dummy policy (input/output, see
* @dummy_ctx: the filesystem's current dummy context (input/output, see below) * below)
* *
* Handle the test_dummy_encryption mount option by creating a dummy encryption * Handle the test_dummy_encryption mount option by creating a dummy encryption
* context, saving it in @dummy_ctx, and adding the corresponding dummy * policy, saving it in @dummy_policy, and adding the corresponding dummy
* encryption key to the filesystem. If the @dummy_ctx is already set, then * encryption key to the filesystem. If the @dummy_policy is already set, then
* instead validate that it matches @arg. Don't support changing it via * instead validate that it matches @arg. Don't support changing it via
* remount, as that is difficult to do safely. * remount, as that is difficult to do safely.
* *
* The reason we use an fscrypt_context rather than an fscrypt_policy is because * Return: 0 on success (dummy policy set, or the same policy is already set);
* we mustn't generate a new nonce each time we access a dummy-encrypted * -EEXIST if a different dummy policy is already set;
* directory, as that would change the way filenames are encrypted.
*
* Return: 0 on success (dummy context set, or the same context is already set);
* -EEXIST if a different dummy context is already set;
* or another -errno value. * or another -errno value.
*/ */
int fscrypt_set_test_dummy_encryption(struct super_block *sb, int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg,
const substring_t *arg, struct fscrypt_dummy_policy *dummy_policy)
struct fscrypt_dummy_context *dummy_ctx)
{ {
const char *argstr = "v2";
const char *argstr_to_free = NULL;
struct fscrypt_key_specifier key_spec = { 0 }; struct fscrypt_key_specifier key_spec = { 0 };
int version; int version;
union fscrypt_context *ctx = NULL; union fscrypt_policy *policy = NULL;
int err; int err;
if (arg->from) { if (!arg)
argstr = argstr_to_free = match_strdup(arg); arg = "v2";
if (!argstr)
return -ENOMEM;
}
if (!strcmp(argstr, "v1")) { if (!strcmp(arg, "v1")) {
version = FSCRYPT_CONTEXT_V1; version = FSCRYPT_POLICY_V1;
key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR; key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
memset(key_spec.u.descriptor, 0x42, memset(key_spec.u.descriptor, 0x42,
FSCRYPT_KEY_DESCRIPTOR_SIZE); FSCRYPT_KEY_DESCRIPTOR_SIZE);
} else if (!strcmp(argstr, "v2")) { } else if (!strcmp(arg, "v2")) {
version = FSCRYPT_CONTEXT_V2; version = FSCRYPT_POLICY_V2;
key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER; key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
/* key_spec.u.identifier gets filled in when adding the key */ /* key_spec.u.identifier gets filled in when adding the key */
} else { } else {
@ -707,21 +736,8 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
goto out; goto out;
} }
if (dummy_ctx->ctx) { policy = kzalloc(sizeof(*policy), GFP_KERNEL);
/* if (!policy) {
* Note: if we ever make test_dummy_encryption support
* specifying other encryption settings, such as the encryption
* modes, we'll need to compare those settings here.
*/
if (dummy_ctx->ctx->version == version)
err = 0;
else
err = -EEXIST;
goto out;
}
ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
if (!ctx) {
err = -ENOMEM; err = -ENOMEM;
goto out; goto out;
} }
@ -730,18 +746,18 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
if (err) if (err)
goto out; goto out;
ctx->version = version; policy->version = version;
switch (ctx->version) { switch (policy->version) {
case FSCRYPT_CONTEXT_V1: case FSCRYPT_POLICY_V1:
ctx->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; policy->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
ctx->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; policy->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
memcpy(ctx->v1.master_key_descriptor, key_spec.u.descriptor, memcpy(policy->v1.master_key_descriptor, key_spec.u.descriptor,
FSCRYPT_KEY_DESCRIPTOR_SIZE); FSCRYPT_KEY_DESCRIPTOR_SIZE);
break; break;
case FSCRYPT_CONTEXT_V2: case FSCRYPT_POLICY_V2:
ctx->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS; policy->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
ctx->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS; policy->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
memcpy(ctx->v2.master_key_identifier, key_spec.u.identifier, memcpy(policy->v2.master_key_identifier, key_spec.u.identifier,
FSCRYPT_KEY_IDENTIFIER_SIZE); FSCRYPT_KEY_IDENTIFIER_SIZE);
break; break;
default: default:
@ -749,12 +765,19 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
err = -EINVAL; err = -EINVAL;
goto out; goto out;
} }
dummy_ctx->ctx = ctx;
ctx = NULL; if (dummy_policy->policy) {
if (fscrypt_policies_equal(policy, dummy_policy->policy))
err = 0;
else
err = -EEXIST;
goto out;
}
dummy_policy->policy = policy;
policy = NULL;
err = 0; err = 0;
out: out:
kfree(ctx); kfree(policy);
kfree(argstr_to_free);
return err; return err;
} }
EXPORT_SYMBOL_GPL(fscrypt_set_test_dummy_encryption); EXPORT_SYMBOL_GPL(fscrypt_set_test_dummy_encryption);
@ -771,10 +794,16 @@ EXPORT_SYMBOL_GPL(fscrypt_set_test_dummy_encryption);
void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep,
struct super_block *sb) struct super_block *sb)
{ {
const union fscrypt_context *ctx = fscrypt_get_dummy_context(sb); const union fscrypt_policy *policy = fscrypt_get_dummy_policy(sb);
int vers;
if (!ctx) if (!policy)
return; return;
seq_printf(seq, "%ctest_dummy_encryption=v%d", sep, ctx->version);
vers = policy->version;
if (vers == FSCRYPT_POLICY_V1) /* Handle numbering quirk */
vers = 1;
seq_printf(seq, "%ctest_dummy_encryption=v%d", sep, vers);
} }
EXPORT_SYMBOL_GPL(fscrypt_show_test_dummy_encryption); EXPORT_SYMBOL_GPL(fscrypt_show_test_dummy_encryption);

View File

@ -169,7 +169,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
} }
if (IS_ENCRYPTED(inode)) { if (IS_ENCRYPTED(inode)) {
err = fscrypt_fname_alloc_buffer(inode, EXT4_NAME_LEN, &fstr); err = fscrypt_fname_alloc_buffer(EXT4_NAME_LEN, &fstr);
if (err < 0) if (err < 0)
return err; return err;
} }

View File

@ -1401,7 +1401,7 @@ struct ext4_super_block {
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */ #define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
#define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_ctx.ctx != NULL) #define DUMMY_ENCRYPTION_ENABLED(sbi) ((sbi)->s_dummy_enc_policy.policy != NULL)
#else #else
#define DUMMY_ENCRYPTION_ENABLED(sbi) (0) #define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
#endif #endif
@ -1584,8 +1584,8 @@ struct ext4_sb_info {
atomic_t s_warning_count; atomic_t s_warning_count;
atomic_t s_msg_count; atomic_t s_msg_count;
/* Encryption context for '-o test_dummy_encryption' */ /* Encryption policy for '-o test_dummy_encryption' */
struct fscrypt_dummy_context s_dummy_enc_ctx; struct fscrypt_dummy_policy s_dummy_enc_policy;
/* /*
* Barrier between writepages ops and changing any inode's JOURNAL_DATA * Barrier between writepages ops and changing any inode's JOURNAL_DATA

View File

@ -745,6 +745,53 @@ static int find_inode_bit(struct super_block *sb, ext4_group_t group,
return 1; return 1;
} }
static int ext4_xattr_credits_for_new_inode(struct inode *dir, mode_t mode,
bool encrypt)
{
struct super_block *sb = dir->i_sb;
int nblocks = 0;
#ifdef CONFIG_EXT4_FS_POSIX_ACL
struct posix_acl *p = get_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(p))
return PTR_ERR(p);
if (p) {
int acl_size = p->a_count * sizeof(ext4_acl_entry);
nblocks += (S_ISDIR(mode) ? 2 : 1) *
__ext4_xattr_set_credits(sb, NULL /* inode */,
NULL /* block_bh */, acl_size,
true /* is_create */);
posix_acl_release(p);
}
#endif
#ifdef CONFIG_SECURITY
{
int num_security_xattrs = 1;
#ifdef CONFIG_INTEGRITY
num_security_xattrs++;
#endif
/*
* We assume that security xattrs are never more than 1k.
* In practice they are under 128 bytes.
*/
nblocks += num_security_xattrs *
__ext4_xattr_set_credits(sb, NULL /* inode */,
NULL /* block_bh */, 1024,
true /* is_create */);
}
#endif
if (encrypt)
nblocks += __ext4_xattr_set_credits(sb,
NULL /* inode */,
NULL /* block_bh */,
FSCRYPT_SET_CONTEXT_MAX_SIZE,
true /* is_create */);
return nblocks;
}
/* /*
* There are two policies for allocating an inode. If the new inode is * There are two policies for allocating an inode. If the new inode is
* a directory, then a forward search is made for a block group with both * a directory, then a forward search is made for a block group with both
@ -775,7 +822,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
ext4_group_t i; ext4_group_t i;
ext4_group_t flex_group; ext4_group_t flex_group;
struct ext4_group_info *grp; struct ext4_group_info *grp;
int encrypt = 0; bool encrypt = false;
/* Cannot create files in a deleted directory */ /* Cannot create files in a deleted directory */
if (!dir || !dir->i_nlink) if (!dir || !dir->i_nlink)
@ -787,59 +834,6 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
if (unlikely(ext4_forced_shutdown(sbi))) if (unlikely(ext4_forced_shutdown(sbi)))
return ERR_PTR(-EIO); return ERR_PTR(-EIO);
if ((IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi)) &&
(S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode)) &&
!(i_flags & EXT4_EA_INODE_FL)) {
err = fscrypt_get_encryption_info(dir);
if (err)
return ERR_PTR(err);
if (!fscrypt_has_encryption_key(dir))
return ERR_PTR(-ENOKEY);
encrypt = 1;
}
if (!handle && sbi->s_journal && !(i_flags & EXT4_EA_INODE_FL)) {
#ifdef CONFIG_EXT4_FS_POSIX_ACL
struct posix_acl *p = get_acl(dir, ACL_TYPE_DEFAULT);
if (IS_ERR(p))
return ERR_CAST(p);
if (p) {
int acl_size = p->a_count * sizeof(ext4_acl_entry);
nblocks += (S_ISDIR(mode) ? 2 : 1) *
__ext4_xattr_set_credits(sb, NULL /* inode */,
NULL /* block_bh */, acl_size,
true /* is_create */);
posix_acl_release(p);
}
#endif
#ifdef CONFIG_SECURITY
{
int num_security_xattrs = 1;
#ifdef CONFIG_INTEGRITY
num_security_xattrs++;
#endif
/*
* We assume that security xattrs are never
* more than 1k. In practice they are under
* 128 bytes.
*/
nblocks += num_security_xattrs *
__ext4_xattr_set_credits(sb, NULL /* inode */,
NULL /* block_bh */, 1024,
true /* is_create */);
}
#endif
if (encrypt)
nblocks += __ext4_xattr_set_credits(sb,
NULL /* inode */, NULL /* block_bh */,
FSCRYPT_SET_CONTEXT_MAX_SIZE,
true /* is_create */);
}
ngroups = ext4_get_groups_count(sb); ngroups = ext4_get_groups_count(sb);
trace_ext4_request_inode(dir, mode); trace_ext4_request_inode(dir, mode);
inode = new_inode(sb); inode = new_inode(sb);
@ -869,10 +863,25 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
else else
ei->i_projid = make_kprojid(&init_user_ns, EXT4_DEF_PROJID); ei->i_projid = make_kprojid(&init_user_ns, EXT4_DEF_PROJID);
if (!(i_flags & EXT4_EA_INODE_FL)) {
err = fscrypt_prepare_new_inode(dir, inode, &encrypt);
if (err)
goto out;
}
err = dquot_initialize(inode); err = dquot_initialize(inode);
if (err) if (err)
goto out; goto out;
if (!handle && sbi->s_journal && !(i_flags & EXT4_EA_INODE_FL)) {
ret2 = ext4_xattr_credits_for_new_inode(dir, mode, encrypt);
if (ret2 < 0) {
err = ret2;
goto out;
}
nblocks += ret2;
}
if (!goal) if (!goal)
goal = sbi->s_inode_goal; goal = sbi->s_inode_goal;
@ -1165,7 +1174,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
* prevent its deduplication. * prevent its deduplication.
*/ */
if (encrypt) { if (encrypt) {
err = fscrypt_inherit_context(dir, inode, handle, true); err = fscrypt_set_context(inode, handle);
if (err) if (err)
goto fail_free_drop; goto fail_free_drop;
} }

View File

@ -667,8 +667,7 @@ static struct stats dx_show_leaf(struct inode *dir,
/* Directory is encrypted */ /* Directory is encrypted */
res = fscrypt_fname_alloc_buffer( res = fscrypt_fname_alloc_buffer(
dir, len, len, &fname_crypto_str);
&fname_crypto_str);
if (res) if (res)
printk(KERN_WARNING "Error " printk(KERN_WARNING "Error "
"allocating crypto " "allocating crypto "
@ -1042,8 +1041,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
brelse(bh); brelse(bh);
return err; return err;
} }
err = fscrypt_fname_alloc_buffer(dir, EXT4_NAME_LEN, err = fscrypt_fname_alloc_buffer(EXT4_NAME_LEN,
&fname_crypto_str); &fname_crypto_str);
if (err < 0) { if (err < 0) {
brelse(bh); brelse(bh);
return err; return err;

View File

@ -1104,7 +1104,7 @@ static void ext4_put_super(struct super_block *sb)
crypto_free_shash(sbi->s_chksum_driver); crypto_free_shash(sbi->s_chksum_driver);
kfree(sbi->s_blockgroup_lock); kfree(sbi->s_blockgroup_lock);
fs_put_dax(sbi->s_daxdev); fs_put_dax(sbi->s_daxdev);
fscrypt_free_dummy_context(&sbi->s_dummy_enc_ctx); fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
#ifdef CONFIG_UNICODE #ifdef CONFIG_UNICODE
utf8_unload(sb->s_encoding); utf8_unload(sb->s_encoding);
#endif #endif
@ -1392,10 +1392,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
return res; return res;
} }
static const union fscrypt_context * static const union fscrypt_policy *ext4_get_dummy_policy(struct super_block *sb)
ext4_get_dummy_context(struct super_block *sb)
{ {
return EXT4_SB(sb)->s_dummy_enc_ctx.ctx; return EXT4_SB(sb)->s_dummy_enc_policy.policy;
} }
static bool ext4_has_stable_inodes(struct super_block *sb) static bool ext4_has_stable_inodes(struct super_block *sb)
@ -1414,7 +1413,7 @@ static const struct fscrypt_operations ext4_cryptops = {
.key_prefix = "ext4:", .key_prefix = "ext4:",
.get_context = ext4_get_context, .get_context = ext4_get_context,
.set_context = ext4_set_context, .set_context = ext4_set_context,
.get_dummy_context = ext4_get_dummy_context, .get_dummy_policy = ext4_get_dummy_policy,
.empty_dir = ext4_empty_dir, .empty_dir = ext4_empty_dir,
.max_namelen = EXT4_NAME_LEN, .max_namelen = EXT4_NAME_LEN,
.has_stable_inodes = ext4_has_stable_inodes, .has_stable_inodes = ext4_has_stable_inodes,
@ -1888,12 +1887,13 @@ static int ext4_set_test_dummy_encryption(struct super_block *sb,
* needed to allow it to be set or changed during remount. We do allow * needed to allow it to be set or changed during remount. We do allow
* it to be specified during remount, but only if there is no change. * it to be specified during remount, but only if there is no change.
*/ */
if (is_remount && !sbi->s_dummy_enc_ctx.ctx) { if (is_remount && !sbi->s_dummy_enc_policy.policy) {
ext4_msg(sb, KERN_WARNING, ext4_msg(sb, KERN_WARNING,
"Can't set test_dummy_encryption on remount"); "Can't set test_dummy_encryption on remount");
return -1; return -1;
} }
err = fscrypt_set_test_dummy_encryption(sb, arg, &sbi->s_dummy_enc_ctx); err = fscrypt_set_test_dummy_encryption(sb, arg->from,
&sbi->s_dummy_enc_policy);
if (err) { if (err) {
if (err == -EEXIST) if (err == -EEXIST)
ext4_msg(sb, KERN_WARNING, ext4_msg(sb, KERN_WARNING,
@ -4924,7 +4924,7 @@ static int ext4_fill_super(struct super_block *sb, void *data, int silent)
for (i = 0; i < EXT4_MAXQUOTAS; i++) for (i = 0; i < EXT4_MAXQUOTAS; i++)
kfree(get_qf_name(sb, sbi, i)); kfree(get_qf_name(sb, sbi, i));
#endif #endif
fscrypt_free_dummy_context(&sbi->s_dummy_enc_ctx); fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
ext4_blkdev_remove(sbi); ext4_blkdev_remove(sbi);
brelse(bh); brelse(bh);
out_fail: out_fail:

View File

@ -113,7 +113,7 @@ static int __f2fs_setup_filename(const struct inode *dir,
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
fname->crypto_buf = crypt_name->crypto_buf; fname->crypto_buf = crypt_name->crypto_buf;
#endif #endif
if (crypt_name->is_ciphertext_name) { if (crypt_name->is_nokey_name) {
/* hash was decoded from the no-key name */ /* hash was decoded from the no-key name */
fname->hash = cpu_to_le32(crypt_name->hash); fname->hash = cpu_to_le32(crypt_name->hash);
} else { } else {
@ -583,7 +583,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
goto put_error; goto put_error;
if (IS_ENCRYPTED(inode)) { if (IS_ENCRYPTED(inode)) {
err = fscrypt_inherit_context(dir, inode, page, false); err = fscrypt_set_context(inode, page);
if (err) if (err)
goto put_error; goto put_error;
} }
@ -1074,7 +1074,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
if (err) if (err)
goto out; goto out;
err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, &fstr); err = fscrypt_fname_alloc_buffer(F2FS_NAME_LEN, &fstr);
if (err < 0) if (err < 0)
goto out; goto out;
} }

View File

@ -138,7 +138,7 @@ struct f2fs_mount_info {
int fsync_mode; /* fsync policy */ int fsync_mode; /* fsync policy */
int fs_mode; /* fs mode: LFS or ADAPTIVE */ int fs_mode; /* fs mode: LFS or ADAPTIVE */
int bggc_mode; /* bggc mode: off, on or sync */ int bggc_mode; /* bggc mode: off, on or sync */
struct fscrypt_dummy_context dummy_enc_ctx; /* test dummy encryption */ struct fscrypt_dummy_policy dummy_enc_policy; /* test dummy encryption */
block_t unusable_cap_perc; /* percentage for cap */ block_t unusable_cap_perc; /* percentage for cap */
block_t unusable_cap; /* Amount of space allowed to be block_t unusable_cap; /* Amount of space allowed to be
* unusable when disabling checkpoint * unusable when disabling checkpoint
@ -1317,13 +1317,6 @@ enum fsync_mode {
#define IS_IO_TRACED_PAGE(page) (0) #define IS_IO_TRACED_PAGE(page) (0)
#endif #endif
#ifdef CONFIG_FS_ENCRYPTION
#define DUMMY_ENCRYPTION_ENABLED(sbi) \
(unlikely(F2FS_OPTION(sbi).dummy_enc_ctx.ctx != NULL))
#else
#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
#endif
/* For compression */ /* For compression */
enum compress_algorithm_type { enum compress_algorithm_type {
COMPRESS_LZO, COMPRESS_LZO,
@ -4017,22 +4010,6 @@ static inline bool f2fs_lfs_mode(struct f2fs_sb_info *sbi)
return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS; return F2FS_OPTION(sbi).fs_mode == FS_MODE_LFS;
} }
static inline bool f2fs_may_encrypt(struct inode *dir, struct inode *inode)
{
#ifdef CONFIG_FS_ENCRYPTION
struct f2fs_sb_info *sbi = F2FS_I_SB(dir);
umode_t mode = inode->i_mode;
/*
* If the directory encrypted or dummy encryption enabled,
* then we should encrypt the inode.
*/
if (IS_ENCRYPTED(dir) || DUMMY_ENCRYPTION_ENABLED(sbi))
return (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode));
#endif
return false;
}
static inline bool f2fs_may_compress(struct inode *inode) static inline bool f2fs_may_compress(struct inode *inode)
{ {
if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) || if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||

View File

@ -28,6 +28,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
nid_t ino; nid_t ino;
struct inode *inode; struct inode *inode;
bool nid_free = false; bool nid_free = false;
bool encrypt = false;
int xattr_size = 0; int xattr_size = 0;
int err; int err;
@ -69,13 +70,17 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns, F2FS_I(inode)->i_projid = make_kprojid(&init_user_ns,
F2FS_DEF_PROJID); F2FS_DEF_PROJID);
err = fscrypt_prepare_new_inode(dir, inode, &encrypt);
if (err)
goto fail_drop;
err = dquot_initialize(inode); err = dquot_initialize(inode);
if (err) if (err)
goto fail_drop; goto fail_drop;
set_inode_flag(inode, FI_NEW_INODE); set_inode_flag(inode, FI_NEW_INODE);
if (f2fs_may_encrypt(dir, inode)) if (encrypt)
f2fs_set_encrypted_inode(inode); f2fs_set_encrypted_inode(inode);
if (f2fs_sb_has_extra_attr(sbi)) { if (f2fs_sb_has_extra_attr(sbi)) {

View File

@ -433,12 +433,12 @@ static int f2fs_set_test_dummy_encryption(struct super_block *sb,
* needed to allow it to be set or changed during remount. We do allow * needed to allow it to be set or changed during remount. We do allow
* it to be specified during remount, but only if there is no change. * it to be specified during remount, but only if there is no change.
*/ */
if (is_remount && !F2FS_OPTION(sbi).dummy_enc_ctx.ctx) { if (is_remount && !F2FS_OPTION(sbi).dummy_enc_policy.policy) {
f2fs_warn(sbi, "Can't set test_dummy_encryption on remount"); f2fs_warn(sbi, "Can't set test_dummy_encryption on remount");
return -EINVAL; return -EINVAL;
} }
err = fscrypt_set_test_dummy_encryption( err = fscrypt_set_test_dummy_encryption(
sb, arg, &F2FS_OPTION(sbi).dummy_enc_ctx); sb, arg->from, &F2FS_OPTION(sbi).dummy_enc_policy);
if (err) { if (err) {
if (err == -EEXIST) if (err == -EEXIST)
f2fs_warn(sbi, f2fs_warn(sbi,
@ -1275,7 +1275,7 @@ static void f2fs_put_super(struct super_block *sb)
for (i = 0; i < MAXQUOTAS; i++) for (i = 0; i < MAXQUOTAS; i++)
kfree(F2FS_OPTION(sbi).s_qf_names[i]); kfree(F2FS_OPTION(sbi).s_qf_names[i]);
#endif #endif
fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx); fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
destroy_percpu_info(sbi); destroy_percpu_info(sbi);
for (i = 0; i < NR_PAGE_TYPE; i++) for (i = 0; i < NR_PAGE_TYPE; i++)
kvfree(sbi->write_io[i]); kvfree(sbi->write_io[i]);
@ -2482,10 +2482,9 @@ static int f2fs_set_context(struct inode *inode, const void *ctx, size_t len,
ctx, len, fs_data, XATTR_CREATE); ctx, len, fs_data, XATTR_CREATE);
} }
static const union fscrypt_context * static const union fscrypt_policy *f2fs_get_dummy_policy(struct super_block *sb)
f2fs_get_dummy_context(struct super_block *sb)
{ {
return F2FS_OPTION(F2FS_SB(sb)).dummy_enc_ctx.ctx; return F2FS_OPTION(F2FS_SB(sb)).dummy_enc_policy.policy;
} }
static bool f2fs_has_stable_inodes(struct super_block *sb) static bool f2fs_has_stable_inodes(struct super_block *sb)
@ -2523,7 +2522,7 @@ static const struct fscrypt_operations f2fs_cryptops = {
.key_prefix = "f2fs:", .key_prefix = "f2fs:",
.get_context = f2fs_get_context, .get_context = f2fs_get_context,
.set_context = f2fs_set_context, .set_context = f2fs_set_context,
.get_dummy_context = f2fs_get_dummy_context, .get_dummy_policy = f2fs_get_dummy_policy,
.empty_dir = f2fs_empty_dir, .empty_dir = f2fs_empty_dir,
.max_namelen = F2FS_NAME_LEN, .max_namelen = F2FS_NAME_LEN,
.has_stable_inodes = f2fs_has_stable_inodes, .has_stable_inodes = f2fs_has_stable_inodes,
@ -3857,7 +3856,7 @@ static int f2fs_fill_super(struct super_block *sb, void *data, int silent)
for (i = 0; i < MAXQUOTAS; i++) for (i = 0; i < MAXQUOTAS; i++)
kfree(F2FS_OPTION(sbi).s_qf_names[i]); kfree(F2FS_OPTION(sbi).s_qf_names[i]);
#endif #endif
fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx); fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
kvfree(options); kvfree(options);
free_sb_buf: free_sb_buf:
kfree(raw_super); kfree(raw_super);

View File

@ -1481,7 +1481,7 @@ static const struct dentry_operations generic_encrypted_ci_dentry_ops = {
void generic_set_encrypted_ci_d_ops(struct inode *dir, struct dentry *dentry) void generic_set_encrypted_ci_d_ops(struct inode *dir, struct dentry *dentry)
{ {
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) { if (dentry->d_flags & DCACHE_NOKEY_NAME) {
#ifdef CONFIG_UNICODE #ifdef CONFIG_UNICODE
if (dir->i_sb->s_encoding) { if (dir->i_sb->s_encoding) {
d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops); d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops);

View File

@ -81,19 +81,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
struct ubifs_inode *ui; struct ubifs_inode *ui;
bool encrypted = false; bool encrypted = false;
if (IS_ENCRYPTED(dir)) {
err = fscrypt_get_encryption_info(dir);
if (err) {
ubifs_err(c, "fscrypt_get_encryption_info failed: %i", err);
return ERR_PTR(err);
}
if (!fscrypt_has_encryption_key(dir))
return ERR_PTR(-EPERM);
encrypted = true;
}
inode = new_inode(c->vfs_sb); inode = new_inode(c->vfs_sb);
ui = ubifs_inode(inode); ui = ubifs_inode(inode);
if (!inode) if (!inode)
@ -112,6 +99,12 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
current_time(inode); current_time(inode);
inode->i_mapping->nrpages = 0; inode->i_mapping->nrpages = 0;
err = fscrypt_prepare_new_inode(dir, inode, &encrypted);
if (err) {
ubifs_err(c, "fscrypt_prepare_new_inode failed: %i", err);
goto out_iput;
}
switch (mode & S_IFMT) { switch (mode & S_IFMT) {
case S_IFREG: case S_IFREG:
inode->i_mapping->a_ops = &ubifs_file_address_operations; inode->i_mapping->a_ops = &ubifs_file_address_operations;
@ -131,7 +124,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
case S_IFBLK: case S_IFBLK:
case S_IFCHR: case S_IFCHR:
inode->i_op = &ubifs_file_inode_operations; inode->i_op = &ubifs_file_inode_operations;
encrypted = false;
break; break;
default: default:
BUG(); BUG();
@ -151,9 +143,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
if (c->highest_inum >= INUM_WATERMARK) { if (c->highest_inum >= INUM_WATERMARK) {
spin_unlock(&c->cnt_lock); spin_unlock(&c->cnt_lock);
ubifs_err(c, "out of inode numbers"); ubifs_err(c, "out of inode numbers");
make_bad_inode(inode); err = -EINVAL;
iput(inode); goto out_iput;
return ERR_PTR(-EINVAL);
} }
ubifs_warn(c, "running out of inode numbers (current %lu, max %u)", ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
(unsigned long)c->highest_inum, INUM_WATERMARK); (unsigned long)c->highest_inum, INUM_WATERMARK);
@ -171,16 +162,19 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
spin_unlock(&c->cnt_lock); spin_unlock(&c->cnt_lock);
if (encrypted) { if (encrypted) {
err = fscrypt_inherit_context(dir, inode, &encrypted, true); err = fscrypt_set_context(inode, NULL);
if (err) { if (err) {
ubifs_err(c, "fscrypt_inherit_context failed: %i", err); ubifs_err(c, "fscrypt_set_context failed: %i", err);
make_bad_inode(inode); goto out_iput;
iput(inode);
return ERR_PTR(err);
} }
} }
return inode; return inode;
out_iput:
make_bad_inode(inode);
iput(inode);
return ERR_PTR(err);
} }
static int dbg_check_name(const struct ubifs_info *c, static int dbg_check_name(const struct ubifs_info *c,
@ -517,7 +511,7 @@ static int ubifs_readdir(struct file *file, struct dir_context *ctx)
if (err) if (err)
return err; return err;
err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr); err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr);
if (err) if (err)
return err; return err;
@ -1667,7 +1661,7 @@ static const struct dentry_operations ubifs_encrypted_dentry_ops = {
static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry) static void ubifs_set_d_ops(struct inode *dir, struct dentry *dentry)
{ {
#ifdef CONFIG_FS_ENCRYPTION #ifdef CONFIG_FS_ENCRYPTION
if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) { if (dentry->d_flags & DCACHE_NOKEY_NAME) {
d_set_d_op(dentry, &ubifs_encrypted_dentry_ops); d_set_d_op(dentry, &ubifs_encrypted_dentry_ops);
return; return;
} }

View File

@ -213,7 +213,7 @@ struct dentry_operations {
#define DCACHE_MAY_FREE 0x00800000 #define DCACHE_MAY_FREE 0x00800000
#define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */ #define DCACHE_FALLTHRU 0x01000000 /* Fall through to lower layer */
#define DCACHE_ENCRYPTED_NAME 0x02000000 /* Encrypted name (dir key was unavailable) */ #define DCACHE_NOKEY_NAME 0x02000000 /* Encrypted name encoded without key */
#define DCACHE_OP_REAL 0x04000000 #define DCACHE_OP_REAL 0x04000000
#define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */ #define DCACHE_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */

View File

@ -15,13 +15,12 @@
#include <linux/fs.h> #include <linux/fs.h>
#include <linux/mm.h> #include <linux/mm.h>
#include <linux/parser.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <uapi/linux/fscrypt.h> #include <uapi/linux/fscrypt.h>
#define FS_CRYPTO_BLOCK_SIZE 16 #define FS_CRYPTO_BLOCK_SIZE 16
union fscrypt_context; union fscrypt_policy;
struct fscrypt_info; struct fscrypt_info;
struct seq_file; struct seq_file;
@ -36,7 +35,7 @@ struct fscrypt_name {
u32 hash; u32 hash;
u32 minor_hash; u32 minor_hash;
struct fscrypt_str crypto_buf; struct fscrypt_str crypto_buf;
bool is_ciphertext_name; bool is_nokey_name;
}; };
#define FSTR_INIT(n, l) { .name = n, .len = l } #define FSTR_INIT(n, l) { .name = n, .len = l }
@ -62,8 +61,7 @@ struct fscrypt_operations {
int (*get_context)(struct inode *inode, void *ctx, size_t len); int (*get_context)(struct inode *inode, void *ctx, size_t len);
int (*set_context)(struct inode *inode, const void *ctx, size_t len, int (*set_context)(struct inode *inode, const void *ctx, size_t len,
void *fs_data); void *fs_data);
const union fscrypt_context *(*get_dummy_context)( const union fscrypt_policy *(*get_dummy_policy)(struct super_block *sb);
struct super_block *sb);
bool (*empty_dir)(struct inode *inode); bool (*empty_dir)(struct inode *inode);
unsigned int max_namelen; unsigned int max_namelen;
bool (*has_stable_inodes)(struct super_block *sb); bool (*has_stable_inodes)(struct super_block *sb);
@ -101,24 +99,16 @@ static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode); return IS_ENCRYPTED(inode) && S_ISREG(inode->i_mode);
} }
static inline const union fscrypt_context *
fscrypt_get_dummy_context(struct super_block *sb)
{
if (!sb->s_cop->get_dummy_context)
return NULL;
return sb->s_cop->get_dummy_context(sb);
}
/* /*
* When d_splice_alias() moves a directory's encrypted alias to its decrypted * When d_splice_alias() moves a directory's no-key alias to its plaintext alias
* alias as a result of the encryption key being added, DCACHE_ENCRYPTED_NAME * as a result of the encryption key being added, DCACHE_NOKEY_NAME must be
* must be cleared. Note that we don't have to support arbitrary moves of this * cleared. Note that we don't have to support arbitrary moves of this flag
* flag because fscrypt doesn't allow encrypted aliases to be the source or * because fscrypt doesn't allow no-key names to be the source or target of a
* target of a rename(). * rename().
*/ */
static inline void fscrypt_handle_d_move(struct dentry *dentry) static inline void fscrypt_handle_d_move(struct dentry *dentry)
{ {
dentry->d_flags &= ~DCACHE_ENCRYPTED_NAME; dentry->d_flags &= ~DCACHE_NOKEY_NAME;
} }
/* crypto.c */ /* crypto.c */
@ -157,23 +147,21 @@ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg);
int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg); int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *arg);
int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg); int fscrypt_ioctl_get_nonce(struct file *filp, void __user *arg);
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child); int fscrypt_has_permitted_context(struct inode *parent, struct inode *child);
int fscrypt_inherit_context(struct inode *parent, struct inode *child, int fscrypt_set_context(struct inode *inode, void *fs_data);
void *fs_data, bool preload);
struct fscrypt_dummy_context { struct fscrypt_dummy_policy {
const union fscrypt_context *ctx; const union fscrypt_policy *policy;
}; };
int fscrypt_set_test_dummy_encryption(struct super_block *sb, int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg,
const substring_t *arg, struct fscrypt_dummy_policy *dummy_policy);
struct fscrypt_dummy_context *dummy_ctx);
void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep, void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep,
struct super_block *sb); struct super_block *sb);
static inline void static inline void
fscrypt_free_dummy_context(struct fscrypt_dummy_context *dummy_ctx) fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
{ {
kfree(dummy_ctx->ctx); kfree(dummy_policy->policy);
dummy_ctx->ctx = NULL; dummy_policy->policy = NULL;
} }
/* keyring.c */ /* keyring.c */
@ -185,6 +173,8 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg);
/* keysetup.c */ /* keysetup.c */
int fscrypt_get_encryption_info(struct inode *inode); int fscrypt_get_encryption_info(struct inode *inode);
int fscrypt_prepare_new_inode(struct inode *dir, struct inode *inode,
bool *encrypt_ret);
void fscrypt_put_encryption_info(struct inode *inode); void fscrypt_put_encryption_info(struct inode *inode);
void fscrypt_free_inode(struct inode *inode); void fscrypt_free_inode(struct inode *inode);
int fscrypt_drop_inode(struct inode *inode); int fscrypt_drop_inode(struct inode *inode);
@ -198,7 +188,7 @@ static inline void fscrypt_free_filename(struct fscrypt_name *fname)
kfree(fname->crypto_buf.name); kfree(fname->crypto_buf.name);
} }
int fscrypt_fname_alloc_buffer(const struct inode *inode, u32 max_encrypted_len, int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
struct fscrypt_str *crypto_str); struct fscrypt_str *crypto_str);
void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str); void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str);
int fscrypt_fname_disk_to_usr(const struct inode *inode, int fscrypt_fname_disk_to_usr(const struct inode *inode,
@ -208,6 +198,7 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode,
bool fscrypt_match_name(const struct fscrypt_name *fname, bool fscrypt_match_name(const struct fscrypt_name *fname,
const u8 *de_name, u32 de_name_len); const u8 *de_name, u32 de_name_len);
u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name); u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name);
int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
/* bio.c */ /* bio.c */
void fscrypt_decrypt_bio(struct bio *bio); void fscrypt_decrypt_bio(struct bio *bio);
@ -225,9 +216,9 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
struct fscrypt_name *fname); struct fscrypt_name *fname);
int fscrypt_prepare_setflags(struct inode *inode, int fscrypt_prepare_setflags(struct inode *inode,
unsigned int oldflags, unsigned int flags); unsigned int oldflags, unsigned int flags);
int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len, int fscrypt_prepare_symlink(struct inode *dir, const char *target,
unsigned int max_len, unsigned int len, unsigned int max_len,
struct fscrypt_str *disk_link); struct fscrypt_str *disk_link);
int __fscrypt_encrypt_symlink(struct inode *inode, const char *target, int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
unsigned int len, struct fscrypt_str *disk_link); unsigned int len, struct fscrypt_str *disk_link);
const char *fscrypt_get_symlink(struct inode *inode, const void *caddr, const char *fscrypt_get_symlink(struct inode *inode, const void *caddr,
@ -250,12 +241,6 @@ static inline bool fscrypt_needs_contents_encryption(const struct inode *inode)
return false; return false;
} }
static inline const union fscrypt_context *
fscrypt_get_dummy_context(struct super_block *sb)
{
return NULL;
}
static inline void fscrypt_handle_d_move(struct dentry *dentry) static inline void fscrypt_handle_d_move(struct dentry *dentry)
{ {
} }
@ -341,14 +326,12 @@ static inline int fscrypt_has_permitted_context(struct inode *parent,
return 0; return 0;
} }
static inline int fscrypt_inherit_context(struct inode *parent, static inline int fscrypt_set_context(struct inode *inode, void *fs_data)
struct inode *child,
void *fs_data, bool preload)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
struct fscrypt_dummy_context { struct fscrypt_dummy_policy {
}; };
static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq, static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq,
@ -358,7 +341,7 @@ static inline void fscrypt_show_test_dummy_encryption(struct seq_file *seq,
} }
static inline void static inline void
fscrypt_free_dummy_context(struct fscrypt_dummy_context *dummy_ctx) fscrypt_free_dummy_policy(struct fscrypt_dummy_policy *dummy_policy)
{ {
} }
@ -395,6 +378,15 @@ static inline int fscrypt_get_encryption_info(struct inode *inode)
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static inline int fscrypt_prepare_new_inode(struct inode *dir,
struct inode *inode,
bool *encrypt_ret)
{
if (IS_ENCRYPTED(dir))
return -EOPNOTSUPP;
return 0;
}
static inline void fscrypt_put_encryption_info(struct inode *inode) static inline void fscrypt_put_encryption_info(struct inode *inode)
{ {
return; return;
@ -429,8 +421,7 @@ static inline void fscrypt_free_filename(struct fscrypt_name *fname)
return; return;
} }
static inline int fscrypt_fname_alloc_buffer(const struct inode *inode, static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
u32 max_encrypted_len,
struct fscrypt_str *crypto_str) struct fscrypt_str *crypto_str)
{ {
return -EOPNOTSUPP; return -EOPNOTSUPP;
@ -465,6 +456,12 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir,
return 0; return 0;
} }
static inline int fscrypt_d_revalidate(struct dentry *dentry,
unsigned int flags)
{
return 1;
}
/* bio.c */ /* bio.c */
static inline void fscrypt_decrypt_bio(struct bio *bio) static inline void fscrypt_decrypt_bio(struct bio *bio)
{ {
@ -514,15 +511,21 @@ static inline int fscrypt_prepare_setflags(struct inode *inode,
return 0; return 0;
} }
static inline int __fscrypt_prepare_symlink(struct inode *dir, static inline int fscrypt_prepare_symlink(struct inode *dir,
unsigned int len, const char *target,
unsigned int max_len, unsigned int len,
struct fscrypt_str *disk_link) unsigned int max_len,
struct fscrypt_str *disk_link)
{ {
return -EOPNOTSUPP; if (IS_ENCRYPTED(dir))
return -EOPNOTSUPP;
disk_link->name = (unsigned char *)target;
disk_link->len = len + 1;
if (disk_link->len > max_len)
return -ENAMETOOLONG;
return 0;
} }
static inline int __fscrypt_encrypt_symlink(struct inode *inode, static inline int __fscrypt_encrypt_symlink(struct inode *inode,
const char *target, const char *target,
unsigned int len, unsigned int len,
@ -768,18 +771,17 @@ static inline int fscrypt_prepare_rename(struct inode *old_dir,
* @fname: (output) the name to use to search the on-disk directory * @fname: (output) the name to use to search the on-disk directory
* *
* Prepare for ->lookup() in a directory which may be encrypted by determining * Prepare for ->lookup() in a directory which may be encrypted by determining
* the name that will actually be used to search the directory on-disk. Lookups * the name that will actually be used to search the directory on-disk. If the
* can be done with or without the directory's encryption key; without the key, * directory's encryption key is available, then the lookup is assumed to be by
* filenames are presented in encrypted form. Therefore, we'll try to set up * plaintext name; otherwise, it is assumed to be by no-key name.
* the directory's encryption key, but even without it the lookup can continue.
* *
* After calling this function, a filesystem should ensure that it's dentry * After calling this function, a filesystem should ensure that it's dentry
* operations contain fscrypt_d_revalidate if DCACHE_ENCRYPTED_NAME was set, * operations contain fscrypt_d_revalidate if DCACHE_NOKEY_NAME was set,
* so that the dentry can be invalidated if the key is later added. * so that the dentry can be invalidated if the key is later added.
* *
* Return: 0 on success; -ENOENT if key is unavailable but the filename isn't a * Return: 0 on success; -ENOENT if the directory's key is unavailable but the
* correctly formed encoded ciphertext name, so a negative dentry should be * filename isn't a valid no-key name, so a negative dentry should be created;
* created; or another -errno code. * or another -errno code.
*/ */
static inline int fscrypt_prepare_lookup(struct inode *dir, static inline int fscrypt_prepare_lookup(struct inode *dir,
struct dentry *dentry, struct dentry *dentry,
@ -821,45 +823,6 @@ static inline int fscrypt_prepare_setattr(struct dentry *dentry,
return 0; return 0;
} }
/**
* fscrypt_prepare_symlink() - prepare to create a possibly-encrypted symlink
* @dir: directory in which the symlink is being created
* @target: plaintext symlink target
* @len: length of @target excluding null terminator
* @max_len: space the filesystem has available to store the symlink target
* @disk_link: (out) the on-disk symlink target being prepared
*
* This function computes the size the symlink target will require on-disk,
* stores it in @disk_link->len, and validates it against @max_len. An
* encrypted symlink may be longer than the original.
*
* Additionally, @disk_link->name is set to @target if the symlink will be
* unencrypted, but left NULL if the symlink will be encrypted. For encrypted
* symlinks, the filesystem must call fscrypt_encrypt_symlink() to create the
* on-disk target later. (The reason for the two-step process is that some
* filesystems need to know the size of the symlink target before creating the
* inode, e.g. to determine whether it will be a "fast" or "slow" symlink.)
*
* Return: 0 on success, -ENAMETOOLONG if the symlink target is too long,
* -ENOKEY if the encryption key is missing, or another -errno code if a problem
* occurred while setting up the encryption key.
*/
static inline int fscrypt_prepare_symlink(struct inode *dir,
const char *target,
unsigned int len,
unsigned int max_len,
struct fscrypt_str *disk_link)
{
if (IS_ENCRYPTED(dir) || fscrypt_get_dummy_context(dir->i_sb) != NULL)
return __fscrypt_prepare_symlink(dir, len, max_len, disk_link);
disk_link->name = (unsigned char *)target;
disk_link->len = len + 1;
if (disk_link->len > max_len)
return -ENAMETOOLONG;
return 0;
}
/** /**
* fscrypt_encrypt_symlink() - encrypt the symlink target if needed * fscrypt_encrypt_symlink() - encrypt the symlink target if needed
* @inode: symlink inode * @inode: symlink inode

View File

@ -45,7 +45,6 @@ struct fscrypt_policy_v1 {
__u8 flags; __u8 flags;
__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE]; __u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
}; };
#define fscrypt_policy fscrypt_policy_v1
/* /*
* Process-subscribed "logon" key description prefix and payload format. * Process-subscribed "logon" key description prefix and payload format.
@ -159,9 +158,9 @@ struct fscrypt_get_key_status_arg {
__u32 __out_reserved[13]; __u32 __out_reserved[13];
}; };
#define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy) #define FS_IOC_SET_ENCRYPTION_POLICY _IOR('f', 19, struct fscrypt_policy_v1)
#define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16]) #define FS_IOC_GET_ENCRYPTION_PWSALT _IOW('f', 20, __u8[16])
#define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy) #define FS_IOC_GET_ENCRYPTION_POLICY _IOW('f', 21, struct fscrypt_policy_v1)
#define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 22, __u8[9]) /* size + version */ #define FS_IOC_GET_ENCRYPTION_POLICY_EX _IOWR('f', 22, __u8[9]) /* size + version */
#define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg) #define FS_IOC_ADD_ENCRYPTION_KEY _IOWR('f', 23, struct fscrypt_add_key_arg)
#define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg) #define FS_IOC_REMOVE_ENCRYPTION_KEY _IOWR('f', 24, struct fscrypt_remove_key_arg)
@ -173,6 +172,7 @@ struct fscrypt_get_key_status_arg {
/* old names; don't add anything new here! */ /* old names; don't add anything new here! */
#ifndef __KERNEL__ #ifndef __KERNEL__
#define fscrypt_policy fscrypt_policy_v1
#define FS_KEY_DESCRIPTOR_SIZE FSCRYPT_KEY_DESCRIPTOR_SIZE #define FS_KEY_DESCRIPTOR_SIZE FSCRYPT_KEY_DESCRIPTOR_SIZE
#define FS_POLICY_FLAGS_PAD_4 FSCRYPT_POLICY_FLAGS_PAD_4 #define FS_POLICY_FLAGS_PAD_4 FSCRYPT_POLICY_FLAGS_PAD_4
#define FS_POLICY_FLAGS_PAD_8 FSCRYPT_POLICY_FLAGS_PAD_8 #define FS_POLICY_FLAGS_PAD_8 FSCRYPT_POLICY_FLAGS_PAD_8