|
@@ -35,11 +35,11 @@ static void fname_crypt_complete(struct crypto_async_request *req, int res)
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
/**
|
|
- * fname_encrypt() -
|
|
|
|
|
|
+ * fname_encrypt() - encrypt a filename
|
|
*
|
|
*
|
|
- * This function encrypts the input filename, and returns the length of the
|
|
|
|
- * ciphertext. Errors are returned as negative numbers. We trust the caller to
|
|
|
|
- * allocate sufficient memory to oname string.
|
|
|
|
|
|
+ * The caller must have allocated sufficient memory for the @oname string.
|
|
|
|
+ *
|
|
|
|
+ * Return: 0 on success, -errno on failure
|
|
*/
|
|
*/
|
|
static int fname_encrypt(struct inode *inode,
|
|
static int fname_encrypt(struct inode *inode,
|
|
const struct qstr *iname, struct fscrypt_str *oname)
|
|
const struct qstr *iname, struct fscrypt_str *oname)
|
|
@@ -105,20 +105,22 @@ static int fname_encrypt(struct inode *inode,
|
|
}
|
|
}
|
|
kfree(alloc_buf);
|
|
kfree(alloc_buf);
|
|
skcipher_request_free(req);
|
|
skcipher_request_free(req);
|
|
- if (res < 0)
|
|
|
|
|
|
+ if (res < 0) {
|
|
printk_ratelimited(KERN_ERR
|
|
printk_ratelimited(KERN_ERR
|
|
"%s: Error (error code %d)\n", __func__, res);
|
|
"%s: Error (error code %d)\n", __func__, res);
|
|
|
|
+ return res;
|
|
|
|
+ }
|
|
|
|
|
|
oname->len = ciphertext_len;
|
|
oname->len = ciphertext_len;
|
|
- return res;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-/*
|
|
|
|
- * fname_decrypt()
|
|
|
|
- * This function decrypts the input filename, and returns
|
|
|
|
- * the length of the plaintext.
|
|
|
|
- * Errors are returned as negative numbers.
|
|
|
|
- * We trust the caller to allocate sufficient memory to oname string.
|
|
|
|
|
|
+/**
|
|
|
|
+ * fname_decrypt() - decrypt a filename
|
|
|
|
+ *
|
|
|
|
+ * The caller must have allocated sufficient memory for the @oname string.
|
|
|
|
+ *
|
|
|
|
+ * Return: 0 on success, -errno on failure
|
|
*/
|
|
*/
|
|
static int fname_decrypt(struct inode *inode,
|
|
static int fname_decrypt(struct inode *inode,
|
|
const struct fscrypt_str *iname,
|
|
const struct fscrypt_str *iname,
|
|
@@ -168,7 +170,7 @@ static int fname_decrypt(struct inode *inode,
|
|
}
|
|
}
|
|
|
|
|
|
oname->len = strnlen(oname->name, iname->len);
|
|
oname->len = strnlen(oname->name, iname->len);
|
|
- return oname->len;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
static const char *lookup_table =
|
|
static const char *lookup_table =
|
|
@@ -279,6 +281,10 @@ EXPORT_SYMBOL(fscrypt_fname_free_buffer);
|
|
/**
|
|
/**
|
|
* fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
|
|
* fscrypt_fname_disk_to_usr() - converts a filename from disk space to user
|
|
* space
|
|
* space
|
|
|
|
+ *
|
|
|
|
+ * The caller must have allocated sufficient memory for the @oname string.
|
|
|
|
+ *
|
|
|
|
+ * Return: 0 on success, -errno on failure
|
|
*/
|
|
*/
|
|
int fscrypt_fname_disk_to_usr(struct inode *inode,
|
|
int fscrypt_fname_disk_to_usr(struct inode *inode,
|
|
u32 hash, u32 minor_hash,
|
|
u32 hash, u32 minor_hash,
|
|
@@ -287,13 +293,12 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
|
|
{
|
|
{
|
|
const struct qstr qname = FSTR_TO_QSTR(iname);
|
|
const struct qstr qname = FSTR_TO_QSTR(iname);
|
|
char buf[24];
|
|
char buf[24];
|
|
- int ret;
|
|
|
|
|
|
|
|
if (fscrypt_is_dot_dotdot(&qname)) {
|
|
if (fscrypt_is_dot_dotdot(&qname)) {
|
|
oname->name[0] = '.';
|
|
oname->name[0] = '.';
|
|
oname->name[iname->len - 1] = '.';
|
|
oname->name[iname->len - 1] = '.';
|
|
oname->len = iname->len;
|
|
oname->len = iname->len;
|
|
- return oname->len;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
|
|
|
|
if (iname->len < FS_CRYPTO_BLOCK_SIZE)
|
|
if (iname->len < FS_CRYPTO_BLOCK_SIZE)
|
|
@@ -303,9 +308,9 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
|
|
return fname_decrypt(inode, iname, oname);
|
|
return fname_decrypt(inode, iname, oname);
|
|
|
|
|
|
if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) {
|
|
if (iname->len <= FS_FNAME_CRYPTO_DIGEST_SIZE) {
|
|
- ret = digest_encode(iname->name, iname->len, oname->name);
|
|
|
|
- oname->len = ret;
|
|
|
|
- return ret;
|
|
|
|
|
|
+ oname->len = digest_encode(iname->name, iname->len,
|
|
|
|
+ oname->name);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
if (hash) {
|
|
if (hash) {
|
|
memcpy(buf, &hash, 4);
|
|
memcpy(buf, &hash, 4);
|
|
@@ -315,15 +320,18 @@ int fscrypt_fname_disk_to_usr(struct inode *inode,
|
|
}
|
|
}
|
|
memcpy(buf + 8, iname->name + iname->len - 16, 16);
|
|
memcpy(buf + 8, iname->name + iname->len - 16, 16);
|
|
oname->name[0] = '_';
|
|
oname->name[0] = '_';
|
|
- ret = digest_encode(buf, 24, oname->name + 1);
|
|
|
|
- oname->len = ret + 1;
|
|
|
|
- return ret + 1;
|
|
|
|
|
|
+ oname->len = 1 + digest_encode(buf, 24, oname->name + 1);
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
|
|
EXPORT_SYMBOL(fscrypt_fname_disk_to_usr);
|
|
|
|
|
|
/**
|
|
/**
|
|
* fscrypt_fname_usr_to_disk() - converts a filename from user space to disk
|
|
* fscrypt_fname_usr_to_disk() - converts a filename from user space to disk
|
|
* space
|
|
* space
|
|
|
|
+ *
|
|
|
|
+ * The caller must have allocated sufficient memory for the @oname string.
|
|
|
|
+ *
|
|
|
|
+ * Return: 0 on success, -errno on failure
|
|
*/
|
|
*/
|
|
int fscrypt_fname_usr_to_disk(struct inode *inode,
|
|
int fscrypt_fname_usr_to_disk(struct inode *inode,
|
|
const struct qstr *iname,
|
|
const struct qstr *iname,
|
|
@@ -333,7 +341,7 @@ int fscrypt_fname_usr_to_disk(struct inode *inode,
|
|
oname->name[0] = '.';
|
|
oname->name[0] = '.';
|
|
oname->name[iname->len - 1] = '.';
|
|
oname->name[iname->len - 1] = '.';
|
|
oname->len = iname->len;
|
|
oname->len = iname->len;
|
|
- return oname->len;
|
|
|
|
|
|
+ return 0;
|
|
}
|
|
}
|
|
if (inode->i_crypt_info)
|
|
if (inode->i_crypt_info)
|
|
return fname_encrypt(inode, iname, oname);
|
|
return fname_encrypt(inode, iname, oname);
|
|
@@ -367,10 +375,10 @@ int fscrypt_setup_filename(struct inode *dir, const struct qstr *iname,
|
|
if (dir->i_crypt_info) {
|
|
if (dir->i_crypt_info) {
|
|
ret = fscrypt_fname_alloc_buffer(dir, iname->len,
|
|
ret = fscrypt_fname_alloc_buffer(dir, iname->len,
|
|
&fname->crypto_buf);
|
|
&fname->crypto_buf);
|
|
- if (ret < 0)
|
|
|
|
|
|
+ if (ret)
|
|
return ret;
|
|
return ret;
|
|
ret = fname_encrypt(dir, iname, &fname->crypto_buf);
|
|
ret = fname_encrypt(dir, iname, &fname->crypto_buf);
|
|
- if (ret < 0)
|
|
|
|
|
|
+ if (ret)
|
|
goto errout;
|
|
goto errout;
|
|
fname->disk_name.name = fname->crypto_buf.name;
|
|
fname->disk_name.name = fname->crypto_buf.name;
|
|
fname->disk_name.len = fname->crypto_buf.len;
|
|
fname->disk_name.len = fname->crypto_buf.len;
|