proot-me / proot

chroot, mount --bind, and binfmt_misc without privilege/setup for Linux
https://proot-me.github.io
GNU General Public License v2.0
2.02k stars 378 forks source link

proot: ./path/path.c:546: compare_paths2: Assertion `length1 > 0' failed. #182

Open zaoqi opened 5 years ago

zaoqi commented 5 years ago

Steps to Reproduce the Problem

do not mkdir tmp

  1. fakechroot fakeroot chroot . ./proot/src/proot -R alpine-minirootfs-3.10.1-x86_64

Specifications

zaoqi commented 5 years ago

if mkdir tmp

$ fakechroot fakeroot chroot . ./proot/src/proot -R alpine-minirootfs-3.10.1-x86_64
proot error: execve("/bin/sh"): No such file or directory
proot info: possible causes:
  * the program is a script but its interpreter (eg. /bin/sh) was not found;
  * the program is an ELF but its interpreter (eg. ld-linux.so) was not found;
  * the program is a foreign binary but qemu was not specified;
  * qemu does not work correctly (if specified);
  * the loader was not found or doesn't work.
fatal error: see `proot --help`.
proot error: can't chmod '/tmp/proot-22405-7CHcGd': No such file or directory
proot error: can't chdir to '/': No such file or directory
oxr463 commented 5 years ago

Interesting.. I'll look into it.

Thanks for providing such detailed debugging information!

0pq76r commented 4 years ago

I had a similar issue. The problem is, that the detranslate_path function somehow is called with empty strings for path and/or t_referrer.

Also length1 and length2 are of type size_t, thus, unsigned integers and by the looks of it the case length1==0 is supposed to be handled in the if statement immediately after the assert.

There's probably a better way to fix it, but this works for me: https://github.com/0pq76r/proot/commit/7d7479c490de083729253f120a5e9a9c5bd47d0c

V6ser commented 3 years ago

Still not fixed as of latest version.

angelsl commented 3 years ago

This is a bit tricky. At least one cause of this crash is when readlinkat is called with an empty string for the path, which is allowed: (see readlinkat(2))

Since Linux 2.6.39, pathname can be an empty string, in which case the call operates on the symbolic link referred to by dirfd (which should have been obtained using open(2) with the O_PATH and O_NOFOLLOW flags).

proot doesn't handle this case, and I'm not sure if simply making detranslate_path ignore an empty t_referrer is correct. In fact, I'm not sure if proot's readlinkat handling is otherwise correct at all.

ruanformigoni commented 1 year ago

Hi, I'm also experiencing this issue:

proot: ./path/path.c:547: compare_paths2: Assertion `length2 > 0' failed.

This makes pacman fail in arch. It also makes wine GUI fail when running inside the new root.

Edit: The changes provided by @0pq76r fix both issues.

alexhenrie commented 9 months ago

I am having the same problem. Here is a Dockerfile that reproduces it:

FROM ubuntu:mantic

RUN apt-get update && apt-get install -y proot systemd

RUN proot dpkg-reconfigure systemd

docker build . fails with the message:

0.402 proot: ./path/path.c:541: compare_paths2: Assertion `length2 > 0' failed.

Is there a workaround?