summaryrefslogtreecommitdiffstats
path: root/fs/ubifs/file.c
diff options
context:
space:
mode:
authorRichard Weinberger <richard@nod.at>2016-10-08 13:24:26 +0200
committerRichard Weinberger <richard@nod.at>2016-12-12 23:07:38 +0100
commitca7f85be8d6cf9ad1b6597e5d907ddbe392082a9 (patch)
treeb676b86785108d7c4581441c10ad385e5fe7e8ca /fs/ubifs/file.c
parentubifs: Implement encrypted filenames (diff)
downloadlinux-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.c55
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,