FS#41257 - [xorg-server] take advantage of the non-root X support

Attached to Project: Arch Linux
Opened by Daniel Micay (thestinger) - Friday, 18 July 2014, 18:37 GMT
Last edited by Laurent Carlier (lordheavy) - Thursday, 11 June 2015, 13:28 GMT
Task Type Feature Request
Category Packages: Testing
Status Closed
Assigned To Laurent Carlier (lordheavy)
Architecture All
Severity High
Priority Normal
Reported Version
Due in Version Undecided
Due Date Undecided
Percent Complete 100%
Votes 17
Private No

Details

The 1.16 release of xorg-server now supports running as non-root out-of-the-box. The /usr/bin/Xorg executable is now a shell script, running the Xorg.wrap setuid binary if it exists and otherwise falling back to Xorg.bin.

The necessary packaging steps are to make /usr/bin/Xorg a non-setuid binary, which will cause it to run as non-root if the driver does not require it.

Some users may be starting X automatically from a virtual console, and they will need to replace "exec startx" with "startx; exit" because the permissions do not seem to be handed off correctly with "exec". A post-install message and perhaps even a news item would be nice to deal with that.

The second step is to split the Xorg.wrap binary out into a second package (xorg-server-setuid-wrapper) and have video drivers like nvidia, catalyst and the various UMS drivers depend on it. This will remove a significant attack surface from the system.

https://hansdegoede.livejournal.com/14268.html
This task depends upon

Closed by  Laurent Carlier (lordheavy)
Thursday, 11 June 2015, 13:28 GMT
Reason for closing:  Implemented
Comment by Jan Alexander Steffens (heftig) - Friday, 18 July 2014, 21:29 GMT
"exec startx" still works fine here.
Comment by Daniel Micay (thestinger) - Friday, 18 July 2014, 21:43 GMT
It does actually work fine here if I run it manually. It seems that starting X automatically via zprofile hits a race condition:

Fatal server error:
[ 10969.595] (EE) xf86OpenConsole: VT_ACTIVATE failed: Operation not permitted
Comment by James (thx1138) - Saturday, 19 July 2014, 16:38 GMT
I can't seem to get the Xorg server to run at all, on a Radeon, with any permissions. I don't remember having any trouble with the development server from the AUR.

Running "startx" for "startkde" ends with:
[ 353.524] setversion 1.4 failed: Permission denied
...

Running "Xorg.wrap" or "Xorg.bin" as a non-root user:
[ 5182.695] (EE)
Fatal server error:
[ 5182.695] (EE) xf86OpenConsole: Cannot open /dev/tty0 (No such file or directory)
[ 5182.695] (EE)
...

Of course, "/dev/tty0" _does_ exist, with:
crw--w---- 1 root tty 4, 0 Jul 19 08:39 /dev/tty0

Running "Xorg.wrap" or "Xorg.bin" as root:
[ 4699.104] (EE) RADEON(0): [drm] failed to set drm interface version.
[ 4699.104] (EE) RADEON(0): Kernel modesetting setup failed
[ 4699.104] (II) UnloadModule: "radeon"
[ 4699.104] (EE) Screen(s) found, but none have a usable configuration.
[ 4699.104] (EE)
Fatal server error:
[ 4699.104] (EE) no screens found(EE)
[ 4699.104] (EE)
...


The log files do not seem to be informative.

On the other hand, Weston and Xwayland seem to work fine - thankfully - though Weston is a bit fragile still.


James
Comment by Daniel Micay (thestinger) - Saturday, 19 July 2014, 16:58 GMT
Are you using systemd, and do you have a valid logind session? (loginctl show-session $XDG_SESSION_ID)

To start Weston as non-root, you need to use the `weston` command. You might be using the setuid `weston-launch` command which would explain why it works.
Comment by James (thx1138) - Saturday, 19 July 2014, 17:42 GMT
> Are you using systemd
Yes, standard stuff.

> loginctl show-session $XDG_SESSION_ID

Id=c1
Name=james
Timestamp=Sat 2014-07-19 11:25:08 MDT
TimestampMonotonic=27417111
VTNr=1
TTY=tty1
Remote=no
Service=login
Scope=session-c1.scope
Leader=359
Audit=0
Type=tty
Class=user
Active=no
State=online
IdleHint=no
IdleSinceHint=1405790784986875
IdleSinceHintMonotonic=103913467

