[PATCH RFC] Xorg: Add a suid root wrapper
Mark Kettenis
mark.kettenis at xs4all.nl
Thu Mar 6 04:46:48 PST 2014
> From: Hans de Goede <hdegoede at redhat.com>
> Date: Wed, 5 Mar 2014 16:51:52 +0100
If you end up going with this wrapper approach anyway despite my
previous message, here are some comments.
Oh, and it's good that this is optional.
> diff --git a/hw/xfree86/Xorg.sh b/hw/xfree86/Xorg.sh
> new file mode 100644
> index 0000000..3a2b34b
> --- /dev/null
> +++ b/hw/xfree86/Xorg.sh
> @@ -0,0 +1,13 @@
> +#!/bin/sh
> +#
> +# See if Xorg.wrap is installed and if it is execute it, otherwise execute
> +# Xorg.bin directly. This allows distros to put the suid wrapper in a
> +# separate package.
> +
> +canonical=$(readlink -f "$0")
POSIX doesn't specify readlink(1), so it might not be available on all
systems. Solaris doesn't seem to have it. Perhaps just have
configure substitute the installation path here?
> +basedir=$(dirname "$canonical")
> +if [ -x "$basedir"/Xorg.wrap ]; then
> + exec "$basedir"/Xorg.wrap "$@"
> +else
> + exec "$basedir"/Xorg.bin "$@"
> +fi
> diff --git a/hw/xfree86/xorg-wrapper.c b/hw/xfree86/xorg-wrapper.c
> new file mode 100644
> index 0000000..93a5f15
> --- /dev/null
> +++ b/hw/xfree86/xorg-wrapper.c
> @@ -0,0 +1,82 @@
> +/*
> + * Copyright © 2014 Red Hat, Inc.
> + *
> + * 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.
> + *
> + * Author: Hans de Goede <hdegoede at redhat.com>
> + */
> +
> +#include <fcntl.h>
> +#include <limits.h>
> +#include <stdint.h>
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/ioctl.h>
> +#include <sys/stat.h>
> +#include <sys/types.h>
> +#include <unistd.h>
> +#include <drm/drm.h>
> +
> +#include "dix-config.h" /* For PROJECTROOT */
> +
> +int main(int argc, char *argv[])
> +{
> + struct drm_mode_card_res res;
> + char buf[PATH_MAX];
> + int i, r, fd;
> + int kms_cards = 0;
> + int total_cards = 0;
> +
> + for (i = 0; i < 16; i++) {
> + snprintf(buf, PATH_MAX, "/dev/dri/card%d", i);
Hardcoding paths like this is a bad idea. We use "/dev/drm%d" on
OpenBSD for example. Other systems might use different names yet
again. Probably better to use libdrm.
> + fd = open(buf, O_RDWR);
> + if (fd == -1)
> + continue;
> +
> + total_cards++;
> +
> + memset(&res, 0, sizeof(struct drm_mode_card_res));
> + r = ioctl(fd, DRM_IOCTL_MODE_GETRESOURCES, &res);
> + if (r == 0 && res.count_connectors > 0)
> + kms_cards++;
> +
> + close(fd);
> + }
> +
> + /* If we've found cards, and all cards support kms, drop root rights */
> + if (total_cards && kms_cards == total_cards) {
I think total_cards only includes devices that have a kernel drm
driver loaded. So what you're really checking here is how many of
those provide KMS support. So you're missing any true legacy device.
More information about the xorg-devel
mailing list