Open raphaelcoeffic opened 2 years ago
Thanks for this issue @raphaelcoeffic -- I'll take a look!
The issue is with the bulk copying of the layer contents using cp -r
when dealing with symlinks at the directory level. cp doesn't recognize the unzipped directory symlink, /root/.tern/temp/3/contents/root
(symlinked to -> /data/root
) to be a valid directory replacement for copying to the working directory. Looping in @nishakm for ideas.
Adding the -L
option to cp and running cp -rL
, which may properly copy the adds significant overhead to the runtime (20+ minutes before I cancelled it vs 15 seconds for cp -r
). rsync may be an option?
@rnjudge To clarify, does the error occur when running cp -r container_layer_dir working_dir
where container_layer_dir
is a symlink to random_dir_path
?
@rnjudge To clarify, does the error occur when running
cp -r container_layer_dir working_dir
wherecontainer_layer_dir
is a symlink torandom_dir_path
?
@nishakm Yep! In this case, the dockerfile has something like: ln -s /data/root /root
in it and during analysis Tern tries to cp -r /root/.tern/temp/3/contents/root /root/.tern/temp/mergedir
but /root/.tern/temp/3/contents/root
is a symlink and therefore doesn't get recognized as a directory that can be copied to /root/.tern/temp/mergedir
.
Describe the bug
When running
tern
on a docker image that has this statement:The following error is spilled while
tern
is processing the layer:To Reproduce Steps to reproduce the behavior:
Dockerfile
that replaces/root
directory with a symlink somewhere elseFROM ${img}:${version}
RUN mkdir -p /data
RUN \ echo "\n#\n#\n# creating symlink from old root dir\n#\n#\n" && \ rm -rf /root && ln -s /data/root /root
docker build -t registry.mycompany.com/debian-systemd-tern-test .
docker push registry.mycompany.com/debian-systemd-tern-test
❯ docker run -it --rm -v /etc/docker/certs.d:/etc/containers/certs.d ternd report -i registry.mycompany.com/debian-systemd-tern-test:latest tern-test 14:10:28 2022-10-28 12:10:35,892 - DEBUG - main - Starting... 2022-10-28 12:10:35,892 - DEBUG - prep - Setting up... 2022-10-28 12:10:35,893 - DEBUG - rootfs - Running command: chmod +x /usr/local/lib/python3.9/site-packages/tern/tools/fs_hash.sh 2022-10-28 12:10:36,072 - DEBUG - run - Starting analysis... 2022-10-28 12:10:36,073 - DEBUG - skopeo - Attempting to pull image "registry.mycompany.com/debian-systemd-tern-test:latest" 2022-10-28 12:10:36,073 - DEBUG - rootfs - Running command: skopeo copy docker://registry.mycompany.com/debian-systemd-tern-test:latest dir:/root/.tern/temp 2022-10-28 12:10:40,253 - DEBUG - skopeo - Inspecting remote image "registry.mycompany.com/debian-systemd-tern-test:latest" 2022-10-28 12:10:40,254 - DEBUG - rootfs - Running command: skopeo inspect docker://registry.mycompany.com/debian-systemd-tern-test:latest 2022-10-28 12:10:40,434 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/17c9e6141fdb3387e5a1c07d4f9b6a05ac1498e96029fa3ea55470d4504f7770 2022-10-28 12:10:41,393 - DEBUG - rootfs - Running command: tar -x -f /root/.tern/temp/17c9e6141fdb3387e5a1c07d4f9b6a05ac1498e96029fa3ea55470d4504f7770 -C /root/.tern/temp/1/contents 2022-10-28 12:10:43,303 - DEBUG - rootfs - Running command: /usr/local/lib/python3.9/site-packages/tern/tools/fs_hash.sh /root/.tern/temp/1/contents 2022-10-28 12:11:02,121 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/67649db123fc6683600860faa84abd4735d3539d70ec4a65451d94ea357f38a3 2022-10-28 12:11:02,182 - DEBUG - rootfs - Running command: tar -x -f /root/.tern/temp/67649db123fc6683600860faa84abd4735d3539d70ec4a65451d94ea357f38a3 -C /root/.tern/temp/2/contents 2022-10-28 12:11:02,192 - DEBUG - rootfs - Running command: /usr/local/lib/python3.9/site-packages/tern/tools/fs_hash.sh /root/.tern/temp/2/contents 2022-10-28 12:11:02,207 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/de5f46f28e027af45576d5155b3e29d574a5153de48726416de2c6bae8934100 2022-10-28 12:11:02,235 - DEBUG - rootfs - Running command: tar -x -f /root/.tern/temp/de5f46f28e027af45576d5155b3e29d574a5153de48726416de2c6bae8934100 -C /root/.tern/temp/3/contents 2022-10-28 12:11:02,242 - DEBUG - rootfs - Running command: /usr/local/lib/python3.9/site-packages/tern/tools/fs_hash.sh /root/.tern/temp/3/contents 2022-10-28 12:11:02,250 - DEBUG - common - Reading files in filesystem... 2022-10-28 12:11:05,065 - DEBUG - rootfs - Running command: tar -tf /root/.tern/temp/17c9e6141fdb3387e5a1c07d4f9b6a05ac1498e96029fa3ea55470d4504f7770 2022-10-28 12:11:06,011 - DEBUG - rootfs - Running command: tar -x -f /root/.tern/temp/17c9e6141fdb3387e5a1c07d4f9b6a05ac1498e96029fa3ea55470d4504f7770 -C /root/.tern/temp/mergedir 2022-10-28 12:11:09,984 - DEBUG - rootfs - Running command: mknod /root/.tern/temp/mergedir/dev/urandom c 1 9 2022-10-28 12:11:10,022 - DEBUG - rootfs - Running command: cp /etc/resolv.conf /root/.tern/temp/mergedir/etc/resolv.conf 2022-10-28 12:11:10,038 - DEBUG - core - Collecting metadata for image layer... 2022-10-28 12:11:10,156 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c dpkg-query -W -f '${Version} ' 2022-10-28 12:11:10,319 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c pkgs=
dpkg-query -W -f '${Package} '
&& for p in $pkgs; do dpkg-query -f '${source:Version} ' -W $p; done 2022-10-28 12:11:10,580 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do dpkg-query -f '${source:Package} ' -W $p; done 2022-10-28 12:11:10,831 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do files=dpkg-query -L $p
; for file in $files; do if [ -f $file ]; then echo $file; fi; done; echo LICF; done 2022-10-28 12:11:11,370 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do /bin/cat /usr/share/doc/$p/copyright; echo LICF; done 2022-10-28 12:11:11,489 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c dpkg-query -W -f '${Package} ' 2022-10-28 12:11:11,496 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c dpkg-query -W -f '${Homepage} ' | /bin/sed 's/^$/Unknown/' 2022-10-28 12:11:11,523 - DEBUG - core - Processing Debian copyrights... 2022-10-28 12:11:11,731 - WARNING - core - Some metadata may be missing 2022-10-28 12:11:23,668 - DEBUG - common - Reading files in filesystem... 2022-10-28 12:11:23,686 - DEBUG - rootfs - Running command: cp -r /root/.tern/temp/2/contents/data /root/.tern/temp/mergedir 2022-10-28 12:11:23,885 - WARNING - command_lib - No listing method for 'mkdir'. Additional analysis may be required.2022-10-28 12:11:23,886 - DEBUG - core - Collecting metadata for image layer... 2022-10-28 12:11:23,886 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && dpkg-query -W -f '${Version} ' 2022-10-28 12:11:23,900 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && pkgs=
dpkg-query -W -f '${Package} '
&& for p in $pkgs; do dpkg-query -f '${source:Version} ' -W $p; done 2022-10-28 12:11:24,308 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do dpkg-query -f '${source:Package} ' -W $p; done 2022-10-28 12:11:24,580 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do files=dpkg-query -L $p
; for file in $files; do if [ -f $file ]; then echo $file; fi; done; echo LICF; done 2022-10-28 12:11:24,913 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && pkgs=dpkg-query -W -f '${Package} '
&& for p in $pkgs; do /bin/cat /usr/share/doc/$p/copyright; echo LICF; done 2022-10-28 12:11:25,009 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && dpkg-query -W -f '${Package} ' 2022-10-28 12:11:25,016 - DEBUG - rootfs - Running command: chroot /root/.tern/temp/mergedir /bin/sh -c export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" && dpkg-query -W -f '${Homepage} ' | /bin/sed 's/^$/Unknown/' 2022-10-28 12:11:25,024 - DEBUG - core - Processing Debian copyrights... 2022-10-28 12:11:25,218 - WARNING - core - Some metadata may be missing 2022-10-28 12:11:25,445 - DEBUG - rootfs - Running command: cp -r /root/.tern/temp/2/contents/data /root/.tern/temp/mergedir 2022-10-28 12:11:32,523 - DEBUG - common - Reading files in filesystem... 2022-10-28 12:11:32,523 - DEBUG - rootfs - Running command: cp -r /root/.tern/temp/3/contents/root /root/.tern/temp/mergedir 2022-10-28 12:11:32,527 - ERROR - rootfs - Command failed. cp: cannot overwrite directory '/root/.tern/temp/mergedir/root' with non-directoryTraceback (most recent call last): File "/usr/local/bin/tern", line 8, in
sys.exit(main())
File "/usr/local/lib/python3.9/site-packages/tern/main.py", line 309, in main
do_main(args)
File "/usr/local/lib/python3.9/site-packages/tern/main.py", line 123, in do_main
crun.execute_image(args)
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/run.py", line 80, in execute_image
cimage.default_analyze(full_image, args)
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/image.py", line 74, in default_analyze
multi_layer.analyze_subsequent_layers(
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/multi_layer.py", line 168, in analyze_subsequent_layers
fresh_analysis(image_obj, curr_layer, prereqs, options)
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/multi_layer.py", line 113, in fresh_analysis
target = prep_layers(image_obj, curr_layer, options.driver)
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/multi_layer.py", line 71, in prep_layers
return apply_layers(image_obj, top_layer)
File "/usr/local/lib/python3.9/site-packages/tern/analyze/default/container/multi_layer.py", line 63, in apply_layers
rootfs.root_command(['cp', '-r'] + glob.glob(layer_contents), target)
File "/usr/local/lib/python3.9/site-packages/tern/utils/rootfs.py", line 71, in root_command
raise subprocess.CalledProcessError( # nosec
subprocess.CalledProcessError: Command '['cp', '-r', '/root/.tern/temp/3/contents/root', '/root/.tern/temp/mergedir']' returned non-zero exit status 1.
Version: 2.10.1
❯ cat /etc/centos-release CentOS Linux release 7.9.2009 (Core)
❯ uname -a Linux docker 3.10.0-1160.76.1.el7.x86_64 #1 SMP Wed Aug 10 16:21:17 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
❯ docker run -it --rm --entrypoint /bin/bash ternd root@7d03c9e9c32b:/# python --version Python 3.9.15