> You might be using the setuid `weston-launch` command which would explain why it works.
Yes.

-rwsr-xr-x 1 root root 19064 Jul 8 07:42 /usr/bin/weston-launch

I haven't tried "weston" with xorg-server-1.16, and I just down-graded. "weston" runs fine with xorg-server-1.15. I had just wanted to mention that Xwayland from 1.16 seemed to be working fine. It also runs with xorg-server-1.15.


James
Comment by Jan Alexander Steffens (heftig) - Saturday, 19 July 2014, 17:44 GMT
Your session should be Active, which it isn't.
Comment by Daniel Micay (thestinger) - Saturday, 19 July 2014, 17:51 GMT
Is that loginctl result from the virtual console or from X / Wayland?
Comment by James (thx1138) - Saturday, 19 July 2014, 18:17 GMT
Sorry, that result was from the downgraded 1.15 Xorg. I have upgraded back to 1.16, to test.

BTW, "weston" also runs fine with 1.16.

"loginctl" from "weston" gives:

Id=c2
Name=james
Timestamp=Sat 2014-07-19 11:35:16 MDT
TimestampMonotonic=635831466
VTNr=2
TTY=tty2
Remote=no
Service=login
Scope=session-c2.scope
Leader=1352
Audit=0
Type=tty
Class=user
Active=yes
State=active
IdleHint=no
IdleSinceHint=1405792928990208
IdleSinceHintMonotonic=2247916800

With no weston or Xorg running, from the virtual terminal, "loginctl show-session $XDG_SESSION_ID" gives:

Id=c2
Name=james
Timestamp=Sat 2014-07-19 11:35:16 MDT
TimestampMonotonic=635831466
VTNr=2
TTY=tty2
Remote=no
Service=login
Scope=session-c2.scope
Leader=1352
Audit=0
Type=tty
Class=user
Active=yes
State=active
IdleHint=no
IdleSinceHint=1405793248990208
IdleSinceHintMonotonic=2567916800


James
Comment by Daniel Micay (thestinger) - Saturday, 19 July 2014, 18:23 GMT
It sounds like you're starting X on a different TTY than where the login happened, which is broken. If you run `startx` and haven't touched the default `/etc/X11/xinit/xserverrc` (or overridden it in your $HOME) then it will work fine.
Comment by James (thx1138) - Saturday, 19 July 2014, 20:38 GMT
Aha! Yes, thanks, that worked. I had had a custom ".xserverrc", starting Xorg on a different VT.

But, as you say, "starting X on a different TTY than where the login happened, which is broken."

I see that "ps" has

/usr/bin/Xorg.bin -nolisten tcp :0 -auth /tmp/serverauth.3Zr4iN05qW vt1

when starting from the first virtual terminal, and that the environment variable "XDG_VTNR" is getting set uniquely at each virtual terminal, to match each virtual terminal number.

Hmm - this is very different behavior, for the X server. My immediate reaction would be that "this is totally unacceptable", but I suppose I could learn to live with it. Certainly, "someone", perhaps Hans de Goede, at https://hansdegoede.livejournal.com/14268.html, or perhaps one of the Arch maintainers, should describe, in very basic and complete terms, what, exactly, is "the plan" for this new X server configuration format.

It seems that, basically, the virtual terminal to which X is attached can no longer be specified. So, instead of having my X session always run on a specific virtual terminal, the X session will run only on the virtual terminal from which it is started. And that virtual terminal from which the X server is started will itself become "unavailable", since the command line interface at that virtual terminal would become inaccessible.

Will the traditional X server user configuration files be made obsolete? Will there be some other method to configure a "fixed" virtual terminal on which to run the X server?

I suppose that these issues should be addressed before releasing xorg-server from testing.

It would also be nice if the server logs were more "transparent", but alas ...


James
Comment by Jan Alexander Steffens (heftig) - Saturday, 19 July 2014, 20:47 GMT
The problem is that the VT has become entangled with the concept of a user session. When logging in, the session is recorded as belonging to the active VT. As long as that VT is in the foreground, the session is considered 'active'. Active, local sessions have special rights like access to graphics and input devices. This access is revoked when the session becomes inactive. Local VT sessions also get to own their virtual TTY (/dev/ttyX).

