diff options
Diffstat (limited to 'fs/crypto')
| -rw-r--r-- | fs/crypto/fname.c | 89 | ||||
| -rw-r--r-- | fs/crypto/keyring.c | 2 | ||||
| -rw-r--r-- | fs/crypto/keysetup.c | 2 |
3 files changed, 8 insertions, 85 deletions
diff --git a/fs/crypto/fname.c b/fs/crypto/fname.c index 8e4c213d418b..a9a4432d12ba 100644 --- a/fs/crypto/fname.c +++ b/fs/crypto/fname.c @@ -16,6 +16,7 @@ #include <linux/export.h> #include <linux/namei.h> #include <linux/scatterlist.h> +#include <linux/base64.h> #include "fscrypt_private.h" @@ -71,7 +72,7 @@ struct fscrypt_nokey_name { /* Encoded size of max-size no-key name */ #define FSCRYPT_NOKEY_NAME_MAX_ENCODED \ - FSCRYPT_BASE64URL_CHARS(FSCRYPT_NOKEY_NAME_MAX) + BASE64_CHARS(FSCRYPT_NOKEY_NAME_MAX) static inline bool fscrypt_is_dot_dotdot(const struct qstr *str) { @@ -162,84 +163,6 @@ static int fname_decrypt(const struct inode *inode, return 0; } -static const char base64url_table[65] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"; - -#define FSCRYPT_BASE64URL_CHARS(nbytes) DIV_ROUND_UP((nbytes) * 4, 3) - -/** - * fscrypt_base64url_encode() - base64url-encode some binary data - * @src: the binary data to encode - * @srclen: the length of @src in bytes - * @dst: (output) the base64url-encoded string. Not NUL-terminated. - * - * Encodes data using base64url encoding, i.e. the "Base 64 Encoding with URL - * and Filename Safe Alphabet" specified by RFC 4648. '='-padding isn't used, - * as it's unneeded and not required by the RFC. base64url is used instead of - * base64 to avoid the '/' character, which isn't allowed in filenames. - * - * Return: the length of the resulting base64url-encoded string in bytes. - * This will be equal to FSCRYPT_BASE64URL_CHARS(srclen). - */ -static int fscrypt_base64url_encode(const u8 *src, int srclen, char *dst) -{ - u32 ac = 0; - int bits = 0; - int i; - char *cp = dst; - - for (i = 0; i < srclen; i++) { - ac = (ac << 8) | src[i]; - bits += 8; - do { - bits -= 6; - *cp++ = base64url_table[(ac >> bits) & 0x3f]; - } while (bits >= 6); - } - if (bits) - *cp++ = base64url_table[(ac << (6 - bits)) & 0x3f]; - return cp - dst; -} - -/** - * fscrypt_base64url_decode() - base64url-decode a string - * @src: the string to decode. Doesn't need to be NUL-terminated. - * @srclen: the length of @src in bytes - * @dst: (output) the decoded binary data - * - * Decodes a string using base64url encoding, i.e. the "Base 64 Encoding with - * URL and Filename Safe Alphabet" specified by RFC 4648. '='-padding isn't - * accepted, nor are non-encoding characters such as whitespace. - * - * This implementation hasn't been optimized for performance. - * - * Return: the length of the resulting decoded binary data in bytes, - * or -1 if the string isn't a valid base64url string. - */ -static int fscrypt_base64url_decode(const char *src, int srclen, u8 *dst) -{ - u32 ac = 0; - int bits = 0; - int i; - u8 *bp = dst; - - for (i = 0; i < srclen; i++) { - const char *p = strchr(base64url_table, src[i]); - - if (p == NULL || src[i] == 0) - return -1; - ac = (ac << 6) | (p - base64url_table); - bits += 6; - if (bits >= 8) { - bits -= 8; - *bp++ = (u8)(ac >> bits); - } - } - if (ac & ((1 << bits) - 1)) - return -1; - return bp - dst; -} - bool __fscrypt_fname_encrypted_size(const union fscrypt_policy *policy, u32 orig_len, u32 max_len, u32 *encrypted_len_ret) @@ -387,8 +310,8 @@ int fscrypt_fname_disk_to_usr(const struct inode *inode, nokey_name.sha256); size = FSCRYPT_NOKEY_NAME_MAX; } - oname->len = fscrypt_base64url_encode((const u8 *)&nokey_name, size, - oname->name); + oname->len = base64_encode((const u8 *)&nokey_name, size, + oname->name, false, BASE64_URLSAFE); return 0; } EXPORT_SYMBOL(fscrypt_fname_disk_to_usr); @@ -467,8 +390,8 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname, if (fname->crypto_buf.name == NULL) return -ENOMEM; - ret = fscrypt_base64url_decode(iname->name, iname->len, - fname->crypto_buf.name); + ret = base64_decode(iname->name, iname->len, + fname->crypto_buf.name, false, BASE64_URLSAFE); if (ret < (int)offsetof(struct fscrypt_nokey_name, bytes[1]) || (ret > offsetof(struct fscrypt_nokey_name, sha256) && ret != FSCRYPT_NOKEY_NAME_MAX)) { diff --git a/fs/crypto/keyring.c b/fs/crypto/keyring.c index 3adbd7167055..5e939ea3ac28 100644 --- a/fs/crypto/keyring.c +++ b/fs/crypto/keyring.c @@ -945,7 +945,7 @@ static void evict_dentries_for_decrypted_inodes(struct fscrypt_master_key *mk) list_for_each_entry(ci, &mk->mk_decrypted_inodes, ci_master_key_link) { inode = ci->ci_inode; spin_lock(&inode->i_lock); - if (inode->i_state & (I_FREEING | I_WILL_FREE | I_NEW)) { + if (inode_state_read(inode) & (I_FREEING | I_WILL_FREE | I_NEW)) { spin_unlock(&inode->i_lock); continue; } diff --git a/fs/crypto/keysetup.c b/fs/crypto/keysetup.c index 4bd3918f50e3..40fa05688d3a 100644 --- a/fs/crypto/keysetup.c +++ b/fs/crypto/keysetup.c @@ -834,7 +834,7 @@ int fscrypt_drop_inode(struct inode *inode) * userspace is still using the files, inodes can be dirtied between * then and now. We mustn't lose any writes, so skip dirty inodes here. */ - if (inode->i_state & I_DIRTY_ALL) + if (inode_state_read(inode) & I_DIRTY_ALL) return 0; /* |
