- 
                Notifications
    You must be signed in to change notification settings 
- Fork 29
[RFC] Add wlr-exec-secure-unstable-v1.xml #27
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | 
|---|---|---|
| @@ -0,0 +1,139 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <protocol name="wlr_exec_secure_unstable_v1"> | ||
| <copyright> | ||
| Copyright © 2018 Drew DeVault | ||
|  | ||
| Permission is hereby granted, free of charge, to any person obtaining a | ||
| copy of this software and associated documentation files (the "Software"), | ||
| to deal in the Software without restriction, including without limitation | ||
| the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
| and/or sell copies of the Software, and to permit persons to whom the | ||
| Software is furnished to do so, subject to the following conditions: | ||
|  | ||
| The above copyright notice and this permission notice (including the next | ||
| paragraph) shall be included in all copies or substantial portions of the | ||
| Software. | ||
|  | ||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
| THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | ||
| FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
| DEALINGS IN THE SOFTWARE. | ||
| </copyright> | ||
|  | ||
| <description summary="a protocol for executing clients with higher permissions"> | ||
| This protocol allows unprivileged clients to ask the compositor to execute | ||
| a program which can access protected Wayland protocols. | ||
|  | ||
| The rationale for this protocol is that the execution environment of an | ||
| arbitrary client cannot be reliably verified by the compositor. Environment | ||
| variables like LD_PRELOAD may alter the runtime behavior of the client to | ||
| malicious ends. However, if the compositor creates the client socket and | ||
| exec's the client program itself, it can be sure of the client's execution | ||
| environment. | ||
|  | ||
| If a client is run with the WAYLAND_SOCKET environment variable set, it can | ||
| assume that the socket represents an authenticated Wayland connection and | ||
| it will be able to use any secure protocols it is afforded. If not, the | ||
| client will likely connect to the Unix socket specified by WAYLAND_DISPLAY, | ||
| but it will be an unauthenticated connection. If it needs authenticated | ||
| protocols to accomplish its basic tasks, it will likely wish to use | ||
| wlr_exec_secure_unstable_v1 to ask the compositor to execute itself again. | ||
| It's at the client's discretion to exit once the compositor runs the second | ||
| process or to wait for it to complete. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's unlikely that is how it's going to pan out. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's more likely that if  | ||
| </description> | ||
|  | ||
| <interface name="zwlr_exec_manager_v1" version="1"> | ||
| <description summary="interface for requesting execution handles"> | ||
| Clients which want the compositor to execute another client should create | ||
| a zwlr_exec_handle_v1 and use it to configure and run the client. | ||
| </description> | ||
|  | ||
| <request name="exec_process"> | ||
| <description summary="creates a wlr_exec_handle_v1 resource"> | ||
| Creates an exec_handle for the requested command. The compositor can | ||
| choose to disallow this request for certain commands, in which case a | ||
| protocol error is issued. The command will be executed without a shell. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should probably be explicit that the arguments are passed unmodified to execv, instead of just saying "executed without a shell". | ||
| </description> | ||
| <arg name="handle" type="new_id" interface="zwlr_exec_handle_v1"/> | ||
| <arg name="command" type="array" summary="the command to execute"/> | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is argv[0] handled? | ||
| </request> | ||
|  | ||
| <request name="destroy" type="destructor"> | ||
| <description summary="destroy the manager"> | ||
| All objects created by the manager will still remain valid, until their | ||
| appropriate destroy request has been called. | ||
| </description> | ||
| </request> | ||
| </interface> | ||
|  | ||
| <interface name="zwlr_exec_handle_v1" version="1"> | ||
| <description summary="an executing or to-be-executed process"> | ||
| This resource represents a process executed by the compositor, or a | ||
| process which will be executed by the compositor shortly. | ||
|  | ||
| The client should transfer any appropriate state, then send an exec | ||
| request and await the exit event. | ||
|  | ||
| Once the compositor receives an exec request, it should fork, close all | ||
| file descriptors (except for the transferred ones), then dup2 them to the | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
 Including stdin, stdout, and stderr? Should they be set to /dev/null? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably specify that the behavior of stdin/stdout/stderr is unspecified if the client doesn't transfer them. | ||