If you try to launch Xorg 1.16 in rootless mode on another VT, it will fail to claim the VT's TTY as it doesn't have the rights needed to open it. Even if it had rights to claim the TTY, the VT would not belong to any session. Rootless Xorg requests access to input devices from logind, and this is only granted while the session is active. Without a session on its VT Xorg could not request any devices.
Comment by Daniel Micay (thestinger) - Saturday, 19 July 2014, 20:51 GMT
Launching X on another TTY was considered broken since consolekit was deprecated in favour of logind, because it has no equivalent to ck-launch-session.

https://www.archlinux.org/news/consolekit-replaced-by-logind/
Comment by James (thx1138) - Monday, 21 July 2014, 15:54 GMT
Thanks for the background. I'm not sure I like the direction this is going, but hopefully, someone more familiar with the resource allocation model can speak to this issue. There is more going on here than just the SUID bit.

Is this seemingly implicit idea of "one login, one terminal" really a "workable" idea for resource allocation? The distinction between "the session belonging to the active VT" and "the active VT belonging to the session" becomes really crucial.

"One login" can result in allowing access to removable discs, printers, scanners, network interfaces, sound devices, mice, keyboards, displays - all kinds of things. Resource allocation issues are especially important when there is more than one user accessing these devices. Two users might share a display but still have exclusive access, each to their own mouse and keyboard, as in a collaborative work environment, or in interactive gaming. This distinction of access would also extend to applications, rather than just devices, while sharing a display, where each user might be able to "see" a window, but not input to that window, each user having their own "work" window. Allocation issues also apply to other "output" devices - audio devices and haptic devices.

This seems to be a more complex issue than just clearing the SUID bit from "Xorg", the idea of who "owns" the terminal - the input devices and the output device - and who "owns" the X server. A "terminal" today is not the same thing it was 40 years ago. And the user "work-flow" need not be the same, either.

James
Comment by Mantas Mikulėnas (grawity) - Monday, 21 July 2014, 17:51 GMT
Exactly the same problem as James had, except I'm quite sure I *am* launching Xorg on the same tty, the logind session is active, /dev/tty2 is owned by myself, and yet Xorg chokes on -EACCES on /dev/tty0 which is owned by root.

open("/dev/tty0", O_WRONLY) = -1 EACCES (Permission denied)
open("/dev/vc/0", O_WRONLY) = -1 ENOENT (No such file or directory)
write(2, "\nFatal server error:\n", 21) = 21
write(2, "xf86OpenConsole: Cannot open /de"..., 67) = 67

Edit: Siiiiiiiiiiiiiiigh. I just realized that my startx script redirects the server's stderr, and when I tried running Xorg directly, it wasn't using the magic xserverrc, so it wasn't actually the same tty. Nevermind :|
Comment by Daniel Micay (thestinger) - Monday, 21 July 2014, 17:58 GMT
@thx1138: logind has concepts of both seats and sessions and is responsible for handling this. A display manager can choose to start X on an arbitrary TTY, but xorg-xinit needs to start it on the one where the session is already created since it can't make a new one. Arch has already been using logind to give out permissions for audio, video, etc. for some time.
Comment by Daniel Micay (thestinger) - Tuesday, 22 July 2014, 03:31 GMT
A few people have mentioned that `startx & exit` is now broken, which is expected as they were already breaking their sessions. You can't give up ownership of the virtual console by exiting before X has taken ownership, and there's an inherent race in that command.

The other issue seems to be that redirecting the stderr of xinit breaks it. I'm unsure about why that occurs and it seems like a bug.
Comment by Jan Alexander Steffens (heftig) - Tuesday, 22 July 2014, 07:27 GMT
For those having problems, you can reenable root mode by editing a config file - see "man Xorg.wrap".

Fedora adds a patch that makes root mode the default (allowing non-root via config): http://pkgs.fedoraproject.org/cgit/xorg-x11-server.git/plain/0001-Fedora-hack-Make-the-suid-root-wrapper-always-start-.patch
Perhaps that's something to consider.
Comment by Laurent Carlier (lordheavy) - Thursday, 24 July 2014, 11:36 GMT
The post install message seems a good solution. Perhaps later we will split the wrapper in a separate package.
I prefer users to fix their configuration instead of patching. Default configuration works with nvidia drivers.

