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:
commit
9d77f49849
@ -351,9 +351,11 @@ void fscrypt_msg(const struct inode *inode, const char *level,
|
||||
va_start(args, fmt);
|
||||
vaf.fmt = fmt;
|
||||
vaf.va = &args;
|
||||
if (inode)
|
||||
if (inode && inode->i_ino)
|
||||
printk("%sfscrypt (%s, inode %lu): %pV\n",
|
||||
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
|
||||
printk("%sfscrypt: %pV\n", level, &vaf);
|
||||
va_end(args);
|
||||
|
@ -61,15 +61,6 @@ struct fscrypt_nokey_name {
|
||||
*/
|
||||
#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)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
|
||||
u32 max_len, u32 *encrypted_len_ret)
|
||||
bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
|
||||
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(&ci->ci_policy) &
|
||||
int padding = 4 << (fscrypt_policy_flags(policy) &
|
||||
FSCRYPT_POLICY_FLAGS_PAD_MASK);
|
||||
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
|
||||
* @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
|
||||
* used to present
|
||||
* @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
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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 {
|
||||
memcpy(nokey_name.bytes, iname->name, sizeof(nokey_name.bytes));
|
||||
/* Compute strong hash of remaining part of name. */
|
||||
fscrypt_do_sha256(&iname->name[sizeof(nokey_name.bytes)],
|
||||
iname->len - sizeof(nokey_name.bytes),
|
||||
nokey_name.sha256);
|
||||
sha256(&iname->name[sizeof(nokey_name.bytes)],
|
||||
iname->len - sizeof(nokey_name.bytes),
|
||||
nokey_name.sha256);
|
||||
size = FSCRYPT_NOKEY_NAME_MAX;
|
||||
}
|
||||
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
|
||||
* get the disk_name.
|
||||
*
|
||||
* Else, for keyless @lookup operations, @iname is the presented ciphertext, so
|
||||
* we decode it to get the fscrypt_nokey_name. Non-@lookup operations will be
|
||||
* impossible in this case, so we fail them with ENOKEY.
|
||||
* Else, for keyless @lookup operations, @iname should be a no-key name, so we
|
||||
* decode it to get the struct fscrypt_nokey_name. Non-@lookup operations will
|
||||
* be impossible in this case, so we fail them with ENOKEY.
|
||||
*
|
||||
* 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;
|
||||
|
||||
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,
|
||||
&fname->crypto_buf.len))
|
||||
return -ENAMETOOLONG;
|
||||
@ -440,7 +429,7 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
|
||||
}
|
||||
if (!lookup)
|
||||
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
|
||||
@ -499,7 +488,7 @@ bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
{
|
||||
const struct fscrypt_nokey_name *nokey_name =
|
||||
(const void *)fname->crypto_buf.name;
|
||||
u8 sha256[SHA256_DIGEST_SIZE];
|
||||
u8 digest[SHA256_DIGEST_SIZE];
|
||||
|
||||
if (likely(fname->disk_name.name)) {
|
||||
if (de_name_len != fname->disk_name.len)
|
||||
@ -510,9 +499,9 @@ bool fscrypt_match_name(const struct fscrypt_name *fname,
|
||||
return false;
|
||||
if (memcmp(de_name, nokey_name->bytes, sizeof(nokey_name->bytes)))
|
||||
return false;
|
||||
fscrypt_do_sha256(&de_name[sizeof(nokey_name->bytes)],
|
||||
de_name_len - sizeof(nokey_name->bytes), sha256);
|
||||
return !memcmp(sha256, nokey_name->sha256, sizeof(sha256));
|
||||
sha256(&de_name[sizeof(nokey_name->bytes)],
|
||||
de_name_len - sizeof(nokey_name->bytes), digest);
|
||||
return !memcmp(digest, nokey_name->sha256, sizeof(digest));
|
||||
}
|
||||
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
|
||||
* 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.
|
||||
*/
|
||||
if (!(dentry->d_flags & DCACHE_ENCRYPTED_NAME))
|
||||
if (!(dentry->d_flags & DCACHE_NOKEY_NAME))
|
||||
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
|
||||
* use dget_parent() here rather than use ->d_parent directly. That's
|
||||
* Although fscrypt forbids rename() on no-key names, we still must use
|
||||
* dget_parent() here rather than use ->d_parent directly. That's
|
||||
* because a corrupted fs image may contain directory hard links, which
|
||||
* 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
|
||||
|
@ -99,7 +99,6 @@ static inline const u8 *fscrypt_context_nonce(const union fscrypt_context *ctx)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#undef fscrypt_policy
|
||||
union fscrypt_policy {
|
||||
u8 version;
|
||||
struct fscrypt_policy_v1 v1;
|
||||
@ -294,8 +293,9 @@ void fscrypt_generate_iv(union fscrypt_iv *iv, u64 lblk_num,
|
||||
/* fname.c */
|
||||
int fscrypt_fname_encrypt(const struct inode *inode, const struct qstr *iname,
|
||||
u8 *out, unsigned int olen);
|
||||
bool fscrypt_fname_encrypted_size(const struct inode *inode, u32 orig_len,
|
||||
u32 max_len, u32 *encrypted_len_ret);
|
||||
bool fscrypt_fname_encrypted_size(const union fscrypt_policy *policy,
|
||||
u32 orig_len, u32 max_len,
|
||||
u32 *encrypted_len_ret);
|
||||
|
||||
/* 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,
|
||||
const struct fscrypt_master_key *mk);
|
||||
|
||||
void fscrypt_hash_inode_number(struct fscrypt_info *ci,
|
||||
const struct fscrypt_master_key *mk);
|
||||
|
||||
/* keysetup_v1.c */
|
||||
|
||||
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,
|
||||
const union fscrypt_context *ctx_u,
|
||||
int ctx_size);
|
||||
const union fscrypt_policy *fscrypt_policy_to_inherit(struct inode *dir);
|
||||
|
||||
#endif /* _FSCRYPT_PRIVATE_H */
|
||||
|
@ -60,8 +60,8 @@ int __fscrypt_prepare_link(struct inode *inode, struct inode *dir,
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
/* ... in case we looked up ciphertext name before key was added */
|
||||
if (dentry->d_flags & DCACHE_ENCRYPTED_NAME)
|
||||
/* ... in case we looked up no-key name before key was added */
|
||||
if (dentry->d_flags & DCACHE_NOKEY_NAME)
|
||||
return -ENOKEY;
|
||||
|
||||
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)
|
||||
return err;
|
||||
|
||||
/* ... in case we looked up ciphertext name(s) before key was added */
|
||||
if ((old_dentry->d_flags | new_dentry->d_flags) &
|
||||
DCACHE_ENCRYPTED_NAME)
|
||||
/* ... in case we looked up no-key name(s) before key was added */
|
||||
if ((old_dentry->d_flags | new_dentry->d_flags) & DCACHE_NOKEY_NAME)
|
||||
return -ENOKEY;
|
||||
|
||||
if (old_dir != new_dir) {
|
||||
@ -114,9 +113,9 @@ int __fscrypt_prepare_lookup(struct inode *dir, struct dentry *dentry,
|
||||
if (err && err != -ENOENT)
|
||||
return err;
|
||||
|
||||
if (fname->is_ciphertext_name) {
|
||||
if (fname->is_nokey_name) {
|
||||
spin_lock(&dentry->d_lock);
|
||||
dentry->d_flags |= DCACHE_ENCRYPTED_NAME;
|
||||
dentry->d_flags |= DCACHE_NOKEY_NAME;
|
||||
spin_unlock(&dentry->d_lock);
|
||||
}
|
||||
return err;
|
||||
@ -165,26 +164,51 @@ int fscrypt_prepare_setflags(struct inode *inode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link)
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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
|
||||
* the amount of NUL padding, which is determined by the flags set in
|
||||
* 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);
|
||||
if (err)
|
||||
return err;
|
||||
if (!fscrypt_has_encryption_key(dir))
|
||||
return -ENOKEY;
|
||||
policy = fscrypt_policy_to_inherit(dir);
|
||||
if (policy == NULL) {
|
||||
/* Not encrypted */
|
||||
disk_link->name = (unsigned char *)target;
|
||||
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
|
||||
@ -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
|
||||
* 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),
|
||||
&disk_link->len))
|
||||
return -ENAMETOOLONG;
|
||||
@ -206,7 +230,7 @@ int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
disk_link->name = NULL;
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(__fscrypt_prepare_symlink);
|
||||
EXPORT_SYMBOL_GPL(fscrypt_prepare_symlink);
|
||||
|
||||
int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
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;
|
||||
unsigned int ciphertext_len;
|
||||
|
||||
err = fscrypt_require_key(inode);
|
||||
if (err)
|
||||
return err;
|
||||
/*
|
||||
* fscrypt_prepare_new_inode() should have already set up the new
|
||||
* 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) {
|
||||
/* 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)
|
||||
return ERR_PTR(-EUCLEAN);
|
||||
|
||||
err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr);
|
||||
err = fscrypt_fname_alloc_buffer(cstr.len, &pstr);
|
||||
if (err)
|
||||
return ERR_PTR(err);
|
||||
|
||||
|
@ -110,7 +110,7 @@ int fscrypt_select_encryption_impl(struct fscrypt_info *ci,
|
||||
crypto_cfg.dun_bytes = fscrypt_get_dun_bytes(ci);
|
||||
crypto_cfg.is_hw_wrapped = is_hw_wrapped_key;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
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;
|
||||
int err;
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -176,10 +175,8 @@ int fscrypt_prepare_inline_crypt_key(struct fscrypt_prepared_key *prep_key,
|
||||
}
|
||||
queue_refs++;
|
||||
|
||||
flags = memalloc_nofs_save();
|
||||
err = blk_crypto_start_using_key(&blk_key->base,
|
||||
blk_key->devs[i]);
|
||||
memalloc_nofs_restore(flags);
|
||||
if (err) {
|
||||
fscrypt_err(inode,
|
||||
"error %d starting to use blk-crypto", err);
|
||||
|
@ -847,6 +847,7 @@ static int check_for_busy_inodes(struct super_block *sb,
|
||||
struct list_head *pos;
|
||||
size_t busy_count = 0;
|
||||
unsigned long ino;
|
||||
char ino_str[50] = "";
|
||||
|
||||
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);
|
||||
|
||||
/* 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,
|
||||
"%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),
|
||||
master_key_spec_len(&mk->mk_spec), (u8 *)&mk->mk_spec.u,
|
||||
ino);
|
||||
ino_str);
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
#include <crypto/skcipher.h>
|
||||
#include <linux/key.h>
|
||||
#include <linux/random.h>
|
||||
|
||||
#include "fscrypt_private.h"
|
||||
|
||||
@ -253,6 +254,16 @@ int fscrypt_derive_dirhash_key(struct fscrypt_info *ci,
|
||||
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,
|
||||
struct fscrypt_master_key *mk)
|
||||
{
|
||||
@ -285,13 +296,20 @@ static int fscrypt_setup_iv_ino_lblk_32_key(struct fscrypt_info *ci,
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
@ -345,7 +363,7 @@ static int fscrypt_setup_v2_file_key(struct fscrypt_info *ci,
|
||||
return err;
|
||||
|
||||
/* 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);
|
||||
if (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.
|
||||
*/
|
||||
static int setup_file_encryption_key(struct fscrypt_info *ci,
|
||||
bool need_dirhash_key,
|
||||
struct key **master_key_ret)
|
||||
{
|
||||
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);
|
||||
break;
|
||||
case FSCRYPT_POLICY_V2:
|
||||
err = fscrypt_setup_v2_file_key(ci, mk);
|
||||
err = fscrypt_setup_v2_file_key(ci, mk, need_dirhash_key);
|
||||
break;
|
||||
default:
|
||||
WARN_ON(1);
|
||||
@ -497,57 +516,28 @@ static void put_crypt_info(struct fscrypt_info *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;
|
||||
union fscrypt_context ctx;
|
||||
struct fscrypt_mode *mode;
|
||||
struct key *master_key = NULL;
|
||||
int res;
|
||||
|
||||
if (fscrypt_has_encryption_key(inode))
|
||||
return 0;
|
||||
|
||||
res = fscrypt_initialize(inode->i_sb->s_cop->flags);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
res = inode->i_sb->s_cop->get_context(inode, &ctx, sizeof(ctx));
|
||||
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);
|
||||
crypt_info = kmem_cache_zalloc(fscrypt_info_cachep, GFP_KERNEL);
|
||||
if (!crypt_info)
|
||||
return -ENOMEM;
|
||||
|
||||
crypt_info->ci_inode = inode;
|
||||
|
||||
res = fscrypt_policy_from_context(&crypt_info->ci_policy, &ctx, res);
|
||||
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;
|
||||
}
|
||||
crypt_info->ci_policy = *policy;
|
||||
memcpy(crypt_info->ci_nonce, nonce, FSCRYPT_FILE_NONCE_SIZE);
|
||||
|
||||
mode = select_encryption_mode(&crypt_info->ci_policy, inode);
|
||||
if (IS_ERR(mode)) {
|
||||
@ -557,13 +547,14 @@ int fscrypt_get_encryption_info(struct inode *inode)
|
||||
WARN_ON(mode->ivsize > FSCRYPT_MAX_IV_SIZE);
|
||||
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)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* Multiple tasks may race to set ->i_crypt_info, so use
|
||||
* cmpxchg_release(). This pairs with the smp_load_acquire() in
|
||||
* For existing inodes, multiple tasks may race to set ->i_crypt_info.
|
||||
* 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
|
||||
* 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);
|
||||
key_put(master_key);
|
||||
}
|
||||
if (res == -ENOKEY)
|
||||
res = 0;
|
||||
put_crypt_info(crypt_info);
|
||||
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);
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @inode: an inode being evicted
|
||||
|
@ -60,7 +60,7 @@ static int derive_key_aes(const u8 *master_key,
|
||||
goto out;
|
||||
}
|
||||
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) {
|
||||
res = -ENOMEM;
|
||||
goto out;
|
||||
@ -99,7 +99,7 @@ find_and_lock_process_key(const char *prefix,
|
||||
const struct user_key_payload *ukp;
|
||||
const struct fscrypt_key *payload;
|
||||
|
||||
description = kasprintf(GFP_NOFS, "%s%*phN", prefix,
|
||||
description = kasprintf(GFP_KERNEL, "%s%*phN", prefix,
|
||||
FSCRYPT_KEY_DESCRIPTOR_SIZE, descriptor);
|
||||
if (!description)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
@ -228,7 +228,7 @@ fscrypt_get_direct_key(const struct fscrypt_info *ci, const u8 *raw_key)
|
||||
return dk;
|
||||
|
||||
/* Nope, allocate one. */
|
||||
dk = kzalloc(sizeof(*dk), GFP_NOFS);
|
||||
dk = kzalloc(sizeof(*dk), GFP_KERNEL);
|
||||
if (!dk)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
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
|
||||
* 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)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -32,6 +32,14 @@ bool fscrypt_policies_equal(const union fscrypt_policy *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)
|
||||
{
|
||||
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))
|
||||
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) &&
|
||||
/* This uses hashed inode numbers, so ino_bits doesn't matter. */
|
||||
!supported_iv_ino_lblk_policy(policy, inode, "IV_INO_LBLK_32",
|
||||
INT_MAX, 32))
|
||||
32, 32))
|
||||
return false;
|
||||
|
||||
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
|
||||
* an fscrypt_policy
|
||||
* fscrypt_new_context() - create a new fscrypt_context
|
||||
* @ctx_u: output context
|
||||
* @policy_u: input policy
|
||||
* @nonce: nonce to use
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
static int fscrypt_new_context_from_policy(union fscrypt_context *ctx_u,
|
||||
const union fscrypt_policy *policy_u)
|
||||
static int fscrypt_new_context(union fscrypt_context *ctx_u,
|
||||
const union fscrypt_policy *policy_u,
|
||||
const u8 nonce[FSCRYPT_FILE_NONCE_SIZE])
|
||||
{
|
||||
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,
|
||||
policy->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);
|
||||
}
|
||||
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,
|
||||
policy->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);
|
||||
}
|
||||
}
|
||||
@ -372,6 +386,7 @@ static int fscrypt_get_policy(struct inode *inode, union fscrypt_policy *policy)
|
||||
static int set_encryption_policy(struct inode *inode,
|
||||
const union fscrypt_policy *policy)
|
||||
{
|
||||
u8 nonce[FSCRYPT_FILE_NONCE_SIZE];
|
||||
union fscrypt_context ctx;
|
||||
int ctxsize;
|
||||
int err;
|
||||
@ -409,7 +424,8 @@ static int set_encryption_policy(struct inode *inode,
|
||||
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);
|
||||
}
|
||||
@ -620,86 +636,99 @@ int fscrypt_has_permitted_context(struct inode *parent, struct inode *child)
|
||||
}
|
||||
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
|
||||
* @parent: Parent inode from which the context is inherited.
|
||||
* @child: Child inode that inherits the context from @parent.
|
||||
* @fs_data: private data given by FS.
|
||||
* @preload: preload child i_crypt_info if true
|
||||
* fscrypt_set_context() - Set the fscrypt context of a new inode
|
||||
* @inode: a new inode
|
||||
* @fs_data: private data given by FS and passed to ->set_context()
|
||||
*
|
||||
* 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
|
||||
*/
|
||||
int fscrypt_inherit_context(struct inode *parent, struct inode *child,
|
||||
void *fs_data, bool preload)
|
||||
int fscrypt_set_context(struct inode *inode, void *fs_data)
|
||||
{
|
||||
struct fscrypt_info *ci = inode->i_crypt_info;
|
||||
union fscrypt_context ctx;
|
||||
int ctxsize;
|
||||
struct fscrypt_info *ci;
|
||||
int res;
|
||||
|
||||
res = fscrypt_get_encryption_info(parent);
|
||||
if (res < 0)
|
||||
return res;
|
||||
|
||||
ci = fscrypt_get_info(parent);
|
||||
if (ci == NULL)
|
||||
/* fscrypt_prepare_new_inode() should have set up the key already. */
|
||||
if (WARN_ON_ONCE(!ci))
|
||||
return -ENOKEY;
|
||||
|
||||
ctxsize = fscrypt_new_context_from_policy(&ctx, &ci->ci_policy);
|
||||
|
||||
BUILD_BUG_ON(sizeof(ctx) != FSCRYPT_SET_CONTEXT_MAX_SIZE);
|
||||
res = parent->i_sb->s_cop->set_context(child, &ctx, ctxsize, fs_data);
|
||||
if (res)
|
||||
return res;
|
||||
return preload ? fscrypt_get_encryption_info(child): 0;
|
||||
ctxsize = fscrypt_new_context(&ctx, &ci->ci_policy, ci->ci_nonce);
|
||||
|
||||
/*
|
||||
* 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'
|
||||
* @sb: the filesystem on which test_dummy_encryption is being specified
|
||||
* @arg: the argument to the test_dummy_encryption option.
|
||||
* If no argument was specified, then @arg->from == NULL.
|
||||
* @dummy_ctx: the filesystem's current dummy context (input/output, see below)
|
||||
* @arg: the argument to the test_dummy_encryption option. May be NULL.
|
||||
* @dummy_policy: the filesystem's current dummy policy (input/output, see
|
||||
* below)
|
||||
*
|
||||
* Handle the test_dummy_encryption mount option by creating a dummy encryption
|
||||
* context, saving it in @dummy_ctx, and adding the corresponding dummy
|
||||
* encryption key to the filesystem. If the @dummy_ctx is already set, then
|
||||
* policy, saving it in @dummy_policy, and adding the corresponding dummy
|
||||
* 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
|
||||
* remount, as that is difficult to do safely.
|
||||
*
|
||||
* The reason we use an fscrypt_context rather than an fscrypt_policy is because
|
||||
* we mustn't generate a new nonce each time we access a dummy-encrypted
|
||||
* 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;
|
||||
* Return: 0 on success (dummy policy set, or the same policy is already set);
|
||||
* -EEXIST if a different dummy policy is already set;
|
||||
* or another -errno value.
|
||||
*/
|
||||
int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
||||
const substring_t *arg,
|
||||
struct fscrypt_dummy_context *dummy_ctx)
|
||||
int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg,
|
||||
struct fscrypt_dummy_policy *dummy_policy)
|
||||
{
|
||||
const char *argstr = "v2";
|
||||
const char *argstr_to_free = NULL;
|
||||
struct fscrypt_key_specifier key_spec = { 0 };
|
||||
int version;
|
||||
union fscrypt_context *ctx = NULL;
|
||||
union fscrypt_policy *policy = NULL;
|
||||
int err;
|
||||
|
||||
if (arg->from) {
|
||||
argstr = argstr_to_free = match_strdup(arg);
|
||||
if (!argstr)
|
||||
return -ENOMEM;
|
||||
}
|
||||
if (!arg)
|
||||
arg = "v2";
|
||||
|
||||
if (!strcmp(argstr, "v1")) {
|
||||
version = FSCRYPT_CONTEXT_V1;
|
||||
if (!strcmp(arg, "v1")) {
|
||||
version = FSCRYPT_POLICY_V1;
|
||||
key_spec.type = FSCRYPT_KEY_SPEC_TYPE_DESCRIPTOR;
|
||||
memset(key_spec.u.descriptor, 0x42,
|
||||
FSCRYPT_KEY_DESCRIPTOR_SIZE);
|
||||
} else if (!strcmp(argstr, "v2")) {
|
||||
version = FSCRYPT_CONTEXT_V2;
|
||||
} else if (!strcmp(arg, "v2")) {
|
||||
version = FSCRYPT_POLICY_V2;
|
||||
key_spec.type = FSCRYPT_KEY_SPEC_TYPE_IDENTIFIER;
|
||||
/* key_spec.u.identifier gets filled in when adding the key */
|
||||
} else {
|
||||
@ -707,21 +736,8 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (dummy_ctx->ctx) {
|
||||
/*
|
||||
* 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) {
|
||||
policy = kzalloc(sizeof(*policy), GFP_KERNEL);
|
||||
if (!policy) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
@ -730,18 +746,18 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
ctx->version = version;
|
||||
switch (ctx->version) {
|
||||
case FSCRYPT_CONTEXT_V1:
|
||||
ctx->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
|
||||
ctx->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
|
||||
memcpy(ctx->v1.master_key_descriptor, key_spec.u.descriptor,
|
||||
policy->version = version;
|
||||
switch (policy->version) {
|
||||
case FSCRYPT_POLICY_V1:
|
||||
policy->v1.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
|
||||
policy->v1.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
|
||||
memcpy(policy->v1.master_key_descriptor, key_spec.u.descriptor,
|
||||
FSCRYPT_KEY_DESCRIPTOR_SIZE);
|
||||
break;
|
||||
case FSCRYPT_CONTEXT_V2:
|
||||
ctx->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
|
||||
ctx->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
|
||||
memcpy(ctx->v2.master_key_identifier, key_spec.u.identifier,
|
||||
case FSCRYPT_POLICY_V2:
|
||||
policy->v2.contents_encryption_mode = FSCRYPT_MODE_AES_256_XTS;
|
||||
policy->v2.filenames_encryption_mode = FSCRYPT_MODE_AES_256_CTS;
|
||||
memcpy(policy->v2.master_key_identifier, key_spec.u.identifier,
|
||||
FSCRYPT_KEY_IDENTIFIER_SIZE);
|
||||
break;
|
||||
default:
|
||||
@ -749,12 +765,19 @@ int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
||||
err = -EINVAL;
|
||||
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;
|
||||
out:
|
||||
kfree(ctx);
|
||||
kfree(argstr_to_free);
|
||||
kfree(policy);
|
||||
return err;
|
||||
}
|
||||
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,
|
||||
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;
|
||||
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);
|
||||
|
@ -169,7 +169,7 @@ static int ext4_readdir(struct file *file, struct dir_context *ctx)
|
||||
}
|
||||
|
||||
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)
|
||||
return err;
|
||||
}
|
||||
|
@ -1401,7 +1401,7 @@ struct ext4_super_block {
|
||||
#define EXT4_MF_FS_ABORTED 0x0002 /* Fatal error detected */
|
||||
|
||||
#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
|
||||
#define DUMMY_ENCRYPTION_ENABLED(sbi) (0)
|
||||
#endif
|
||||
@ -1584,8 +1584,8 @@ struct ext4_sb_info {
|
||||
atomic_t s_warning_count;
|
||||
atomic_t s_msg_count;
|
||||
|
||||
/* Encryption context for '-o test_dummy_encryption' */
|
||||
struct fscrypt_dummy_context s_dummy_enc_ctx;
|
||||
/* Encryption policy for '-o test_dummy_encryption' */
|
||||
struct fscrypt_dummy_policy s_dummy_enc_policy;
|
||||
|
||||
/*
|
||||
* Barrier between writepages ops and changing any inode's JOURNAL_DATA
|
||||
|
119
fs/ext4/ialloc.c
119
fs/ext4/ialloc.c
@ -745,6 +745,53 @@ static int find_inode_bit(struct super_block *sb, ext4_group_t group,
|
||||
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
|
||||
* 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 flex_group;
|
||||
struct ext4_group_info *grp;
|
||||
int encrypt = 0;
|
||||
bool encrypt = false;
|
||||
|
||||
/* Cannot create files in a deleted directory */
|
||||
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)))
|
||||
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);
|
||||
trace_ext4_request_inode(dir, mode);
|
||||
inode = new_inode(sb);
|
||||
@ -869,10 +863,25 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
||||
else
|
||||
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);
|
||||
if (err)
|
||||
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)
|
||||
goal = sbi->s_inode_goal;
|
||||
|
||||
@ -1165,7 +1174,7 @@ struct inode *__ext4_new_inode(handle_t *handle, struct inode *dir,
|
||||
* prevent its deduplication.
|
||||
*/
|
||||
if (encrypt) {
|
||||
err = fscrypt_inherit_context(dir, inode, handle, true);
|
||||
err = fscrypt_set_context(inode, handle);
|
||||
if (err)
|
||||
goto fail_free_drop;
|
||||
}
|
||||
|
@ -667,8 +667,7 @@ static struct stats dx_show_leaf(struct inode *dir,
|
||||
|
||||
/* Directory is encrypted */
|
||||
res = fscrypt_fname_alloc_buffer(
|
||||
dir, len,
|
||||
&fname_crypto_str);
|
||||
len, &fname_crypto_str);
|
||||
if (res)
|
||||
printk(KERN_WARNING "Error "
|
||||
"allocating crypto "
|
||||
@ -1042,8 +1041,8 @@ static int htree_dirblock_to_tree(struct file *dir_file,
|
||||
brelse(bh);
|
||||
return err;
|
||||
}
|
||||
err = fscrypt_fname_alloc_buffer(dir, EXT4_NAME_LEN,
|
||||
&fname_crypto_str);
|
||||
err = fscrypt_fname_alloc_buffer(EXT4_NAME_LEN,
|
||||
&fname_crypto_str);
|
||||
if (err < 0) {
|
||||
brelse(bh);
|
||||
return err;
|
||||
|
@ -1104,7 +1104,7 @@ static void ext4_put_super(struct super_block *sb)
|
||||
crypto_free_shash(sbi->s_chksum_driver);
|
||||
kfree(sbi->s_blockgroup_lock);
|
||||
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
|
||||
utf8_unload(sb->s_encoding);
|
||||
#endif
|
||||
@ -1392,10 +1392,9 @@ static int ext4_set_context(struct inode *inode, const void *ctx, size_t len,
|
||||
return res;
|
||||
}
|
||||
|
||||
static const union fscrypt_context *
|
||||
ext4_get_dummy_context(struct super_block *sb)
|
||||
static const union fscrypt_policy *ext4_get_dummy_policy(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)
|
||||
@ -1414,7 +1413,7 @@ static const struct fscrypt_operations ext4_cryptops = {
|
||||
.key_prefix = "ext4:",
|
||||
.get_context = ext4_get_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,
|
||||
.max_namelen = EXT4_NAME_LEN,
|
||||
.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
|
||||
* 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,
|
||||
"Can't set test_dummy_encryption on remount");
|
||||
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 == -EEXIST)
|
||||
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++)
|
||||
kfree(get_qf_name(sb, sbi, i));
|
||||
#endif
|
||||
fscrypt_free_dummy_context(&sbi->s_dummy_enc_ctx);
|
||||
fscrypt_free_dummy_policy(&sbi->s_dummy_enc_policy);
|
||||
ext4_blkdev_remove(sbi);
|
||||
brelse(bh);
|
||||
out_fail:
|
||||
|
@ -113,7 +113,7 @@ static int __f2fs_setup_filename(const struct inode *dir,
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
fname->crypto_buf = crypt_name->crypto_buf;
|
||||
#endif
|
||||
if (crypt_name->is_ciphertext_name) {
|
||||
if (crypt_name->is_nokey_name) {
|
||||
/* hash was decoded from the no-key name */
|
||||
fname->hash = cpu_to_le32(crypt_name->hash);
|
||||
} else {
|
||||
@ -583,7 +583,7 @@ struct page *f2fs_init_inode_metadata(struct inode *inode, struct inode *dir,
|
||||
goto put_error;
|
||||
|
||||
if (IS_ENCRYPTED(inode)) {
|
||||
err = fscrypt_inherit_context(dir, inode, page, false);
|
||||
err = fscrypt_set_context(inode, page);
|
||||
if (err)
|
||||
goto put_error;
|
||||
}
|
||||
@ -1074,7 +1074,7 @@ static int f2fs_readdir(struct file *file, struct dir_context *ctx)
|
||||
if (err)
|
||||
goto out;
|
||||
|
||||
err = fscrypt_fname_alloc_buffer(inode, F2FS_NAME_LEN, &fstr);
|
||||
err = fscrypt_fname_alloc_buffer(F2FS_NAME_LEN, &fstr);
|
||||
if (err < 0)
|
||||
goto out;
|
||||
}
|
||||
|
@ -138,7 +138,7 @@ struct f2fs_mount_info {
|
||||
int fsync_mode; /* fsync policy */
|
||||
int fs_mode; /* fs mode: LFS or ADAPTIVE */
|
||||
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; /* Amount of space allowed to be
|
||||
* unusable when disabling checkpoint
|
||||
@ -1317,13 +1317,6 @@ enum fsync_mode {
|
||||
#define IS_IO_TRACED_PAGE(page) (0)
|
||||
#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 */
|
||||
enum compress_algorithm_type {
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
if (IS_SWAPFILE(inode) || f2fs_is_pinned_file(inode) ||
|
||||
|
@ -28,6 +28,7 @@ static struct inode *f2fs_new_inode(struct inode *dir, umode_t mode)
|
||||
nid_t ino;
|
||||
struct inode *inode;
|
||||
bool nid_free = false;
|
||||
bool encrypt = false;
|
||||
int xattr_size = 0;
|
||||
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_DEF_PROJID);
|
||||
|
||||
err = fscrypt_prepare_new_inode(dir, inode, &encrypt);
|
||||
if (err)
|
||||
goto fail_drop;
|
||||
|
||||
err = dquot_initialize(inode);
|
||||
if (err)
|
||||
goto fail_drop;
|
||||
|
||||
set_inode_flag(inode, FI_NEW_INODE);
|
||||
|
||||
if (f2fs_may_encrypt(dir, inode))
|
||||
if (encrypt)
|
||||
f2fs_set_encrypted_inode(inode);
|
||||
|
||||
if (f2fs_sb_has_extra_attr(sbi)) {
|
||||
|
@ -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
|
||||
* 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");
|
||||
return -EINVAL;
|
||||
}
|
||||
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 == -EEXIST)
|
||||
f2fs_warn(sbi,
|
||||
@ -1275,7 +1275,7 @@ static void f2fs_put_super(struct super_block *sb)
|
||||
for (i = 0; i < MAXQUOTAS; i++)
|
||||
kfree(F2FS_OPTION(sbi).s_qf_names[i]);
|
||||
#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);
|
||||
for (i = 0; i < NR_PAGE_TYPE; 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);
|
||||
}
|
||||
|
||||
static const union fscrypt_context *
|
||||
f2fs_get_dummy_context(struct super_block *sb)
|
||||
static const union fscrypt_policy *f2fs_get_dummy_policy(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)
|
||||
@ -2523,7 +2522,7 @@ static const struct fscrypt_operations f2fs_cryptops = {
|
||||
.key_prefix = "f2fs:",
|
||||
.get_context = f2fs_get_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,
|
||||
.max_namelen = F2FS_NAME_LEN,
|
||||
.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++)
|
||||
kfree(F2FS_OPTION(sbi).s_qf_names[i]);
|
||||
#endif
|
||||
fscrypt_free_dummy_context(&F2FS_OPTION(sbi).dummy_enc_ctx);
|
||||
fscrypt_free_dummy_policy(&F2FS_OPTION(sbi).dummy_enc_policy);
|
||||
kvfree(options);
|
||||
free_sb_buf:
|
||||
kfree(raw_super);
|
||||
|
@ -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)
|
||||
{
|
||||
#ifdef CONFIG_FS_ENCRYPTION
|
||||
if (dentry->d_flags & DCACHE_ENCRYPTED_NAME) {
|
||||
if (dentry->d_flags & DCACHE_NOKEY_NAME) {
|
||||
#ifdef CONFIG_UNICODE
|
||||
if (dir->i_sb->s_encoding) {
|
||||
d_set_d_op(dentry, &generic_encrypted_ci_dentry_ops);
|
||||
|
@ -81,19 +81,6 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
|
||||
struct ubifs_inode *ui;
|
||||
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);
|
||||
ui = ubifs_inode(inode);
|
||||
if (!inode)
|
||||
@ -112,6 +99,12 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
|
||||
current_time(inode);
|
||||
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) {
|
||||
case S_IFREG:
|
||||
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_IFCHR:
|
||||
inode->i_op = &ubifs_file_inode_operations;
|
||||
encrypted = false;
|
||||
break;
|
||||
default:
|
||||
BUG();
|
||||
@ -151,9 +143,8 @@ struct inode *ubifs_new_inode(struct ubifs_info *c, struct inode *dir,
|
||||
if (c->highest_inum >= INUM_WATERMARK) {
|
||||
spin_unlock(&c->cnt_lock);
|
||||
ubifs_err(c, "out of inode numbers");
|
||||
make_bad_inode(inode);
|
||||
iput(inode);
|
||||
return ERR_PTR(-EINVAL);
|
||||
err = -EINVAL;
|
||||
goto out_iput;
|
||||
}
|
||||
ubifs_warn(c, "running out of inode numbers (current %lu, max %u)",
|
||||
(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);
|
||||
|
||||
if (encrypted) {
|
||||
err = fscrypt_inherit_context(dir, inode, &encrypted, true);
|
||||
err = fscrypt_set_context(inode, NULL);
|
||||
if (err) {
|
||||
ubifs_err(c, "fscrypt_inherit_context failed: %i", err);
|
||||
make_bad_inode(inode);
|
||||
iput(inode);
|
||||
return ERR_PTR(err);
|
||||
ubifs_err(c, "fscrypt_set_context failed: %i", err);
|
||||
goto out_iput;
|
||||
}
|
||||
}
|
||||
|
||||
return inode;
|
||||
|
||||
out_iput:
|
||||
make_bad_inode(inode);
|
||||
iput(inode);
|
||||
return ERR_PTR(err);
|
||||
}
|
||||
|
||||
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)
|
||||
return err;
|
||||
|
||||
err = fscrypt_fname_alloc_buffer(dir, UBIFS_MAX_NLEN, &fstr);
|
||||
err = fscrypt_fname_alloc_buffer(UBIFS_MAX_NLEN, &fstr);
|
||||
if (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)
|
||||
{
|
||||
#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);
|
||||
return;
|
||||
}
|
||||
|
@ -213,7 +213,7 @@ struct dentry_operations {
|
||||
|
||||
#define DCACHE_MAY_FREE 0x00800000
|
||||
#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_PAR_LOOKUP 0x10000000 /* being looked up (with parent locked shared) */
|
||||
|
@ -15,13 +15,12 @@
|
||||
|
||||
#include <linux/fs.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/parser.h>
|
||||
#include <linux/slab.h>
|
||||
#include <uapi/linux/fscrypt.h>
|
||||
|
||||
#define FS_CRYPTO_BLOCK_SIZE 16
|
||||
|
||||
union fscrypt_context;
|
||||
union fscrypt_policy;
|
||||
struct fscrypt_info;
|
||||
struct seq_file;
|
||||
|
||||
@ -36,7 +35,7 @@ struct fscrypt_name {
|
||||
u32 hash;
|
||||
u32 minor_hash;
|
||||
struct fscrypt_str crypto_buf;
|
||||
bool is_ciphertext_name;
|
||||
bool is_nokey_name;
|
||||
};
|
||||
|
||||
#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 (*set_context)(struct inode *inode, const void *ctx, size_t len,
|
||||
void *fs_data);
|
||||
const union fscrypt_context *(*get_dummy_context)(
|
||||
struct super_block *sb);
|
||||
const union fscrypt_policy *(*get_dummy_policy)(struct super_block *sb);
|
||||
bool (*empty_dir)(struct inode *inode);
|
||||
unsigned int max_namelen;
|
||||
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);
|
||||
}
|
||||
|
||||
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
|
||||
* alias as a result of the encryption key being added, DCACHE_ENCRYPTED_NAME
|
||||
* must be cleared. Note that we don't have to support arbitrary moves of this
|
||||
* flag because fscrypt doesn't allow encrypted aliases to be the source or
|
||||
* target of a rename().
|
||||
* When d_splice_alias() moves a directory's no-key alias to its plaintext alias
|
||||
* as a result of the encryption key being added, DCACHE_NOKEY_NAME must be
|
||||
* cleared. Note that we don't have to support arbitrary moves of this flag
|
||||
* because fscrypt doesn't allow no-key names to be the source or target of a
|
||||
* rename().
|
||||
*/
|
||||
static inline void fscrypt_handle_d_move(struct dentry *dentry)
|
||||
{
|
||||
dentry->d_flags &= ~DCACHE_ENCRYPTED_NAME;
|
||||
dentry->d_flags &= ~DCACHE_NOKEY_NAME;
|
||||
}
|
||||
|
||||
/* 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_nonce(struct file *filp, void __user *arg);
|
||||
int fscrypt_has_permitted_context(struct inode *parent, struct inode *child);
|
||||
int fscrypt_inherit_context(struct inode *parent, struct inode *child,
|
||||
void *fs_data, bool preload);
|
||||
int fscrypt_set_context(struct inode *inode, void *fs_data);
|
||||
|
||||
struct fscrypt_dummy_context {
|
||||
const union fscrypt_context *ctx;
|
||||
struct fscrypt_dummy_policy {
|
||||
const union fscrypt_policy *policy;
|
||||
};
|
||||
|
||||
int fscrypt_set_test_dummy_encryption(struct super_block *sb,
|
||||
const substring_t *arg,
|
||||
struct fscrypt_dummy_context *dummy_ctx);
|
||||
int fscrypt_set_test_dummy_encryption(struct super_block *sb, const char *arg,
|
||||
struct fscrypt_dummy_policy *dummy_policy);
|
||||
void fscrypt_show_test_dummy_encryption(struct seq_file *seq, char sep,
|
||||
struct super_block *sb);
|
||||
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);
|
||||
dummy_ctx->ctx = NULL;
|
||||
kfree(dummy_policy->policy);
|
||||
dummy_policy->policy = NULL;
|
||||
}
|
||||
|
||||
/* keyring.c */
|
||||
@ -185,6 +173,8 @@ int fscrypt_ioctl_get_key_status(struct file *filp, void __user *arg);
|
||||
|
||||
/* keysetup.c */
|
||||
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_free_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);
|
||||
}
|
||||
|
||||
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);
|
||||
void fscrypt_fname_free_buffer(struct fscrypt_str *crypto_str);
|
||||
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,
|
||||
const u8 *de_name, u32 de_name_len);
|
||||
u64 fscrypt_fname_siphash(const struct inode *dir, const struct qstr *name);
|
||||
int fscrypt_d_revalidate(struct dentry *dentry, unsigned int flags);
|
||||
|
||||
/* bio.c */
|
||||
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);
|
||||
int fscrypt_prepare_setflags(struct inode *inode,
|
||||
unsigned int oldflags, unsigned int flags);
|
||||
int __fscrypt_prepare_symlink(struct inode *dir, unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
int fscrypt_prepare_symlink(struct inode *dir, const char *target,
|
||||
unsigned int len, unsigned int max_len,
|
||||
struct fscrypt_str *disk_link);
|
||||
int __fscrypt_encrypt_symlink(struct inode *inode, const char *target,
|
||||
unsigned int len, struct fscrypt_str *disk_link);
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -341,14 +326,12 @@ static inline int fscrypt_has_permitted_context(struct inode *parent,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_inherit_context(struct inode *parent,
|
||||
struct inode *child,
|
||||
void *fs_data, bool preload)
|
||||
static inline int fscrypt_set_context(struct inode *inode, void *fs_data)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
struct fscrypt_dummy_context {
|
||||
struct fscrypt_dummy_policy {
|
||||
};
|
||||
|
||||
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
|
||||
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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
return;
|
||||
@ -429,8 +421,7 @@ static inline void fscrypt_free_filename(struct fscrypt_name *fname)
|
||||
return;
|
||||
}
|
||||
|
||||
static inline int fscrypt_fname_alloc_buffer(const struct inode *inode,
|
||||
u32 max_encrypted_len,
|
||||
static inline int fscrypt_fname_alloc_buffer(u32 max_encrypted_len,
|
||||
struct fscrypt_str *crypto_str)
|
||||
{
|
||||
return -EOPNOTSUPP;
|
||||
@ -465,6 +456,12 @@ static inline u64 fscrypt_fname_siphash(const struct inode *dir,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int fscrypt_d_revalidate(struct dentry *dentry,
|
||||
unsigned int flags)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* bio.c */
|
||||
static inline void fscrypt_decrypt_bio(struct bio *bio)
|
||||
{
|
||||
@ -514,15 +511,21 @@ static inline int fscrypt_prepare_setflags(struct inode *inode,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int __fscrypt_prepare_symlink(struct inode *dir,
|
||||
unsigned int len,
|
||||
unsigned int max_len,
|
||||
struct fscrypt_str *disk_link)
|
||||
static inline int fscrypt_prepare_symlink(struct inode *dir,
|
||||
const char *target,
|
||||
unsigned int len,
|
||||
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,
|
||||
const char *target,
|
||||
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
|
||||
*
|
||||
* 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
|
||||
* can be done with or without the directory's encryption key; without the key,
|
||||
* filenames are presented in encrypted form. Therefore, we'll try to set up
|
||||
* the directory's encryption key, but even without it the lookup can continue.
|
||||
* the name that will actually be used to search the directory on-disk. If the
|
||||
* directory's encryption key is available, then the lookup is assumed to be by
|
||||
* plaintext name; otherwise, it is assumed to be by no-key name.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* Return: 0 on success; -ENOENT if key is unavailable but the filename isn't a
|
||||
* correctly formed encoded ciphertext name, so a negative dentry should be
|
||||
* created; or another -errno code.
|
||||
* Return: 0 on success; -ENOENT if the directory's key is unavailable but the
|
||||
* filename isn't a valid no-key name, so a negative dentry should be created;
|
||||
* or another -errno code.
|
||||
*/
|
||||
static inline int fscrypt_prepare_lookup(struct inode *dir,
|
||||
struct dentry *dentry,
|
||||
@ -821,45 +823,6 @@ static inline int fscrypt_prepare_setattr(struct dentry *dentry,
|
||||
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
|
||||
* @inode: symlink inode
|
||||
|
@ -45,7 +45,6 @@ struct fscrypt_policy_v1 {
|
||||
__u8 flags;
|
||||
__u8 master_key_descriptor[FSCRYPT_KEY_DESCRIPTOR_SIZE];
|
||||
};
|
||||
#define fscrypt_policy fscrypt_policy_v1
|
||||
|
||||
/*
|
||||
* Process-subscribed "logon" key description prefix and payload format.
|
||||
@ -159,9 +158,9 @@ struct fscrypt_get_key_status_arg {
|
||||
__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_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_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)
|
||||
@ -173,6 +172,7 @@ struct fscrypt_get_key_status_arg {
|
||||
|
||||
/* old names; don't add anything new here! */
|
||||
#ifndef __KERNEL__
|
||||
#define fscrypt_policy fscrypt_policy_v1
|
||||
#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_8 FSCRYPT_POLICY_FLAGS_PAD_8
|
||||
|
Loading…
Reference in New Issue
Block a user