Unable to debug a program which was built inside the jail

I'm testing some debugging tools for C and C++ programs. If you're interested, these tools are: emacs+dap-mode+lldb-vscode (but most likely it's irrelevant for the purposes of this question).

My problem is that C program that was compiled using /usr/bin/clang from inside the jail (i.e. when i did jexec -U user test and went to jail) cannot be debugged (breakpoints do not stop the program). But if I take /usr/bin/clang from the host system (without going inside the jail), then such a binary file can be debugged immediately, breakpoints work and everything works. In both cases, we are talking about the *.c file and its binary file, which have the same location in the jail file system, but in the first case they are compiled by the internal jail's compiler, and in the second case (succesfull) - by the external clang from the host. The fact is that I did not provide any special security options for jail. Here are my settings:
Code:
exec.clean;
exec.start="sh /etc/rc";
exec.stop="sh /etc/rc.shutdown";
ip4=inherit;
mount.devfs;

test {
        allow.chflags=1;
        path="/test";
}

Subsequently, I added the following permission settings to this file:
Code:
allow.unprivileged_proc_debug=1;
allow.raw_sockets=1;
allow.mlock=1;
allow.read_msgbuf=1;

These settings had no effect.

Of course, I could use host compiler external to the jail. But I need compilers builded in a special way that live inside the jail.

Please, tell me jail or host system settings that would allow debugging files builded by compilers that live inside the jail.
 
What's in /etc/sysctl.conf
/etc/systctl.conf on host machine:
Code:
kern.coredump=0
kern.randompid=1
net.inet.ip.forwarding=1
net.inet.ip.fw.one_pass=0
net.link.bridge.ipfw=0
net.link.bridge.pfil_bridge=0
net.link.bridge.pfil_member=0
net.link.bridge.pfil_onlyip=0
net.link.tap.up_on_open=1
vfs.zfs.min_auto_ashift=12 # use sectors more than 4KiB
 
It works for me.

Code:
(host)# jexec -U user01 www /bin/sh
cd /tmp
$ cat << END > test.c
> #include <stdio.h>
>
> int main() {
> printf("hello\n");
> return 0;
> }
> END
$ clang -o test test.c
www(/tmp)# gdb -q ./test
Reading symbols from ./test...
(gdb) b main
Breakpoint 1 at 0x201894
(gdb) r
Starting program: /tmp/test

Breakpoint 1, 0x0000000000201894 in main ()
(gdb) x/3i $pc
=> 0x201894 <main+4>:    sub    $0x10,%rsp
   0x201898 <main+8>:    movl   $0x0,-0x4(%rbp)
   0x20189f <main+15>:    movabs $0x200538,%rdi
(gdb)
Using default settings.
 
  • Thanks
Reactions: dnb
It works for me.

Code:
(host)# jexec -U user01 www /bin/sh
cd /tmp
$ cat << END > test.c
> #include <stdio.h>
>
> int main() {
> printf("hello\n");
> return 0;
> }
> END
$ clang -o test test.c
www(/tmp)# gdb -q ./test
Reading symbols from ./test...
(gdb) b main
Breakpoint 1 at 0x201894
(gdb) r
Starting program: /tmp/test

Breakpoint 1, 0x0000000000201894 in main ()
(gdb) x/3i $pc
=> 0x201894 <main+4>:    sub    $0x10,%rsp
   0x201898 <main+8>:    movl   $0x0,-0x4(%rbp)
   0x20189f <main+15>:    movabs $0x200538,%rdi
(gdb)
Using default settings.
I have tested as you advised with gdb and lldb. It works both inside the jail and outside with files that have been built by external and internal compilers. Moreover, I even ran the lldb installed inside the jail via a direct path from the host machine. And it works too. Maybe these are some surprises related to the work of lldb-vscode.
 
Maybe these are some surprises related to the work of lldb-vscode.
I can't say for lldb as I don't use it. But gdb/lldb do use the ptrace syscall so I'd assume behavior around this would be the same.

For the sake of test it does make sense to store both binaries built from host and jail. Once you hit the problem do the comparison of these two (I'd guess they are the same but it doesn't hurt to check). Older versions of gdb did have problems hitting the breakpoint on PIE binaries (they were not aware of the PIE and they actually did literrally bp on PIE address).
 
  • Thanks
Reactions: dnb
Back
Top