Here is a proposal for the install message:
"xorg-server now provides the ability to run without root rights with
the support of systemd-logind. xserver may fail if not launched
in the same TTY as the login, or with a modified xserverrc file."
Comment by James (thx1138) - Thursday, 24 July 2014, 19:05 GMT
Hmm - I would suggest "... The X server will fail to run if not launched from the same virtual terminal as was used to log in. ..." Saying "will", rather than saying "may", since this seems to be a certainty.

Also, do we know of anything else in the user ".xserverrc" file, or in the system "/etc/X11/xinit/xserverrc" file that will cause the X server to fail, other than starting on a different VT?

I'm still catching-up with this "systemd-logind" thing. Reading "man 8 systemd-logind", I see -
"systemd-logind ... is responsible for:
...
Multi-seat management
Session switch management
Device access management for users
..."

So then, resource allocation will all be handled by logind? And this is the "new model" for resource allocation?

And then, in a sense, running the X server is within the exclusive purview of logind, as "just another resource"? And if there is no "systemd", then Xorg stays SUID root?

By analogy, spawning a virtual "text terminal" with "agetty" from "/etc/inittab" is similar to spawning a virtual "graphic terminal" with "xdm" from "/usr/lib/systemd/system/xdm.service". But reading at "man 1 xdm", Xorg is not a "session manager". Rather differently, "Xorg" is just a bit of software that makes a, possibly minimal, bit of hardware act as a kind of "graphics terminal" connecting to a remote "real computer" over a "network" connection, just as a "text terminal", running some proprietary firmware, connects to a remote "real computer" over a "serial" connection. That is the traditional model of "X terminals". In the X terminal model, all of the "terminal hardware" is directly connected stuff - keyboard, mouse, screen, and any other kind of I/O. In that model, it is not unreasonable to suppose that the X server is managing resource allocation of all connected I/O devices, because those devices certainly were not being managed from the remote "real computer". I/O devices were "local" to the X server.

And, I would suggest that, if we imagined an "advanced X terminal", which provided a multi-seat collaborative work environment, then it would have been the X server that managed the division of various I/O resources - multiple mice, multiple keyboards, multiple audio speakers, multiple video screens, multiple whatever - and _not_ this "remote real computer".

Also, in the traditional X terminal model, the "display manager" did not "start X", where the display manager itself would be running on an entirely different computer - though it _could_ start an X server "locally". Regardless, "X", itself, must be "already running", since otherwise no "display manager" would be visible to a user, except "through" a running X server. What was a "special case" - an X server "local" to the display manager - has become the "common case", but "starting X" was not the essential purpose of the display manager, which is more akin to "getty".

So it seems that systemd is throwing-out this traditional "X terminal" model, and creating some new model in which the "remote real computer" _does_have_ the ability and the authority to allocate, what could effectively be, "remote I/O resources". That will be a clever trick, if these I/O resources are indeed remote. I am not suggesting that this is unreasonable. But, it will require some cooperation on the part of these remote devices. I can imagine a system of, say, gaming devices, or virtual reality devices, or just distributed I/O devices, only connected and accessible over a network. But then, "who" decides how these devices are allocated to users? Printers, for instance, are shared, and not usually used exclusively by one user. "logind" does not manage access to the printer. Generally, the printer has its own access configuration.

Think into the future "network of things" for a moment. Who is to say that, for instance, the "kitchen display screen" should not become available to whomever walks into the kitchen? What about the touch-panel which overlays the display screen - should that always be allocated to the "owner" of the screen itself? What if there are different user windows on that screen? How about the touch-panel which controls the stove? Is logind going to manage my access to the stove? On Star Trek, I remember that you have to "log into" a control panel before you can use it. But then, would you want to individually "log into" every single device on your "network of things"? One approach would allow any user to "take possession" of an I/O device, but only allow that I/O device to access that user's processes. That is not easy, though, if the I/O device does not "know" which user is using it.

Hmm - I suppose that I'm talking myself into the need for some kind of centralized access control management. I'm strongly in favor of a centralized configuration model and will argue against "scattered" configuration files. How many different files will I have to "twiddle"? Setting "/etc/group" is not going to provide access control to some remote device - or is it? Do I have to individually configure user access to every single device on my "network of things"? I don't want to have to do that.

