if (contents_mode != filenames_mode) {
fscrypt_warn(inode, "Direct key flag not allowed with different contents and filenames modes"); returnfalse;
}
mode = &fscrypt_modes[contents_mode];
if (mode->ivsize < offsetofend(union fscrypt_iv, nonce)) {
fscrypt_warn(inode, "Direct key flag not allowed with %s",
mode->friendly_name); returnfalse;
} returntrue;
}
/* *IV_INO_LBLK_*existonlybecauseofhardwarelimitations,and *currentlytheonlyknownusecasefortheminvolvesAES-256-XTS. *That'salsoallwetestcurrently.Forthesereasons,fornowonly *allowAES-256-XTShere.Thiscanberelaxedlaterifausecasefor *IV_INO_LBLK_*withotherencryptionmodesarises.
*/ if (policy->contents_encryption_mode != FSCRYPT_MODE_AES_256_XTS) {
fscrypt_warn(inode, "Can't use %s policy with contents mode other than AES-256-XTS",
type); returnfalse;
}
/* *It'sunsafetoincludeinodenumbersintheIVsifthefilesystemcan *potentiallyrenumberinodes,e.g.viafilesystemshrinking.
*/ if (!sb->s_cop->has_stable_inodes ||
!sb->s_cop->has_stable_inodes(sb)) {
fscrypt_warn(inode, "Can't use %s policy on filesystem '%s' because it doesn't have stable inode numbers",
type, sb->s_id); returnfalse;
}
/* *IV_INO_LBLK_64andIV_INO_LBLK_32bothrequirethatinodenumbersfit *in32bits.Inprinciple,IV_INO_LBLK_32couldsupportlongerinode *numbersbecauseithashestheinodenumber;however,currentlythe *inodenumberisgottenfrominode::i_inowhichis'unsignedlong'. *Sofornowtheimplementationlimitis32bits.
*/ if (!sb->s_cop->has_32bit_inodes) {
fscrypt_warn(inode, "Can't use %s policy on filesystem '%s' because its inode numbers are too long",
type, sb->s_id); returnfalse;
}
/* *IV_INO_LBLK_64andIV_INO_LBLK_32bothrequirethatfiledataunit *indicesfitin32bits.
*/ if (fscrypt_max_file_dun_bits(sb,
fscrypt_policy_v2_du_bits(policy, inode)) > 32) {
fscrypt_warn(inode, "Can't use %s policy on filesystem '%s' because its maximum file size is too large",
type, sb->s_id); returnfalse;
} returntrue;
}
if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) &&
!supported_direct_key_modes(inode, policy->contents_encryption_mode,
policy->filenames_encryption_mode)) returnfalse;
if (IS_CASEFOLDED(inode)) { /* With v1, there's no way to derive dirhash keys. */
fscrypt_warn(inode, "v1 policies can't be used on casefolded directories"); returnfalse;
}
if (policy->log2_data_unit_size) { if (!inode->i_sb->s_cop->supports_subblock_data_units) {
fscrypt_warn(inode, "Filesystem does not support configuring crypto data unit size"); returnfalse;
} if (policy->log2_data_unit_size > inode->i_blkbits ||
policy->log2_data_unit_size < SECTOR_SHIFT /* 9 */) {
fscrypt_warn(inode, "Unsupported log2_data_unit_size in encryption policy: %d",
policy->log2_data_unit_size); returnfalse;
} if (policy->log2_data_unit_size != inode->i_blkbits &&
(policy->flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { /* *Notsafetoenableyet,asweneedtoensurethatDUN *wraparoundcanonlyoccuronaFSblockboundary.
*/
fscrypt_warn(inode, "Sub-block data units not yet supported with IV_INO_LBLK_32"); returnfalse;
}
}
if ((policy->flags & FSCRYPT_POLICY_FLAG_DIRECT_KEY) &&
!supported_direct_key_modes(inode, policy->contents_encryption_mode,
policy->filenames_encryption_mode)) returnfalse;
if ((policy->flags & (FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 |
FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) &&
!supported_iv_ino_lblk_policy(policy, inode)) returnfalse;
if (memchr_inv(policy->__reserved, 0, sizeof(policy->__reserved))) {
fscrypt_warn(inode, "Reserved bits set in encryption policy"); returnfalse;
}
staticint set_encryption_policy(struct inode *inode, constunion fscrypt_policy *policy)
{
u8 nonce[FSCRYPT_FILE_NONCE_SIZE]; union fscrypt_context ctx; int ctxsize; int err;
if (!fscrypt_supported_policy(policy, inode)) return -EINVAL;
switch (policy->version) { case FSCRYPT_POLICY_V1: /* *Theoriginalencryptionpolicyversionprovidednowayof *verifyingthatthecorrectmasterkeywassupplied,whichwas *insecureinscenarioswheremultipleusershaveaccesstothe *sameencryptedfiles(evenjustread-onlyaccess).Thenew *encryptionpolicyversionfixesthisandalsoimpliesuseof *animprovedkeyderivationfunctionandallowsnon-rootusers *tosecurelyremovekeys.Soaslongascompatibilitywith *oldkernelsisn'trequired,itisrecommendedtousethenew *policyversionforallnewencrypteddirectories.
*/
pr_warn_once("%s (pid %d) is setting deprecated v1 encryption policy; recommend upgrading to v2.\n",
current->comm, current->pid); break; case FSCRYPT_POLICY_V2:
err = fscrypt_verify_key_added(inode->i_sb,
policy->v2.master_key_identifier); if (err) return err; if (policy->v2.flags & FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)
pr_warn_once("%s (pid %d) is setting an IV_INO_LBLK_32 encryption policy. This should only be used if there are certain hardware limitations.\n",
current->comm, current->pid); break; default:
WARN_ON_ONCE(1); return -EINVAL;
}
int fscrypt_ioctl_set_policy(struct file *filp, constvoid __user *arg)
{ union fscrypt_policy policy; union fscrypt_policy existing_policy; struct inode *inode = file_inode(filp);
u8 version; int size; int ret;
if (get_user(policy.version, (const u8 __user *)arg)) return -EFAULT;
size = fscrypt_policy_size(&policy); if (size <= 0) return -EINVAL;
/* Original ioctl version; can only get the original policy version */ int fscrypt_ioctl_get_policy(struct file *filp, void __user *arg)
{ union fscrypt_policy policy; int err;
err = fscrypt_get_policy(file_inode(filp), &policy); if (err) return err;
if (policy.version != FSCRYPT_POLICY_V1) return -EINVAL;
if (copy_to_user(arg, &policy, sizeof(policy.v1))) return -EFAULT; return0;
}
EXPORT_SYMBOL(fscrypt_ioctl_get_policy);
/* Extended ioctl version; can get policies of any version */ int fscrypt_ioctl_get_policy_ex(struct file *filp, void __user *uarg)
{ struct fscrypt_get_policy_ex_arg arg; union fscrypt_policy *policy = (union fscrypt_policy *)&arg.policy;
size_t policy_size; int err;
/* arg is policy_size, then policy */
BUILD_BUG_ON(offsetof(typeof(arg), policy_size) != 0);
BUILD_BUG_ON(offsetofend(typeof(arg), policy_size) !=
offsetof(typeof(arg), policy));
BUILD_BUG_ON(sizeof(arg.policy) != sizeof(*policy));
/* No restrictions on file types which are never encrypted */ if (!S_ISREG(child->i_mode) && !S_ISDIR(child->i_mode) &&
!S_ISLNK(child->i_mode)) return1;
/* No restrictions if the parent directory is unencrypted */ if (!IS_ENCRYPTED(parent)) return1;
/* Encrypted directories must not contain unencrypted files */ if (!IS_ENCRYPTED(child)) return0;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.