| appropriate file descriptor number. It should then exec (with PATH lookup, | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 to exec'ing with PATH lookup. To apply security rules we need the full executable path anyway. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fair. | ||
| e.g. via execlp or exevp) the requested command. Then it should send the | ||
| pid event, followed by the exit event when the child terminates. | ||
| </description> | ||
|  | ||
| <request name="environment"> | ||
| <description summary="set an environment variable in the process"> | ||
| Sets an environment variable for the new process. The compositor can | ||
| choose not to set any variables, including for example LD_PRELOAD. | ||
| </description> | ||
| <arg name="name" type="string" summary="environment variable name"/> | ||
| <arg name="value" type="string" summary="environment variable value"/> | ||
| </request> | ||
|  | ||
| <request name="fd"> | ||
| <description summary="transfer a file descriptor to the process"> | ||
| Transfers a file descriptor to the new process. The compositor will use | ||
| dup2 to assign the specified file descriptor number, then close the | ||
| danging fd. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dangling fd | ||
| </description> | ||
| <arg name="fd" type="fd" summary="file descriptor to transfer"/> | ||
| <arg name="num" type="uint" summary="first parameter to dup2"/> | ||
| </request> | ||
|  | ||
| <request name="exec"> | ||
| <description summary="start the new process"> | ||
| Asks the compositor to start the new process. Any request other than | ||
| destroy after this point is a protocol violation. | ||
| </description> | ||
| </request> | ||
|  | ||
| <event name="pid"> | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As discussed in my comment about "exit", I don't really think this is necessary or that helpful, and there are other ways that this could be found out. | ||
| <description summary="the process's pid is available"> | ||
| The compositor sends this after it has forked, to inform the client of | ||
| the new process's pid. | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this after fork and before exec of the new process or is this deliberately unspecified? | ||
| </description> | ||
| <arg name="pid" type="uint" | ||
| summary="pid_t of the child process"/> | ||
| </event> | ||
|  | ||
| <event name="exit"> | ||
| There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't like the idea of this event. It basically asks the compositor to become a service manager, and track extra client state over normal wayland clients. It just seems unnecessary in my opinion. It also doesn't address harder questions about processes that fork themselves (daemon-like) or otherwise hand their WAYLAND_SOCKET to another process. The compositor doesn't have a way to track this kind of state and shouldn't be expected to. Also, there is an indefinite amount of time before this is called. How long do we really expect launcher programs to wait around doing nothing? It would just be cleaner if you fire off the client and don't hear about it again. As far as I can see, there are two potential use cases for this extension: (General) Application launchersAs stated above, there isn't really a robust way to track the state of the clients (unless you want to implement/depend on full-blown service manager), and application launchers wouldn't care anyway. They would ignore this event, and destroy the object. Applications gaining privileges for themselvesPerhaps a program wants to provide a proper interactive interface and really do care about the state of the process they create. We don't need the exit event to be able to implement this. You can create a socketpair/pipe in the launcher process, pass it to the child process, and communicate anything you want back via that, including noticing when the socket/pipe closes (e.g. on death). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 
 It's not becoming a service manager because I don't expect it to do this, either. This is basically fork/exec/wait the protocol, nothing more and it doesn't need to handle the edge cases. Clients using this and launched by this will be designed to accomodate it, the edge cases are not important. 
 I disagree, pid is a natural thing to include in this design and its absence would be glaring. Making applications deal with some secondary exit hatch which sends an exit status down the drain first is dumb. The compositor will already have an event loop and handling SIGCHLD isn't a tall order. | ||
| <description summary="the process has exited"> | ||
| The compositor will send this when the process has terminated, with the | ||
| exit status. No further events will be sent after this, and further | ||
| requests will be ignored. | ||
| </description> | ||
| <arg name="status" type="uint" summary="exit status of the process"/> | ||
| </event> | ||
|  | ||
| <request name="destroy" type="destructor"> | ||
| <description summary="delete the exec_handle"> | ||
| Unreferences the exec_handle. If started, the associated process will | ||
| not be killed. Sending any additional requests after destroy is a | ||
| protocol error. | ||
| </description> | ||
| </request> | ||
| </interface> | ||
| </protocol> | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found the description somewhat confusing (I read it as that the protocol is not about privileges but rather to make sure that the program is spawned in a compositor controlled environment). I'd simply drop the
part since this is not part of the protocol or add a
I'd also drop the "with higher permissions" part from the short description since this is (as I read it) not what the protocol does.