[Libguestfs] [PATCH supermin] ext2: Build symbolic links correctly (RHBZ#1770304).

Richard W.M. Jones rjones at redhat.com
Tue Nov 26 09:09:47 UTC 2019


We created symlinks in two steps, by creating the empty inode and then
calling ext2fs_symlink to populate it.  This created broken symlinks
where the directory name contained a / character, eg:

lrwxrwxrwx  1 root root     7 Nov 26 08:43 /bin -> usr/bin
lrwxrwxrwx  1 root root     7 Nov 26 08:43 /lib -> usr/lib
lrwxrwxrwx  1 root root     9 Nov 26 08:43 /lib64 -> usr/lib64
lrwxrwxrwx  1 root root     8 Nov 26 08:43 /sbin -> usr/sbin
lrwxrwxrwx  1 root root     7 Nov 26 08:38 bin -> usr/bin

This breaks with Linux >= 5.3.8, most likely because of extra
validation now being done at the VFS layer:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/readdir.c?id=8a23eb804ca4f2be909e372cf5a9e7b30ae476cd

It's unnecessary to create the empty inode since ext2fs_symlink can
create the inode for us perfectly fine if we simply pass ino == 0, and
it creates them correctly too.

Thanks: Toolybird for identifying the problem and kernel patch.
---
 src/ext2fs-c.c | 8 +-------
 1 file changed, 1 insertion(+), 7 deletions(-)

diff --git a/src/ext2fs-c.c b/src/ext2fs-c.c
index e8ab972..8903f74 100644
--- a/src/ext2fs-c.c
+++ b/src/ext2fs-c.c
@@ -782,12 +782,6 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest)
   }
   /* Create a symlink. */
   else if (S_ISLNK (statbuf.st_mode)) {
-    ext2_ino_t ino;
-    ext2_empty_inode (data->fs, dir_ino, dirname, basename,
-                      statbuf.st_mode, statbuf.st_uid, statbuf.st_gid,
-                      statbuf.st_ctime, statbuf.st_atime, statbuf.st_mtime,
-                      0, 0, EXT2_FT_SYMLINK, &ino);
-
     char *buf = malloc (statbuf.st_size+1);
     if (buf == NULL)
       caml_raise_out_of_memory ();
@@ -797,7 +791,7 @@ ext2_copy_file (struct ext2_data *data, const char *src, const char *dest)
     if (r > statbuf.st_size)
       r = statbuf.st_size;
     buf[r] = '\0';
-    ext2fs_symlink (data->fs, dir_ino, ino, dest, buf);
+    ext2fs_symlink (data->fs, dir_ino, 0, basename, buf);
     free (buf);
   }
   /* Create directory. */
-- 
2.23.0




More information about the Libguestfs mailing list