GDB problems inside docker
Asked Answered
C

1

3

With docker version Docker version 1.1.0, build 79812e3 on Ubuntu 13.04, and using the docker container created by:

# docker build -t gdb_problem_testing - < THIS_FILE
FROM ubuntu
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get install -y build-essential gdb

Doing this:

user@host $ sudo docker run --rm -it --user=root gdb_problem_testing su root -c bash
root@690396061e81:/# cat <<EOF > test.c && gcc -ggdb test.c -o test && gdb -ex run test
> #include <stdio.h>
>
> int main(int argc, char **argv) {
>     printf("Hello\n!");
> }
> EOF
GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /test...done.
Starting program: /test
user@host $

DOES NOT RUN THE PROGRAM. gdb just up and quits. Notice on the last line that I even got booted from the docker container and didn't return to the bash prompt (!)

I have not been able to reproduce this in a non-docker environment (su <some_user> -c bash etc).

This problem does not occur if I do not su <some_user> -c bash but instead just use bash. For various reasons, su must be used, mainly because it's the only way I've found to be able to enforce ulimits for a specific user in a docker container.

Why won't gdb work in this situation??

EDIT

copy-pastable command to run in docker container:

cat <<EOF > test.c && gcc -ggdb test.c -o test && gdb -ex run test
#include <stdio.h>

int main(int argc, char **argv) {
    printf("Hello\n!");
}
EOF

UPDATE

Just to show that it's the su command in a docker container that's messing things up, below is the output of doing the same thing with bash instead of su root -c bash:

user@host $ sudo docker run --rm -it --user=root gdb_problem_testing bash
root@ce1581184f7a:/# cat <<EOF > test.c && gcc -ggdb test.c -o test && gdb -ex run test
> #include <stdio.h>
>
> int main(int argc, char **argv) {
>     printf("Hello\n!");
> }
> EOF
GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /test...done.
Starting program: /test
warning: no loadable sections found in added symbol-file system-supplied DSO at 0x7ffff7ffa000
Hello
![Inferior 1 (process 17) exited with code 07]
(gdb)

Notice how the program actually ran (printed "Hello") and I stayed in gdb and in the docker container.

Calle answered 5/7, 2014 at 11:45 Comment(1)
Out of desperately trying random things, I happened to find a way around this. Do sudo -u root su root -c <cmd>. I HAVE NO IDEA WHY THIS SHOULD BE DIFFERENT, but it is. gdb will run, and all ulimits are still appliedCalle
P
2

This is due to apparmor. I have a solution but it needs to be applied after each boot.

The trick is to tell apparmor to 'complain' about security violations rather than block them. This isn't the most secure workaround, I'd really like to find a better way to deal with it (like only allow ptrace and whatever else GDB requires).

To tell apparmor to complain, you need to change the line in /etc/apparmor.d/docker from:

profile docker-default flags=(attach_disconnected,mediate_deleted) {

to:

profile docker-default flags=(attach_disconnected,mediate_deleted,complain) {
Prosthodontics answered 20/8, 2014 at 17:42 Comment(1)
Steven Van Acker proposes a solution [here][1], that survives boot. So in short, if you are on Ubuntu, do this on the host machine: 1. Install apparmor-utils with: sudo apt-get install apparmor-utils 2. Enable the complain mode for the docker apparmor config. sudo aa-complain /etc/apparmor.d/docker 3. Make the above command persistent across reboots: sudo echo "aa-complain /etc/apparmor.d/docker" >> /etc/rc.local [1]: github.com/docker/docker/issues/7276#issuecomment-50436671Dowlen

© 2022 - 2024 — McMap. All rights reserved.