I just want to be clear about the game plan - comments appreciated. A completely different approach would just have Xorg _always_run_ when the computer is turned-on, just as now a virtual text terminal _always_runs_ when the computer is turned-on, as otherwise there is no display device. Why is the default display device a "text terminal", and not a "graphics terminal"? Probably, simply, because running X was so less reliable than running the virtual text terminal. Perhaps this all changes with Wayland? When you think about it, it is odd that the OS kernel gets to decide what kind of "terminal" the "personal computer" first pretends to be. It could be argued that things like "real-time kernels" and "terminals" are more fundamental than the multi-user networking OS. Or, if these components are all seen as peers, then someday, "pretending" to be a "text terminal" will become more complicated than "pretending" to be a "graphics terminal", and the "X server"/Wayland is going to be absorbed into the Linux kernel, as its basic terminal device. And logind will have nothing to do with "starting Xorg".

Except that, perhaps we are taking the first step, where Xorg can be made to _replace_ any instance of a virtual terminal - graphics terminal overlays text terminal. And "starting a graphics terminal" will become meaningless when the basic terminal _is_ a graphics terminal.


James
Comment by Daniel Micay (thestinger) - Thursday, 24 July 2014, 19:18 GMT
Very little of what you've written there is accurate. The logind service replaced consolekit, which was responsible for a subset of the same tasks before. All it does is hand out permissions for resources (devices) to the correct session. Using static groups doesn't work with multi-seat / user switching because users would have access to resources not associated with their session. Anyway, none of that really has to do with this issue. It was *already* broken to be starting X on another TTY and it has been clearly documented for some time.
Comment by James (thx1138) - Sunday, 27 July 2014, 14:40 GMT
Hans de Goede suggested that I might follow David Herrmann, for more information on these issues. It turns out that David has a highly illuminating series of articles, along with questions and comments, discussing the evolution of Session Management, VTs, cgroups, logind, Xorg, and Wayland:

Session-Management on Linux
https://dvdhrm.wordpress.com/2013/08/24/session-management-on-linux/

How VT-switching works
https://dvdhrm.wordpress.com/2013/08/24/how-vt-switching-works/

Sane Session-Switching
https://dvdhrm.wordpress.com/2013/08/25/sane-session-switching/

In particular, this later article has a section addressing "Session-management without VTs".

Developing further this idea of session management without VTs, based upon some ideas presented by Jesse Barnes in 2011, David has also created a userspace KMS/DRM-based system console and terminal emulator, that dissolves the need for the Linux framebuffer and virtual terminal subsystems in the Linux kernel:

KMS/DRM based System Console
http://www.freedesktop.org/wiki/Software/kmscon/

libtsm - Terminal-emulator State Machine
http://www.freedesktop.org/wiki/Software/libtsm/

kmscon
http://en.wikipedia.org/wiki/Kmscon

KMSCON Introduction
http://dvdhrm.wordpress.com/2012/12/10/kmscon-introduction/

KMSCON
https://wiki.archlinux.org/index.php/KMSCON

"kmscon" is still experimental and a bit fragile. At the moment, it will fail if Weston is run, and it has no mouse interface yet. But it definitely shows the direction things are moving. It seems that there is a game plan, and it is moving apace.


James
Comment by jb (jb.1234abcd) - Thursday, 31 July 2014, 06:06 GMT
"The other issue seems to be that redirecting the stderr of xinit breaks it. I'm unsure about why that occurs and it seems like a bug."
Some say it is a bug, others say it is not. What is the cause ? Any fix ?
My usual '/usr/bin/startx > ~/.startx.log 2>&1' fails.
$ cat .startx.log
...
Fatal server error:
(EE) xf86OpenConsole: VT_ACTIVATE failed: Operation not permitted
...
FatalError re-entered, aborting
(EE) xf86CloseConsole: VT_ACTIVATE failed: Operation not permitted
(EE)
xinit: giving up
xinit: unable to connect to X server: Connection refused
xinit: server error

   core.out (2.6 KiB)
Comment by Laurent Carlier (lordheavy) - Tuesday, 26 August 2014, 12:09 GMT

Loading...