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. Commented Nov 11, 2021 at 13:42
  • @nobody Yes, they are present. See Update3. 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) :| 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. 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.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.