2021-07-02 06:55:29

by Eric Biggers

[permalink] [raw]
Subject: [PATCH 0/5] fscrypt: report correct st_size for encrypted symlinks

This series makes the stat() family of syscalls start reporting the
correct size for encrypted symlinks.

See patch 1 for a detailed explanation of the problem and solution.

Patch 1 adds a helper function that computes the correct size for an
encrypted symlink. Patches 2-4 make the filesystems with fscrypt
support use it, and patch 5 updates the documentation.

This series applies to mainline commit 3dbdb38e2869.

Eric Biggers (5):
fscrypt: add fscrypt_symlink_getattr() for computing st_size
ext4: report correct st_size for encrypted symlinks
f2fs: report correct st_size for encrypted symlinks
ubifs: report correct st_size for encrypted symlinks
fscrypt: remove mention of symlink st_size quirk from documentation

Documentation/filesystems/fscrypt.rst | 5 ---
fs/crypto/hooks.c | 44 +++++++++++++++++++++++++++
fs/ext4/symlink.c | 12 +++++++-
fs/f2fs/namei.c | 12 +++++++-
fs/ubifs/file.c | 13 +++++++-
include/linux/fscrypt.h | 7 +++++
6 files changed, 85 insertions(+), 8 deletions(-)


base-commit: 3dbdb38e286903ec220aaf1fb29a8d94297da246
--
2.32.0


2021-07-02 06:55:34

by Eric Biggers

[permalink] [raw]
Subject: [PATCH 4/5] ubifs: report correct st_size for encrypted symlinks

From: Eric Biggers <[email protected]>

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after ubifs_getattr() for
encrypted symlinks. This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: ca7f85be8d6c ("ubifs: Add support for encrypted symlinks")
Cc: [email protected]
Signed-off-by: Eric Biggers <[email protected]>
---
fs/ubifs/file.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c
index 2e4e1d159969..5cfa28cd00cd 100644
--- a/fs/ubifs/file.c
+++ b/fs/ubifs/file.c
@@ -1630,6 +1630,17 @@ static const char *ubifs_get_link(struct dentry *dentry,
return fscrypt_get_symlink(inode, ui->data, ui->data_len, done);
}

