Skip to content

Commit 37d11cf

Browse files
mjguzikbrauner
authored andcommitted
vfs: sanity check the length passed to inode_set_cached_link()
This costs a strlen() call when instatianating a symlink. Preferably it would be hidden behind VFS_WARN_ON (or compatible), but there is no such facility at the moment. With the facility in place the call can be patched out in production kernels. In the meantime, since the cost is being paid unconditionally, use the result to a fixup the bad caller. This is not expected to persist in the long run (tm). Sample splat: bad length passed for symlink [/tmp/syz-imagegen43743633/file0/file0] (got 131109, expected 37) [rest of WARN blurp goes here] Signed-off-by: Mateusz Guzik <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Christian Brauner <[email protected]>
1 parent 091ee63 commit 37d11cf

File tree

1 file changed

+13
-0
lines changed

1 file changed

+13
-0
lines changed

include/linux/fs.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -790,6 +790,19 @@ struct inode {
790790

791791
static inline void inode_set_cached_link(struct inode *inode, char *link, int linklen)
792792
{
793+
int testlen;
794+
795+
/*
796+
* TODO: patch it into a debug-only check if relevant macros show up.
797+
* In the meantime, since we are suffering strlen even on production kernels
798+
* to find the right length, do a fixup if the wrong value got passed.
799+
*/
800+
testlen = strlen(link);
801+
if (testlen != linklen) {
802+
WARN_ONCE(1, "bad length passed for symlink [%s] (got %d, expected %d)",
803+
link, linklen, testlen);
804+
linklen = testlen;
805+
}
793806
inode->i_link = link;
794807
inode->i_linklen = linklen;
795808
inode->i_opflags |= IOP_CACHED_LINK;

0 commit comments

Comments
 (0)