hostfs __dentry_name() fix

use of strcpy() with overlapping source and destination is a UB;
 original loop hadn't been.  More to the point, the whole thing
 is much easier done with memcpy() + memmove().
 
 Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYIAB0WIQQqUNBr3gm4hGXdBJlZ7Krx/gZQ6wUCZ5yI4gAKCRBZ7Krx/gZQ
 632bAQCTq1Zgm9lNqvpqZTn6COZlZcG1Ux1qhzeIsvDsYUb+5QD9HCDBAIlLnOLp
 3C/PxpxE70NApXYhvvAYcF24dR43wAY=
 =CxjV
 -----END PGP SIGNATURE-----

Merge tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull hostfs fix from Al Viro:
 "Fix hostfs __dentry_name() string handling.

  The use of strcpy() with overlapping source and destination is a UB;
  original loop hadn't been. More to the point, the whole thing is much
  easier done with memcpy() + memmove()"

* tag 'pull-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
  hostfs: fix string handling in __dentry_name()
This commit is contained in:
Linus Torvalds 2025-01-31 09:33:54 -08:00
commit b2fde87318
1 changed files with 6 additions and 21 deletions

View File

@ -95,32 +95,17 @@ __uml_setup("hostfs=", hostfs_args,
static char *__dentry_name(struct dentry *dentry, char *name)
{
char *p = dentry_path_raw(dentry, name, PATH_MAX);
char *root;
size_t len;
struct hostfs_fs_info *fsi;
struct hostfs_fs_info *fsi = dentry->d_sb->s_fs_info;
char *root = fsi->host_root_path;
size_t len = strlen(root);
fsi = dentry->d_sb->s_fs_info;
root = fsi->host_root_path;
len = strlen(root);
if (IS_ERR(p)) {
if (IS_ERR(p) || len > p - name) {
__putname(name);
return NULL;
}
/*
* This function relies on the fact that dentry_path_raw() will place
* the path name at the end of the provided buffer.
*/
BUG_ON(p + strlen(p) + 1 != name + PATH_MAX);
strscpy(name, root, PATH_MAX);
if (len > p - name) {
__putname(name);
return NULL;
}
if (p > name + len)
strcpy(name + len, p);
memcpy(name, root, len);
memmove(name + len, p, name + PATH_MAX - p);
return name;
}