2

I created a chroot jail and copied multiple binaries and their corresponding libraries to the relevant subdirectories. Example:

cp -v /usr/bin/edit /home/jail/usr/bin
ldd /usr/bin/edit
        linux-vdso.so.1 (0x00007fff565ae000)
        libm.so.6 => /lib64/libm.so.6 (0x00007f7749145000)
        libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f7748f11000)
        libacl.so.1 => /lib64/libacl.so.1 (0x00007f7748d08000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f7748b04000)
        libperl.so => /usr/lib/perl5/5.18.2/x86_64-linux-thread-multi/CORE/libperl.so (0x00007f7748771000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7748554000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f77481ad000)
        libattr.so.1 => /lib64/libattr.so.1 (0x00007f7747fa8000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f7749446000)
        libcrypt.so.1 => /lib64/libcrypt.so.1 (0x00007f7747d6d000)
cp -v /lib64/{libm.so.6,libtinfo.so.5,libacl.so.1,libdl.so.2,libpthread.so.0,libc.so.6,libattr.so.1,ld-linux-x86-64.so.2,libcrypt.so.1} /home/jail/lib64/

I did the same with the man command and copied all manual files with cp -rv /usr/share/man/ /home/jail/usr/share/, but if I execute it, it returns this error:

-bash-4.2$ man gzip
execve: No such file or directory

What could be missing?

More details:

-bash-4.2$ ls /usr/share/man
ca  da  el  es  fr.ISO8859-1  hu  it  man0p  man1p  man3   man4  man6  man8  mann  pl  pt_BR  sk  sv  zh     zh_TW
cs  de  eo  fr  fr.UTF-8      id  ja  man1   man2   man3p  man5  man7  man9  nl    pt  ru     sr  uk  zh_CN

Update:

