Hi,

Looking at cpio, i found what seems to be a way to bypass the
--no-absolute-filenames option, which supposedly prevents data to be
written outside of the current folder.

One just need to create a cpio archive that contains a symlink to the
required destination, then a file that appears to be from inside the
symlink (this requires a specially crafted cpio archive) :

1) there is no file called /tmp/blah
[cedric@x201 testings]$ ll
total 4
-rw-rw-r--. 1 cedric cedric 384 Jun  4 22:34 link.cpio
[cedric@x201 testings]$ ll /tmp/blah
ls: cannot access '/tmp/blah': No such file or directory

2) I extract the specially crafted cpio
[cedric@x201 testings]$ cpio -idv --no-absolute-filenames < link.cpio
link
link/blah
1 block

3) there is a file /tmp/blah
[cedric@x201 testings]$ ll
total 4
lrwxrwxrwx. 1 cedric cedric   5 Jun  4 22:21 link -> /tmp/
-rw-rw-r--. 1 cedric cedric 384 Jun  4 22:15 link.cpio
[cedric@x201 testings]$ ll /tmp/blah
-rw-rw-r--. 1 cedric cedric 3 Jun  4 22:21 /tmp/blah

The very naive patch attached makes use of safer_name_suffix() to sanitize
symlink's value.

Thanks!

-- 
Cedric Buissart,
Product Security
diff --git a/src/copyin.c b/src/copyin.c
index ba887ae..38ca70e 100644
--- a/src/copyin.c
+++ b/src/copyin.c
@@ -645,6 +645,7 @@ copyin_link (struct cpio_file_stat *file_hdr, int in_file_des)
       link_name = xstrdup (file_hdr->c_tar_linkname);
     }
 
+  cpio_safer_name_suffix (link_name, false, !no_abs_paths_flag, false);
   res = UMASKED_SYMLINK (link_name, file_hdr->c_name,
 			 file_hdr->c_mode);
   if (res < 0 && create_dir_flag)

Reply via email to