struct llcrypt_str *disk_link)
{
if ((IS_ENCRYPTED(dir) &&
- likely(llcrypt_policy_has_filename_enc(dir))) ||
+ llcrypt_policy_has_filename_enc(dir)) ||
llcrypt_dummy_context_enabled(dir))
return __llcrypt_prepare_symlink(dir, len, max_len, disk_link);
#ifndef __LIBCFS_DEBUG_H__
#define __LIBCFS_DEBUG_H__
+#include <linux/tty.h>
#include <linux/limits.h>
#include <uapi/linux/lnet/libcfs_debug.h>
void cfs_debug_init(void);
+static inline void cfs_tty_write_msg(const char *msg)
+{
+ struct tty_struct *tty;
+
+ tty = get_current_tty();
+ if (!tty)
+ return;
+ mutex_lock(&tty->atomic_write_lock);
+ tty_lock(tty);
+ if (tty->ops->write && tty->count > 0)
+ tty->ops->write(tty, msg, strlen(msg));
+ tty_unlock(tty);
+ mutex_unlock(&tty->atomic_write_lock);
+ wake_up_interruptible_poll(&tty->write_wait, POLL_OUT);
+ tty_kref_put(tty);
+}
+
#endif /* __LIBCFS_DEBUG_H__ */
return fname_decrypt(inode, iname, oname);
}
- if (unlikely(!llcrypt_policy_has_filename_enc(inode))) {
+ if (!llcrypt_policy_has_filename_enc(inode)) {
memcpy(oname->name, iname->name, iname->len);
oname->name[iname->len] = '\0';
oname->len = iname->len;
if (!lookup)
return -ENOKEY;
- if (unlikely(!llcrypt_policy_has_filename_enc(dir))) {
+ if (!llcrypt_policy_has_filename_enc(dir)) {
fname->disk_name.name = (unsigned char *)iname->name;
fname->disk_name.len = iname->len;
return 0;
struct llcrypt_symlink_data *sd;
unsigned int ciphertext_len;
- if (unlikely(!llcrypt_policy_has_filename_enc(inode)))
+ if (!llcrypt_policy_has_filename_enc(inode))
return 0;
err = llcrypt_require_key(inode);
* the ciphertext length, even though this is redundant with i_size.
*/
- if (unlikely(!llcrypt_policy_has_filename_enc(inode))) {
+ if (!llcrypt_policy_has_filename_enc(inode)) {
cstr.name = (unsigned char *)caddr;
cstr.len = strlen(cstr.name);
union llcrypt_policy policy;
union llcrypt_policy existing_policy;
struct inode *inode = file_inode(filp);
+ struct lustre_sb_info *lsi = s2lsi(inode->i_sb);
u8 version;
int size;
int ret;
return -EFAULT;
policy.version = version;
+ /* Force file/directory name encryption policy to null if
+ * LSI_FILENAME_ENC flag is not set on sb.
+ * This allows enabling filename encryption separately from data
+ * encryption, and can be useful for interoperability with
+ * encryption-unaware clients.
+ */
+ if (!(lsi->lsi_flags & LSI_FILENAME_ENC)) {
+ CWARN("inode %lu: forcing policy filenames_encryption_mode to null\n",
+ inode->i_ino);
+ cfs_tty_write_msg("\n\nForcing policy filenames_encryption_mode to null.\n\n");
+ switch (policy.version) {
+ case LLCRYPT_POLICY_V1:
+ policy.v1.filenames_encryption_mode = LLCRYPT_MODE_NULL;
+ break;
+ case LLCRYPT_POLICY_V2:
+ policy.v2.filenames_encryption_mode = LLCRYPT_MODE_NULL;
+ break;
+ }
+ }
+
if (!inode_owner_or_capable(&init_user_ns, inode))
return -EACCES;
};
#define LSI_UMOUNT_FAILOVER 0x00200000
+#ifndef HAVE_SUPER_SETUP_BDI_NAME
+#define LSI_BDI_INITIALIZED 0x00400000
+#endif
+#define LSI_FILENAME_ENC 0x00800000 /* enable name encryption */
#define s2lsi(sb) ((struct lustre_sb_info *)((sb)->s_fs_info))
#define s2lsi_nocast(sb) ((sb)->s_fs_info)
}
if (lltr.len > LLCRYPT_FNAME_MAX_UNDIGESTED_SIZE &&
!llcrypt_has_encryption_key(inode) &&
- likely(llcrypt_policy_has_filename_enc(inode))) {
+ llcrypt_policy_has_filename_enc(inode)) {
digested = 1;
/* Without the key for long names, set the dentry name
* to the representing struct ll_digest_filename. It
__u64 data_version = 0;
size_t namelen = strlen(name);
int lumlen = lmv_user_md_size(lum->lum_stripe_count, lum->lum_magic);
- bool oldformat = false;
int rc;
ENTRY;
if (is_root_inode(child_inode))
GOTO(out_iput, rc = -EINVAL);
- if (IS_ENCRYPTED(parent)) {
- if (unlikely(!llcrypt_policy_has_filename_enc(parent)))
- oldformat = true;
- } else if (IS_ENCRYPTED(child_inode) &&
- unlikely(!llcrypt_policy_has_filename_enc(child_inode))) {
- oldformat = true;
- }
- if (unlikely(oldformat)) {
- CDEBUG(D_SEC,
- "cannot migrate old format encrypted "DFID", please move to new enc dir first\n",
- PFID(ll_inode2fid(child_inode)));
- GOTO(out_iput, rc = -EUCLEAN);
- }
-
op_data = ll_prep_md_op_data(NULL, parent, NULL, name, namelen,
child_inode->i_mode, LUSTRE_OPC_ANY, NULL);
if (IS_ERR(op_data))
#define MAX_STRING_SIZE 128
#ifndef HAVE_SUPER_SETUP_BDI_NAME
-
-#define LSI_BDI_INITIALIZED 0x00400000
-
#ifndef HAVE_BDI_CAP_MAP_COPY
# define BDI_CAP_MAP_COPY 0
#endif
LDEBUGFS_SEQ_FOPS(ll_nosquash_nids);
+static int ll_filename_enc_seq_show(struct seq_file *m, void *v)
+{
+ struct super_block *sb = m->private;
+ struct lustre_sb_info *lsi = s2lsi(sb);
+
+ seq_printf(m, "%u\n", lsi->lsi_flags & LSI_FILENAME_ENC ? 1 : 0);
+ return 0;
+}
+
+static ssize_t ll_filename_enc_seq_write(struct file *file,
+ const char __user *buffer,
+ size_t count, loff_t *off)
+{
+ struct seq_file *m = file->private_data;
+ struct super_block *sb = m->private;
+ struct lustre_sb_info *lsi = s2lsi(sb);
+ bool val;
+ int rc;
+
+ rc = kstrtobool_from_user(buffer, count, &val);
+ if (rc)
+ return rc;
+
+ if (val)
+ lsi->lsi_flags |= LSI_FILENAME_ENC;
+ else
+ lsi->lsi_flags &= ~LSI_FILENAME_ENC;
+
+ return count;
+}
+
+LDEBUGFS_SEQ_FOPS(ll_filename_enc);
+
static int ll_pcc_seq_show(struct seq_file *m, void *v)
{
struct super_block *sb = m->private;
.fops = &ll_nosquash_nids_fops },
{ .name = "pcc",
.fops = &ll_pcc_fops, },
+ { .name = "enable_filename_encryption",
+ .fops = &ll_filename_enc_fops, },
{ NULL }
};
}
CDEBUG(D_MOUNT, "Mounting client %s\n", lmd->lmd_profile);
+ /* filename encryption is disabled by default */
+ lsi->lsi_flags &= ~LSI_FILENAME_ENC;
rc = lustre_start_mgc(sb);
if (rc) {
lustre_common_put_super(sb);
local testfile2=$testdir/${tfile}withveryverylongnametoexercisecode
local tmpfile=$TMP/${tfile}.tmp
local resfile=$TMP/${tfile}.res
+ local nameenc
local fid1
local fid2
local filecount=$($RUNAS find $testdir -type f | wc -l)
[ $filecount -eq 3 ] || error "found $filecount files"
+ # check enable_filename_encryption default value
+ nameenc=$(lctl get_param -n llite.*.enable_filename_encryption |
+ head -n1)
+ [ $nameenc -eq 0 ] ||
+ error "enable_filename_encryption should be 0 by default"
+
+ # $testfile and $testfile2 should exist because names are not encrypted
+ [ -f $testfile ] ||
+ error "$testfile should exist because name is not encrypted"
+ [ -f $testfile2 ] ||
+ error "$testfile should exist because name is not encrypted"
+
scrambledfiles=( $(find $testdir/ -maxdepth 1 -type f) )
$RUNAS hexdump -C ${scrambledfiles[0]} &&
error "reading ${scrambledfiles[0]} should fail without key"
fid1=$(path2fid $MOUNT/.fscrypt)
echo "With FILESET $tdir, .fscrypt FID is $fid1"
+ # enable name encryption
+ do_facet mgs $LCTL set_param -P llite.*.enable_filename_encryption=1
+ [ $? -eq 0 ] ||
+ error "set_param -P llite.*.enable_filename_encryption failed"
+
+ wait_update_facet --verbose client \
+ "$LCTL get_param -n llite.*.enable_filename_encryption | head -n1" \
+ 1 30 ||
+ error "enable_filename_encryption not set on client"
+
# encrypt 'vault' dir inside the subdir mount
echo -e 'mypass\nmypass' | su - $USER0 -c "fscrypt encrypt --verbose \
--source=custom_passphrase --name=protector $testdir" ||
$RUNAS fscrypt lock --verbose $testdir ||
error "fscrypt lock $testdir failed (4)"
+ # encfile should actually have its name encrypted
+ [ -f $testdir/encfile ] && error "encfile name should be encrypted"
+ filecount=$(find $testdir -type f | wc -l)
+ [ $filecount -eq 1 ] || error "found $filecount files instead of 1"
+
# remount client with encrypted dir as subdirectory mount
umount_client $MOUNT || error "umount $MOUNT failed (2)"
export FILESET=/$tdir/vault
$RUNAS fscrypt lock --verbose $DIR/$tdir/vault ||
error "fscrypt lock $DIR/$tdir/vault failed (5)"
+ # disable name encryption
+ do_facet mgs $LCTL set_param -P llite.*.enable_filename_encryption=0
+ [ $? -eq 0 ] ||
+ error "set_param -P llite.*.enable_filename_encryption failed"
+
+ wait_update_facet --verbose client \
+ "$LCTL get_param -n llite.*.enable_filename_encryption | head -n1" \
+ 0 30 ||
+ error "enable_filename_encryption not set back to default"
+
rm -rf $tmpfile $MOUNT/.fscrypt
}
run_test 54 "Encryption policies with fscrypt"