+static int ubifs_symlink_getattr(struct user_namespace *mnt_userns,
+ const struct path *path, struct kstat *stat,
+ u32 request_mask, unsigned int query_flags)
+{
+ ubifs_getattr(mnt_userns, path, stat, request_mask, query_flags);
+
+ if (IS_ENCRYPTED(d_inode(path->dentry)))
+ return fscrypt_symlink_getattr(path, stat);
+ return 0;
+}
+
const struct address_space_operations ubifs_file_address_operations = {
.readpage = ubifs_readpage,
.writepage = ubifs_writepage,
@@ -1655,7 +1666,7 @@ const struct inode_operations ubifs_file_inode_operations = {
const struct inode_operations ubifs_symlink_inode_operations = {
.get_link = ubifs_get_link,
.setattr = ubifs_setattr,
- .getattr = ubifs_getattr,
+ .getattr = ubifs_symlink_getattr,
.listxattr = ubifs_listxattr,
.update_time = ubifs_update_time,
};
--
2.32.0

2021-07-02 06:55:38

by Eric Biggers

[permalink] [raw]
Subject: [PATCH 5/5] fscrypt: remove mention of symlink st_size quirk from documentation

From: Eric Biggers <[email protected]>

Now that the correct st_size is reported for encrypted symlinks on all
filesystems, update the documentation accordingly.

Signed-off-by: Eric Biggers <[email protected]>
---
Documentation/filesystems/fscrypt.rst | 5 -----
1 file changed, 5 deletions(-)

diff --git a/Documentation/filesystems/fscrypt.rst b/Documentation/filesystems/fscrypt.rst
index 44b67ebd6e40..02ec57818920 100644
--- a/Documentation/filesystems/fscrypt.rst
+++ b/Documentation/filesystems/fscrypt.rst
@@ -1063,11 +1063,6 @@ astute users may notice some differences in behavior:

- DAX (Direct Access) is not supported on encrypted files.

-- The st_size of an encrypted symlink will not necessarily give the
- length of the symlink target as required by POSIX. It will actually
- give the length of the ciphertext, which will be slightly longer
- than the plaintext due to NUL-padding and an extra 2-byte overhead.
-
- The maximum length of an encrypted symlink is 2 bytes shorter than
the maximum length of an unencrypted symlink. For example, on an
EXT4 filesystem with a 4K block size, unencrypted symlinks can be up
--
2.32.0

2021-07-02 06:55:57

by Eric Biggers

[permalink] [raw]
Subject: [PATCH 3/5] f2fs: report correct st_size for encrypted symlinks

From: Eric Biggers <[email protected]>

The stat() family of syscalls report the wrong size for encrypted
symlinks, which has caused breakage in several userspace programs.

Fix this by calling fscrypt_symlink_getattr() after f2fs_getattr() for
encrypted symlinks. This function computes the correct size by reading
and decrypting the symlink target (if it's not already cached).

For more details, see the commit which added fscrypt_symlink_getattr().

Fixes: cbaf042a3cc6 ("f2fs crypto: add symlink encryption")
Cc: [email protected]
Signed-off-by: Eric Biggers <[email protected]>
---
fs/f2fs/namei.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/fs/f2fs/namei.c b/fs/f2fs/namei.c
index a9cd9cf97229..e2d540ae2293 100644
--- a/fs/f2fs/namei.c
+++ b/fs/f2fs/namei.c
@@ -1305,9 +1305,19 @@ static const char *f2fs_encrypted_get_link(struct dentry *dentry,
return target;
}

+static int f2fs_encrypted_symlink_getattr(struct user_namespace *mnt_userns,
+ const struct path *path,
+ struct kstat *stat, u32 request_mask,
+ unsigned int query_flags)
+{
+ f2fs_getattr(mnt_userns, path, stat, request_mask, query_flags);
+
+ return fscrypt_symlink_getattr(path, stat);
+}
+
const struct inode_operations f2fs_encrypted_symlink_inode_operations = {
.get_link = f2fs_encrypted_get_link,
- .getattr = f2fs_getattr,
+ .getattr = f2fs_encrypted_symlink_getattr,
.setattr = f2fs_setattr,
.listxattr = f2fs_listxattr,
};
--
2.32.0

2021-07-26 03:59:04

by Eric Biggers

[permalink] [raw]
Subject: Re: [PATCH 0/5] fscrypt: report correct st_size for encrypted symlinks

On Thu, Jul 01, 2021 at 11:53:45PM -0700, Eric Biggers wrote:
> This series makes the stat() family of syscalls start reporting the
> correct size for encrypted symlinks.
>
> See patch 1 for a detailed explanation of the problem and solution.
>
> Patch 1 adds a helper function that computes the correct size for an
> encrypted symlink. Patches 2-4 make the filesystems with fscrypt
> support use it, and patch 5 updates the documentation.
>
> This series applies to mainline commit 3dbdb38e2869.
>
> Eric Biggers (5):
> fscrypt: add fscrypt_symlink_getattr() for computing st_size
> ext4: report correct st_size for encrypted symlinks
> f2fs: report correct st_size for encrypted symlinks
> ubifs: report correct st_size for encrypted symlinks
> fscrypt: remove mention of symlink st_size quirk from documentation
>
> Documentation/filesystems/fscrypt.rst | 5 ---
> fs/crypto/hooks.c | 44 +++++++++++++++++++++++++++
> fs/ext4/symlink.c | 12 +++++++-
> fs/f2fs/namei.c | 12 +++++++-
> fs/ubifs/file.c | 13 +++++++-
> include/linux/fscrypt.h | 7 +++++
> 6 files changed, 85 insertions(+), 8 deletions(-)
>
>
> base-commit: 3dbdb38e286903ec220aaf1fb29a8d94297da246

All applied to fscrypt.git#master for 5.15.

- Eric