jessfraz / dockerfiles

Various Dockerfiles I use on the desktop and on servers.

Home Page:https://blog.jessfraz.com/post/docker-containers-on-the-desktop/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

MIT-SHM error solutions

mviereck opened this issue · comments

Running dockered GUI applications on host display :0 can lead to MIT-SHM errors and rendering issues. Sample setup:

xhost +     # security issue, you know
docker run -it \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -e DISPLAY=unix$DISPLAY \
    jess/gimp

Sample error message:

X Error of failed request:  BadValue (integer parameter out of range for operation)
  Major opcode of failed request:  130 (MIT-SHM)
  Minor opcode of failed request:  3 (X_ShmPutImage)
[...]

I got this MIT-SHM error quite often if I share host display :0. Though, normally it does not crash the application, but leads to rendering issues and artefacts after some time. (Some applications regard unix in unix$DISPLAY and don't use MIT-SHM. But that is not reliable.)

To avoid this error it is possible to disable IPC namespacing, thus allowing shared memory:

--ipc=host

I don't like the solution to disable IPC namespacing with --ipc=host because of isolation loss. Instead I prefer to run additional X servers with extension MIT-SHM disabled. Simpified example:

Displaynumber=50
Xephyr :$Displaynumber -retro -extension MIT-SHM &   # '-extension' disables, '+extension' enables 
sleep 1  # give Xephyr time to get ready
env DISPLAY=:$Displaynumber xfwm4 &  # window manager
docker run -it \
    -v /tmp/.X11-unix/X$Displaynumber:/tmp/.X11-unix/X$Displaynumber \
    -e DISPLAY=:$Displaynumber \
    jess/gimp

I gave a more extended example on stack overflow.


@jessfraz Hello jess!

I want to thank you for your work at docker and for your investigations to run GUI applications, too.

Inspired by your examples I developed a tool to run GUI applications and desktops in docker containers that also adresses X security issues and additionally provides features like sound and hardware acceleration.

I often thought about how to tell you about this without looking like someone who wants to advertise his project. Well, I take this opportunity, and I hope you like it.

The project is hosted on github: x11docker

Examples:

# LXDE desktop
x11docker --desktop x11docker/lxde
# GIMP
x11docker jess/gimp

Another possibility to avoid MIT-SHM error is to disable the extension in Xorg.
Create a file /etc/X11/xorg.conf.d/disable-MIT-SHM.conf with the content:

Section "Extensions"
    Option "MIT-SHM" "Disable"
EndSection

Though, this may cause a performance loss for all GUI applications (including those from host) as the shared memory provided by the MIT-SHM extension reduces copy operations in RAM.

Faking XShmQueryExtension(...)=false using LD_PRELOAD also works for the applications I tried (DBeaver, Sublime Text, Spicy), and it doesn't require messing with the host.

Open a shell Inside the container, create a docker_xnoshm.c file with the following content:

#include <X11/Xlib.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <X11/extensions/XShm.h>

Bool XShmQueryExtension(Display *display) {
	return 0;
}

Install gcc, libc-dev and libxext-dev (for Debian) and then run:

$ gcc docker_xnoshm.c -shared -o docker_xnoshm.so
$ export LD_PRELOAD=$(realpath docker_xnoshm.so)
$ your_application_here

Bonus: Dockerfile recipe

#####################
# BUILD XNOSHM HACK #
#####################
# See: https://github.com/jessfraz/dockerfiles/issues/359#issuecomment-828714848
FROM docker.io/library/alpine:3.13 AS docker_xnoshm

RUN apk add --no-cache gcc musl-dev libxext-dev

COPY docker_xnoshm.c /
RUN gcc /docker_xnoshm.c -shared -nostdlib -o /docker_xnoshm.so

################################################################################

# Use the image you want here
FROM docker.io/library/debian:buster

#######################
# INSTALL XNOSHM HACK #
#######################
COPY --from=docker_xnoshm /docker_xnoshm.so /usr/lib/docker_xnoshm.so
ENV LD_PRELOAD="/usr/lib/docker_xnoshm.so"

# ...

Another way that I've found that has a different set of tradeoffs is using an untrusted X11 cookie (NOTE: This is how ssh -X works). This enables the X11 SECURITY extension, which disables all extensions for the container, including MIT-SHM. It should also prevent applications inside the container from snooping on the host, without needing a separate X11 server.

The backdraw of this method is that performance is worse (due to disabled extensions) and some applications depend on X11 extensions so they just don't work.

Simple demo:

truncate -s0 /tmp/untrusted_cookie
xauth -f /tmp/untrusted_cookie generate "$DISPLAY" MIT-MAGIC-COOKIE-1 untrusted
untrusted_cookie_data=$(XAUTHORITY=/tmp/untrusted_cookie xauth list "$DISPLAY" | awk '{print $NF}')

truncate -s0 /tmp/untrusted_cookie_fixhost
xauth -f /tmp/untrusted_cookie_fixhost add somehostname/unix"$DISPLAY" MIT-MAGIC-COOKIE-1 "$untrusted_cookie_data"

docker run --hostname somehostname \
    -v /tmp/untrusted_cookie_fixhost:/root/.Xauthority \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -e DISPLAY="$DISPLAY" \
    -e XAUTHORITY=/root/.Xauthority \
    -it alpine:3.13 sh -c 'apk add xeyes && xeyes'

NOTE: You shouldn't stuff like xhost local:root when using this method, since that would allow the container to connect as a fully trusted client.

@joanbm I have tried your LD_PRELOAD proposal.
Unfortunately it does not seem to work.

I've compiled the script as you suggested, but still get MIT-SHM errors with some applications.
Testing on host with xdpyinfo still shows MIT-SHM:

$ LD_PRELOAD=$(pwd)/xnoshm.so xdpyinfo | grep MIT
    MIT-SCREEN-SAVER
    MIT-SHM

Do you have an idea what might be wrong?

@mviereck Just as a sanity check that the library is loading correctly, can you confirm that DBeaver / Spicy do never throw a MIT-SHM error when using LD_PRELOAD?

The reason xdpyinfo is still showing MIT-SHM is because my hack only patches XShmQueryExtension which is the most obvious way to check for SHM support (and for example Cairo and by extension GTK does it that way). But it is not foolproof, as there are other ways to check for it, like XListExtensions, which is what xdpyinfo uses.
That may also be why it may not be working for you, as possibly your application is checking for MIT-SHM support in another way.

Interestingly while looking around GitHub, I found the following code on GitHub which is a more robust version of the LD_PRELOAD hack:
https://github.com/mobdata/mobnode/blob/01fa78f67f01ade55b3dd6c4d8da088ed9507f9c/XlibNoSHM.c

Can you try to use this code in place of docker_xnoshm.c and see if it works for your application? At the very least, it should make xdpyinfo stop listing MIT-SHM.
EDIT: Also, to avoid a lot of stuff breaking due to symbols errors, change the last line of the Dockerfile from ENV LD_PRELOAD=... to:

ENV LD_PRELOAD=libdl.so.2:/usr/lib/docker_xnoshm.so

EDIT1: Also, change the #define LIBXLIB ... in the code with #define LIBXLIB "libXext.so.6"

Otherwise, it would be great to know which application(s) are failing, to find out how they are still detecting MIT-SHM support.

Thank you very much @joanbm !

The extended MIT-SHM hack along with the finetuning added with your post edits solved all issues!
xdpyinfo shows no MIT-SHM, and kaptain, that I used for diagnosis, throws no errors anymore.

@mviereck Hi,sorry to bother you here,I meet the same error when I try to run the orb slam2 in my container like below:
image
Actually I was running the gui in docker with wslg and it works well when I open other gui applications such as qv4l2:
image
I follow the instructions in the documention here and the command I used to create the container is as follows:
image
so why this problem only occurs when I am going to run orb slam,I have read the discussions between you and @joanbm,the problem seems to be solved by adding --ipc=host when creating the container.But I really don't want to create a new container to see if it works because I had a hard time getting the environment configured to run orb slam,so is there any other solutions can solve this by doing something inside the container?I would appreciate it if you can give me any suggestions:-)

@Hezhexi2002 It'd likely be better if you set up your container using a Dockerfile and/or volumes so you can re-create it quickly. But otherwise...

The LD_PRELOAD way I commented here can be done without restarting the container: #359 (comment)

Otherwise, you should be able to 'add' --ipc=host to your container doing something like this: https://stackoverflow.com/a/26622041 (haven't tested it myself, though).

@Hezhexi2002 As @joanbm pointed out, you can use his solution.
To elaborate on this, you can could compile the XlibNoSHM library and run within the container with LD_PRELOAD pointing to that library.

You could compile within the container, or, if the host has the same system, compile on host and use the shared /tmp/.X11-unix to copy the library into the contaner.
Once you have the compiled library in the container, run export LD_PRELOAD=/path/to/XlibNoSHM.so for all applications, or run env LD_PRELOAD=/path/to/XlibNoSHM.so COMMAND for each command.

@Hezhexi2002 As @joanbm pointed out, you can use his solution. To elaborate on this, you can could compile the XlibNoSHM library and run within the container with LD_PRELOAD pointing to that library.

You could compile within the container, or, if the host has the same system, compile on host and use the shared /tmp/.X11-unix to copy the library into the contaner. Once you have the compiled library in the container, run export LD_PRELOAD=/path/to/XlibNoSHM.so for all applications, or run env LD_PRELOAD=/path/to/XlibNoSHM.so COMMAND for each command.

ok,really thank you for your sincere reply,but the error disappeared as soon as I restart the container and run orb slam again.However,it throw the segmentation fault now like this:
image
I have submitted an issue under the original repo here and I also tried some solutions provided by google but still not solved.Anyway,thank you again for your patient answers, and I will try to use the solutions you provide if I encounter this error again.

@Hezhexi2002

The easiest solution for the MIT-SHM error is a change of xorg.conf: #359 (comment)
Xorg needs to be restarted afterwards. (Just reboot.)
If you still get segmentation faults after doing so, the issue is elsewhere.

@Hezhexi2002

The easiest solution for the MIT-SHM error is a change of xorg.conf: #359 (comment) Xorg needs to be restarted afterwards. (Just reboot.) If you still get segmentation faults after doing so, the issue is elsewhere.

Thanks for your patient reply,and now I have successfully run the orb slam2 in tum dataset:
image
but there is still having segmentation fault when I try to use my own rgbd camera:
image
I plan to use gdb to troubleshoot problems in the program,and I will inform you as soon as possible if there is any progress