Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

fscrypt: remove kernel-internal constants from UAPI header

There isn't really any valid reason to use __FSCRYPT_MODE_MAX or
FSCRYPT_POLICY_FLAGS_VALID in a userspace program. These constants are
only meant to be used by the kernel internally, and they are defined in
the UAPI header next to the mode numbers and flags only so that kernel
developers don't forget to update them when adding new modes or flags.

In https://lkml.kernel.org/r/20201005074133.1958633-2-satyat@google.com
there was an example of someone wanting to use __FSCRYPT_MODE_MAX in a
user program, and it was wrong because the program would have broken if
__FSCRYPT_MODE_MAX were ever increased. So having this definition
available is harmful. FSCRYPT_POLICY_FLAGS_VALID has the same problem.

So, remove these definitions from the UAPI header. Replace
FSCRYPT_POLICY_FLAGS_VALID with just listing the valid flags explicitly
in the one kernel function that needs it. Move __FSCRYPT_MODE_MAX to
fscrypt_private.h, remove the double underscores (which were only
present to discourage use by userspace), and add a BUILD_BUG_ON() and
comments to (hopefully) ensure it is kept in sync.

Keep the old name FS_POLICY_FLAGS_VALID, since it's been around for
longer and there's a greater chance that removing it would break source
compatibility with some program. Indeed, mtd-utils is using it in
an #ifdef, and removing it would introduce compiler warnings (about
FS_POLICY_FLAGS_PAD_* being redefined) into the mtd-utils build.
However, reduce its value to 0x07 so that it only includes the flags
with old names (the ones present before Linux 5.4), and try to make it
clear that it's now "frozen" and no new flags should be added to it.

Fixes: 2336d0deb2d4 ("fscrypt: use FSCRYPT_ prefix for uapi constants")
Cc: <stable@vger.kernel.org> # v5.4+
Link: https://lore.kernel.org/r/20201024005132.495952-1-ebiggers@kernel.org
Signed-off-by: Eric Biggers <ebiggers@google.com>

+16 -9
+6 -3
fs/crypto/fscrypt_private.h
··· 25 25 #define FSCRYPT_CONTEXT_V1 1 26 26 #define FSCRYPT_CONTEXT_V2 2 27 27 28 + /* Keep this in sync with include/uapi/linux/fscrypt.h */ 29 + #define FSCRYPT_MODE_MAX FSCRYPT_MODE_ADIANTUM 30 + 28 31 struct fscrypt_context_v1 { 29 32 u8 version; /* FSCRYPT_CONTEXT_V1 */ 30 33 u8 contents_encryption_mode; ··· 494 491 * Per-mode encryption keys for the various types of encryption policies 495 492 * that use them. Allocated and derived on-demand. 496 493 */ 497 - struct fscrypt_prepared_key mk_direct_keys[__FSCRYPT_MODE_MAX + 1]; 498 - struct fscrypt_prepared_key mk_iv_ino_lblk_64_keys[__FSCRYPT_MODE_MAX + 1]; 499 - struct fscrypt_prepared_key mk_iv_ino_lblk_32_keys[__FSCRYPT_MODE_MAX + 1]; 494 + struct fscrypt_prepared_key mk_direct_keys[FSCRYPT_MODE_MAX + 1]; 495 + struct fscrypt_prepared_key mk_iv_ino_lblk_64_keys[FSCRYPT_MODE_MAX + 1]; 496 + struct fscrypt_prepared_key mk_iv_ino_lblk_32_keys[FSCRYPT_MODE_MAX + 1]; 500 497 501 498 /* Hash key for inode numbers. Initialized only when needed. */ 502 499 siphash_key_t mk_ino_hash_key;
+1 -1
fs/crypto/keyring.c
··· 44 44 45 45 wipe_master_key_secret(&mk->mk_secret); 46 46 47 - for (i = 0; i <= __FSCRYPT_MODE_MAX; i++) { 47 + for (i = 0; i <= FSCRYPT_MODE_MAX; i++) { 48 48 fscrypt_destroy_prepared_key(&mk->mk_direct_keys[i]); 49 49 fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_64_keys[i]); 50 50 fscrypt_destroy_prepared_key(&mk->mk_iv_ino_lblk_32_keys[i]);
+3 -1
fs/crypto/keysetup.c
··· 56 56 select_encryption_mode(const union fscrypt_policy *policy, 57 57 const struct inode *inode) 58 58 { 59 + BUILD_BUG_ON(ARRAY_SIZE(fscrypt_modes) != FSCRYPT_MODE_MAX + 1); 60 + 59 61 if (S_ISREG(inode->i_mode)) 60 62 return &fscrypt_modes[fscrypt_policy_contents_mode(policy)]; 61 63 ··· 170 168 unsigned int hkdf_infolen = 0; 171 169 int err; 172 170 173 - if (WARN_ON(mode_num > __FSCRYPT_MODE_MAX)) 171 + if (WARN_ON(mode_num > FSCRYPT_MODE_MAX)) 174 172 return -EINVAL; 175 173 176 174 prep_key = &keys[mode_num];
+4 -1
fs/crypto/policy.c
··· 175 175 return false; 176 176 } 177 177 178 - if (policy->flags & ~FSCRYPT_POLICY_FLAGS_VALID) { 178 + if (policy->flags & ~(FSCRYPT_POLICY_FLAGS_PAD_MASK | 179 + FSCRYPT_POLICY_FLAG_DIRECT_KEY | 180 + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 | 181 + FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32)) { 179 182 fscrypt_warn(inode, "Unsupported encryption flags (0x%02x)", 180 183 policy->flags); 181 184 return false;
+2 -3
include/uapi/linux/fscrypt.h
··· 20 20 #define FSCRYPT_POLICY_FLAG_DIRECT_KEY 0x04 21 21 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_64 0x08 22 22 #define FSCRYPT_POLICY_FLAG_IV_INO_LBLK_32 0x10 23 - #define FSCRYPT_POLICY_FLAGS_VALID 0x1F 24 23 25 24 /* Encryption algorithms */ 26 25 #define FSCRYPT_MODE_AES_256_XTS 1 ··· 27 28 #define FSCRYPT_MODE_AES_128_CBC 5 28 29 #define FSCRYPT_MODE_AES_128_CTS 6 29 30 #define FSCRYPT_MODE_ADIANTUM 9 30 - #define __FSCRYPT_MODE_MAX 9 31 + /* If adding a mode number > 9, update FSCRYPT_MODE_MAX in fscrypt_private.h */ 31 32 32 33 /* 33 34 * Legacy policy version; ad-hoc KDF and no key verification. ··· 176 177 #define FS_POLICY_FLAGS_PAD_32 FSCRYPT_POLICY_FLAGS_PAD_32 177 178 #define FS_POLICY_FLAGS_PAD_MASK FSCRYPT_POLICY_FLAGS_PAD_MASK 178 179 #define FS_POLICY_FLAG_DIRECT_KEY FSCRYPT_POLICY_FLAG_DIRECT_KEY 179 - #define FS_POLICY_FLAGS_VALID FSCRYPT_POLICY_FLAGS_VALID 180 + #define FS_POLICY_FLAGS_VALID 0x07 /* contains old flags only */ 180 181 #define FS_ENCRYPTION_MODE_INVALID 0 /* never used */ 181 182 #define FS_ENCRYPTION_MODE_AES_256_XTS FSCRYPT_MODE_AES_256_XTS 182 183 #define FS_ENCRYPTION_MODE_AES_256_GCM 2 /* never used */