Subject: [PATCH 1/1] XSELinux: When SELinux is enabled the xserver seg faults
Peter Hutterer
peter.hutterer at who-t.net
Wed Jun 13 22:14:13 PDT 2012
On Tue, Jun 12, 2012 at 02:49:52PM +0100, Richard Haines wrote:
> This patch was created using xorg-server-1.12.0 source.
>
> When using Fedora 17 with xorg-server-1.12.0 and SELinux is enabled
> ('setsebool xserver_object_manager on') the xserver will not load. The X
> log file has a seg fault pointing to XACE/SELinux. Bug 50641 was raised
> (https://bugs.freedesktop.org/show_bug.cgi?id=50641). The patch below is a
> possible fix.
>
> The bug is caused by X calling XaceHook(XACE_DEVICE_ACCESS, client, ...)
> with a device ID of '1' that is XIAllMasterDevices. It would also happen
> if the device ID = 0 (XIAllDevices).
>
> The only places currently seen calling with a device id=1 are:
> GrabKey - in Xi/exevents.c and AddPassiveGrabToList - in dix/grabs.c
> These start life in ProcXIPassiveGrabDevice (in Xi/xipassivegrab.c) that
> has been called by XIGrabKeycode.
tricky one. the question here is: if I put a grab on all keyboard devices,
should it fail if I'm not allowed to access one of them and thus force the
client to re-do on a per-keyboard basis (which has different semantics, btw)
or should I just continue as usual and grab all _but_ the disallowed ones.
I'm actually leaning towards the latter. Eamon?
as for the patch itself, seems correct for the disallow-all behaviour.
Please fix up the indentation though.
> The patch has been tested using the other XI calls that would also impact
> this: XIGrabTouchBegin, XIGrabButton, XIGrabFocusIn and XIGrabEnter with
> and without the correct permissions (grab and freeze) with no problems.
>
> Both possible classes have to be checked (x_keyboard and x_pointer) as it
> is not known whether it is a pointer or keyboard as this info is not
> available. To get this info would require a change to the
> XaceHook(XACE_DEVICE_ACCESS, client, ..) call to pass an additional
> parameter stating the actual devices (that would defeat the objective of
> the XIAllMasterDevices and XIAllDevices dev ids).
>
> Note that there are other devices apart from the keyboard and pointer, for
> example on the test system: DeviceID: 9 is the Integrated_Webcam_1.3M. As
> it is classed as a slave keyboard it is checked.
the keyboard vs pointer distinction is quite arbitrary, it's a legacy and
many modern devices don't fit into either. the webcam is a keyboard in X
because it has no axes but a KEY_CAMERA.
Cheers,
Peter
>
> Signed-off-by: Richard Haines <richard_c_haines at btinternet.com>
> ---
> Xext/xselinux_hooks.c | 44 +++++++++++++++++++++++++++++++++++++++-----
> 1 file changed, 39 insertions(+), 5 deletions(-)
>
> diff --git a/Xext/xselinux_hooks.c b/Xext/xselinux_hooks.c
> index 0d4c9ab..c2b21d6 100644
> --- a/Xext/xselinux_hooks.c
> +++ b/Xext/xselinux_hooks.c
> @@ -336,9 +336,17 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
> SELinuxAuditRec auditdata = { .client = rec->client, .dev = rec->dev };
> security_class_t cls;
> int rc;
> + DeviceIntPtr dev = NULL;
> + int i = 0;
>
> subj = dixLookupPrivate(&rec->client->devPrivates, subjectKey);
> - obj = dixLookupPrivate(&rec->dev->devPrivates, objectKey);
> + /*
> + * The XIAllMasterDevices or XIAllDevices do not have devPrivates
> + * entries. Therefore dixLookupPrivate for the object is done later
> + * for these device IDs.
> + */
> + if (rec->dev->id != XIAllDevices && rec->dev->id != XIAllMasterDevices)
> + obj = dixLookupPrivate(&rec->dev->devPrivates, objectKey);
>
> /* If this is a new object that needs labeling, do it now */
> if (rec->access_mode & DixCreateAccess) {
> @@ -356,12 +364,38 @@ SELinuxDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
> }
> }
>
> - cls = IsPointerDevice(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
> - rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
> - if (rc != Success)
> - rec->status = rc;
> + if (rec->dev->id != XIAllDevices && rec->dev->id != XIAllMasterDevices) {
> + cls = IsPointerDevice(rec->dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
> + rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
> + if (rc != Success)
> + rec->status = rc;
> + return;
> + } else {
> + /*
> + * Device ID must be 0 or 1
> + * We have to check both possible classes as we don't know whether it
> + * was a pointer or keyboard. Therefore all devices are checked for:
> + * rec->dev->id == XIAllDevices
> + * and only masters for:
> + * rec->dev->id == XIAllMasterDevices
> + *
> + * An error is returned should any device fail SELinuxDoCheck
> + */
> + for (dev = inputInfo.devices; dev; dev = dev->next, i++) {
> + if (!IsMaster(dev) && rec->dev->id == XIAllMasterDevices)
> + continue;
> + cls = IsPointerDevice(dev) ? SECCLASS_X_POINTER : SECCLASS_X_KEYBOARD;
> + obj = dixLookupPrivate(&dev->devPrivates, objectKey);
> + rc = SELinuxDoCheck(subj, obj, cls, rec->access_mode, &auditdata);
> + if (rc != Success) {
> + rec->status = rc;
> + return;
> + }
> + }
> + }
> }
>
> +
> static void
> SELinuxSend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
> {
> --
> 1.7.10.2
>
> _______________________________________________
> xorg-devel at lists.x.org: X.Org development
> Archives: http://lists.x.org/archives/xorg-devel
> Info: http://lists.x.org/mailman/listinfo/xorg-devel
>
More information about the xorg-devel
mailing list