-bash-4.2$ strace -f /usr/bin/mandb ls 2>ls.log
-bash-4.2$ cat ls.log
execve("/usr/bin/mandb", ["/usr/bin/mandb", "ls"], [/* 45 vars */]) = 0
brk(0)                                  = 0x138b000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd43a9ac000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/lib64/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib64/tls/x86_64", 0x7ffde87d2510) = -1 ENOENT (No such file or directory)
open("/lib64/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib64/tls", 0x7ffde87d2510)      = -1 ENOENT (No such file or directory)
open("/lib64/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
stat("/lib64/x86_64", 0x7ffde87d2510)   = -1 ENOENT (No such file or directory)
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\20\34\2\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1974416, ...}) = 0
mmap(NULL, 3828256, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7fd43a3e6000
mprotect(0x7fd43a584000, 2093056, PROT_NONE) = 0
mmap(0x7fd43a783000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x19d000) = 0x7fd43a783000
mmap(0x7fd43a789000, 14880, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7fd43a789000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd43a9ab000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd43a9aa000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7fd43a9a9000
arch_prctl(ARCH_SET_FS, 0x7fd43a9aa700) = 0
mprotect(0x7fd43a783000, 16384, PROT_READ) = 0
mprotect(0x601000, 4096, PROT_READ)     = 0
mprotect(0x7fd43a9ad000, 4096, PROT_READ) = 0
brk(0)                                  = 0x138b000
brk(0x13ac000)                          = 0x13ac000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/locale.alias", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de_DE.UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de_DE.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de_DE/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de.UTF-8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de.utf8/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("/usr/lib/locale/de/LC_CTYPE", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
getuid()                                = 1000
geteuid()                               = 1000
getgid()                                = 100
execve("/usr/lib/man-db/mandb", ["/usr/bin/mandb", "ls"], [/* 45 vars */]) = -1 ENOENT (No such file or directory)
dup(2)                                  = 3
fcntl(3, F_GETFL)                       = 0x8001 (flags O_WRONLY|O_LARGEFILE)
close(3)                                = 0
write(2, "execve: No such file or director"..., 34execve: No such file or directory
) = 34
exit_group(-22)                         = ?
+++ exited with 234 +++

Update2: Ok this part was missing:

cp -rv /usr/lib/man-db/ usr/lib/

Now I get this error:

man: error while loading shared libraries: libmandb-2.6.6.so: cannot open shared object file: No such file or directory

Strangely it's not part of the ldd return:

# which mandb
/usr/bin/mandb
# ldd /usr/bin/mandb
        linux-vdso.so.1 (0x00007fffd64d0000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f1885120000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f18854c7000)

Finally I needed those libraries:

cp /usr/lib64/libmandb-2.6.6.so usr/lib64/libmandb-2.6.6.so
cp /usr/lib64/libgdbm.so.4 usr/lib64/libgdbm.so.4

After that man loaded, but no text is displayed:

# man ls
Man: find all matching manual pages (set MAN_POSIXLY_CORRECT to avoid this)
 * ls (1)
   ls (1p)
Man: What manual page do you want?
Man: 1

enter image description here

I compared the strace results of the jail and root user and they differ now only in this part (jail is left): enter image description here

As I added a bind mount to /var/run/nscd, the socket is available for the jail user:

-bash-4.2$ if [[ -S /var/run/nscd/socket ]]; then echo "socket is available"; fi
socket is available

So the problem seems to be something else?!

Update3: @nobody Yes, passwd and group are present:

-bash-4.2$ ls -la /etc
total 124
drwxr-xr-x  4 root root   216 Nov 11 14:15 .
drwxr-xr-x 13 root root   183 Nov  4 08:49 ..
-rw-r--r--  1 root root   779 Nov  3 12:43 group
-rw-r--r--  1 root root 67659 Nov 11 13:55 ld.so.cache
-rw-r--r--  1 root root  2335 Nov  4 09:02 localtime
-rw-r--r--  1 root root 12061 Nov 11 13:16 manpath.config
-rw-r--r--  1 root root  1304 Nov 11 14:15 nsswitch.conf
-rw-r--r--  1 root root  3961 Nov  3 12:43 passwd
drwxr-xr-x  2 root root  4096 Nov  3 14:13 postfix
-rw-r--r--  1 root root  9168 Nov  4 09:02 profile
drwxr-xr-x  2 root root  4096 Nov  4 09:02 profile.d
-rw-r--r--  1 root root  8006 Nov  4 09:17 vimrc

Update4:

The -Tascii flag returned more missing binaries:

-bash-4.2$ man -Tascii ls
man: can't execute tbl: No such file or directory
man: can't execute groff: No such file or directory
man: command exited with status 255: /usr/bin/zsoelim | /usr/lib/man-db/manconv -f UTF-8:ISO-8859-1 -t ANSI_X3.4-1968//IGNORE | tbl | groff -mandoc -Tascii

So I copied tbl, groff and zsoelim and the complete dir /usr/share/groff. Now two additional binaries were missing:

-bash-4.2$ man -Tascii ls
groff: couldn't exec troff: No such file or directory
groff: couldn't exec grotty: No such file or directory
man: command exited with status 4: /usr/bin/zsoelim | /usr/lib/man-db/manconv -f UTF-8:ISO-8859-1 -t ANSI_X3.4-1968//IGNORE | tbl | groff -mandoc -Tascii

After copying these, the manual was displayed:

enter image description here

But without the -Tascii flag its still black/empty. :|

Update5:

Default pager seems to be less

-bash-4.2$ env | grep MANPATH
MANPATH=/usr/share/man
-bash-4.2$ env | grep PAGER
PAGER=less
2
  • 1
    Did you copy /etc/passwd, /etc/group to the jail. I think you should copy those files, too.
    – nobody
    Commented Nov 11, 2021 at 13:42
  • @nobody Yes, they are present. See Update3.
    – mgutt
    Commented Nov 11, 2021 at 13:44

2 Answers 2

5

You should type the command strace -f man ls 2>ls.log and see how many execve lines there are in the ls.log file. You will have /usr/bin/pager, nroff, groff, tbl… groff would surely need a lot of files to work properly. See how many openat in the log file are successful.

3
  • Thanks. This helped a lot. Now man starts, but does not display any text (see Update2 in my question) :|
    – mgutt
    Commented Nov 11, 2021 at 13:31
  • You can compare strace -f chroot … and strace -f …. There must be something missing, but the man ecosystem is a bit complex since it depends of groff. Note man -Tascii ls doesn’t load the pager and should be easier to debug with strace. NB : my Debian system doesn’t use a socket to nscd. Commented Nov 11, 2021 at 13:56
  • With the -Tascii flag and after copying tbl, groff, zsoelim, troff and grotty, the manual text is displayed, but with the default pager it's still black/empty. The default pager seems to be less, but less works. Even displaying .gz files works. And man -Tascii ls | less works, too.
    – mgutt
    Commented Nov 11, 2021 at 14:23
0

The missing proc file system + restricted socket access in the chroot jail could be the reasons based on the strace screenshot. As a work around an alias does the job quite well:

alias_man() { man -Tascii "$@" | pager; }
alias man='alias_man'

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .