diff options
author | Richard Weinberger <richard@nod.at> | 2016-10-08 13:24:26 +0200 |
---|---|---|
committer | Richard Weinberger <richard@nod.at> | 2016-12-12 23:07:38 +0100 |
commit | ca7f85be8d6cf9ad1b6597e5d907ddbe392082a9 (patch) | |
tree | b676b86785108d7c4581441c10ad385e5fe7e8ca /fs/ubifs/file.c | |
parent | ubifs: Implement encrypted filenames (diff) | |
download | linux-ca7f85be8d6cf9ad1b6597e5d907ddbe392082a9.tar.xz linux-ca7f85be8d6cf9ad1b6597e5d907ddbe392082a9.zip |
ubifs: Add support for encrypted symlinks
Signed-off-by: Richard Weinberger <richard@nod.at>
Diffstat (limited to 'fs/ubifs/file.c')
-rw-r--r-- | fs/ubifs/file.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 4c50f8feb0d5..aa0625f4f642 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c @@ -1657,6 +1657,59 @@ static int ubifs_file_open(struct inode *inode, struct file *filp) return 0; } +static const char *ubifs_get_link(struct dentry *dentry, + struct inode *inode, + struct delayed_call *done) +{ + int err; + struct fscrypt_symlink_data *sd; + struct ubifs_inode *ui = ubifs_inode(inode); + struct fscrypt_str cstr; + struct fscrypt_str pstr; + + if (!ubifs_crypt_is_encrypted(inode)) + return ui->data; + + if (!dentry) + return ERR_PTR(-ECHILD); + + err = fscrypt_get_encryption_info(inode); + if (err) + return ERR_PTR(err); + + sd = (struct fscrypt_symlink_data *)ui->data; + cstr.name = sd->encrypted_path; + cstr.len = le16_to_cpu(sd->len); + + if (cstr.len == 0) + return ERR_PTR(-ENOENT); + + if ((cstr.len + sizeof(struct fscrypt_symlink_data) - 1) > ui->data_len) + return ERR_PTR(-EIO); + + err = fscrypt_fname_alloc_buffer(inode, cstr.len, &pstr); + if (err) + return ERR_PTR(err); + + err = fscrypt_fname_disk_to_usr(inode, 0, 0, &cstr, &pstr); + if (err) { + fscrypt_fname_free_buffer(&pstr); + return ERR_PTR(err); + } + + pstr.name[pstr.len] = '\0'; + + // XXX this probably won't happen anymore... + if (pstr.name[0] == '\0') { + fscrypt_fname_free_buffer(&pstr); + return ERR_PTR(-ENOENT); + } + + set_delayed_call(done, kfree_link, pstr.name); + return pstr.name; +} + + const struct address_space_operations ubifs_file_address_operations = { .readpage = ubifs_readpage, .writepage = ubifs_writepage, @@ -1681,7 +1734,7 @@ const struct inode_operations ubifs_file_inode_operations = { const struct inode_operations ubifs_symlink_inode_operations = { .readlink = generic_readlink, - .get_link = simple_get_link, + .get_link = ubifs_get_link, .setattr = ubifs_setattr, .getattr = ubifs_getattr, .listxattr = ubifs_listxattr, |