* [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics
@ 2020-03-06 17:33 Emil Velikov
2020-03-06 19:36 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
2020-03-09 14:33 ` [igt-dev] [PATCH i-g-t v4] " Petri Latvala
0 siblings, 2 replies; 4+ messages in thread
From: Emil Velikov @ 2020-03-06 17:33 UTC (permalink / raw)
To: igt-dev; +Cc: Petri Latvala
From: Emil Velikov <emil.velikov@collabora.com>
This test adds three distinct subtests:
- drop/set master as root
- drop/set master as non-root
- drop/set master for a shared fd
Currently the second subtest will fail, with kernel patch to address
that has been submitted.
v2: Add to the autotools build
v3:
- Add igt_describe()
- Use igt_fixture() for tweak_perm
- Enhance comments
v4:
- More comment tweaks
- Add close(drm_open_driver()) workaround)
- use igt_require() for the fd, in final test
Cc: Petri Latvala <petri.latvala@intel.com>
Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
---
tests/Makefile.sources | 1 +
tests/core_setmaster.c | 211 +++++++++++++++++++++++++++++++++++++++++
tests/meson.build | 1 +
3 files changed, 213 insertions(+)
create mode 100644 tests/core_setmaster.c
diff --git a/tests/Makefile.sources b/tests/Makefile.sources
index b87d6333..5da36a91 100644
--- a/tests/Makefile.sources
+++ b/tests/Makefile.sources
@@ -18,6 +18,7 @@ TESTS_progs = \
core_getclient \
core_getstats \
core_getversion \
+ core_setmaster \
core_setmaster_vs_auth \
debugfs_test \
dmabuf \
diff --git a/tests/core_setmaster.c b/tests/core_setmaster.c
new file mode 100644
index 00000000..7f3b039c
--- /dev/null
+++ b/tests/core_setmaster.c
@@ -0,0 +1,211 @@
+/*
+ * Copyright © 2020 Collabora, Ltd.
+ *
+ * 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.
+ *
+ * Authors:
+ * Emil Velikov <emil.l.velikov@gmail.com>
+ *
+ */
+
+/*
+ * Testcase: Check that drop/setMaster behaves correctly wrt root/user access
+ *
+ * Test checks if the ioctls succeed or fail, depending if the applications was
+ * run with root, user privileges or if we have separate privileged arbitrator.
+ */
+
+#include "igt.h"
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+IGT_TEST_DESCRIPTION("Check that Drop/SetMaster behaves correctly wrt root/user"
+ " access");
+
+static bool is_master(int fd)
+{
+ /* FIXME: replace with drmIsMaster once we bumped libdrm version */
+ return drmAuthMagic(fd, 0) != -EACCES;
+}
+
+static void check_drop_set(void)
+{
+ int master;
+
+ master = __drm_open_driver(DRIVER_ANY);
+
+ /* Ensure we have a valid device. This is _extremely_ unlikely to
+ * trigger as tweak_perm() aims to ensure we have the correct rights.
+ * Although:
+ * - igt_fork() + igt_skip() is broken, aka the igt_skip() is not
+ * propagated to the child and we FAIL with a misleading trace.
+ * - there is _no_ guarantee that we'll open a device handled by
+ * tweak_perm(), because __drm_open_driver() does a modprobe(8)
+ * - successfully opening a device is part of the test
+ */
+ igt_assert_neq(master, -1);
+
+ /* At this point we're master capable due to:
+ * - being root - always
+ * - normal user - as the only drm only drm client (on this VT)
+ */
+ igt_assert_eq(is_master(master), true);
+
+ /* If we have SYS_CAP_ADMIN we're in the textbook best-case scenario.
+ *
+ * Otherwise newer kernels allow the application to drop/revoke its
+ * master capability and request it again later.
+ *
+ * In this case, we address two types of issues:
+ * - the application no longer need suid-root (or equivalent) which
+ * was otherwise required _solely_ for these two ioctls
+ * - plenty of applications ignore (or discard) the result of the
+ * calls all together.
+ */
+ igt_assert_eq(drmDropMaster(master), 0);
+ igt_assert_eq(drmSetMaster(master), 0);
+
+ close(master);
+}
+
+static unsigned tweak_perm(uint8_t *saved_perm, unsigned max_perm, bool save)
+{
+ char path[256];
+ struct stat st;
+ unsigned i;
+
+ for (i = 0; i < max_perm; i++) {
+ snprintf(path, sizeof(path), "/dev/dri/card%u", i);
+
+ /* Existing userspace assumes there's no gaps, do the same. */
+ if (stat(path, &st) != 0)
+ break;
+
+ if (save) {
+ /* Save and toggle */
+ saved_perm[i] = st.st_mode & (S_IROTH | S_IWOTH);
+ st.st_mode |= S_IROTH | S_IWOTH;
+ } else {
+ /* Clear and restore */
+ st.st_mode &= ~(S_IROTH | S_IWOTH);
+ st.st_mode |= saved_perm[i];
+ }
+
+ /* There's only one way for chmod to fail - race vs rmmod.
+ * In that case, do _not_ error/skip, since:
+ * - we need to restore the [correct] permissions
+ * - __drm_open_driver() can open another device, aka the
+ * failure may be irrelevant.
+ */
+ chmod(path, st.st_mode);
+ }
+ return i;
+}
+
+
+igt_main
+{
+ igt_describe("Ensure that root can Set/DropMaster");
+ igt_subtest("master-drop-set-root") {
+ check_drop_set();
+ }
+
+
+ igt_subtest_group {
+ uint8_t saved_perm[255];
+ unsigned num;
+
+ /* Upon dropping root we end up as random user, which
+ * a) is not in the video group, and
+ * b) lacks ACL (set via logind or otherwise), thus
+ * any open() fill fail.
+ *
+ * As such, save the state of original other rw permissions
+ * and toggle them on.
+ */
+
+ /* Note: we use a fixture to ensure the permissions are
+ * restored on skip or failure.
+ */
+ igt_fixture {
+ /* In case we're executing after a failed module
+ * reload test, attempt to load all relevant modules.
+ * Otherwise the nodes will be missing.
+ */
+ close(drm_open_driver(DRIVER_ANY));
+ num = tweak_perm(saved_perm, ARRAY_SIZE(saved_perm),
+ true);
+ }
+
+ igt_describe("Ensure first normal user can Set/DropMaster");
+ igt_subtest("master-drop-set-user") {
+ igt_fork(child, 1) {
+ igt_drop_root();
+ check_drop_set();
+ }
+ igt_waitchildren();
+ }
+
+ /* Restore the original permissions */
+ igt_fixture {
+ tweak_perm(saved_perm, num, false);
+ }
+ }
+
+ igt_describe("Check the Set/DropMaster behaviour on shared fd");
+ igt_subtest("master-drop-set-shared-fd") {
+ int master;
+
+ master = __drm_open_driver(DRIVER_ANY);
+
+ igt_require(master >= 0);
+
+ igt_assert_eq(is_master(master), true);
+ igt_fork(child, 1) {
+ igt_drop_root();
+
+ /* Dropping root privileges should not alter the
+ * master capability of the fd */
+ igt_assert_eq(is_master(master), true);
+
+ /* Even though we've got the master capable fd, we're
+ * a different process (kernel struct pid *) than the
+ * one which opened the device node.
+ *
+ * This ensures that existing workcases of separate
+ * (privileged) arbitrator still work. For example:
+ * - logind + X/Wayland compositor
+ * - weston-launch + weston
+ */
+ igt_assert_eq(drmDropMaster(master), -1);
+ igt_assert_eq(errno, EACCES);
+ igt_assert_eq(drmSetMaster(master), -1);
+ igt_assert_eq(errno, EACCES);
+
+ close(master);
+ }
+ igt_waitchildren();
+
+ close(master);
+ }
+}
diff --git a/tests/meson.build b/tests/meson.build
index fa0103e3..d8fb9f3e 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -3,6 +3,7 @@ test_progs = [
'core_getclient',
'core_getstats',
'core_getversion',
+ 'core_setmaster',
'core_setmaster_vs_auth',
'debugfs_test',
'dmabuf',
--
2.25.1
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply related [flat|nested] 4+ messages in thread* [igt-dev] ✗ Fi.CI.BAT: failure for test/core_setmaster: new test for drop/set master semantics
2020-03-06 17:33 [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics Emil Velikov
@ 2020-03-06 19:36 ` Patchwork
2020-03-09 14:33 ` [igt-dev] [PATCH i-g-t v4] " Petri Latvala
1 sibling, 0 replies; 4+ messages in thread
From: Patchwork @ 2020-03-06 19:36 UTC (permalink / raw)
To: Emil Velikov; +Cc: igt-dev
== Series Details ==
Series: test/core_setmaster: new test for drop/set master semantics
URL : https://patchwork.freedesktop.org/series/74400/
State : failure
== Summary ==
CI Bug Log - changes from IGT_5498 -> IGTPW_4275
====================================================
Summary
-------
**FAILURE**
Serious unknown changes coming with IGTPW_4275 absolutely need to be
verified manually.
If you think the reported changes have nothing to do with the changes
introduced in IGTPW_4275, please notify your bug team to allow them
to document this new failure mode, which will reduce false positives in CI.
External URL: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/index.html
Possible new issues
-------------------
Here are the unknown changes that may have been introduced in IGTPW_4275:
### IGT changes ###
#### Possible regressions ####
* igt@i915_selftest@live@gt_lrc:
- fi-snb-2520m: [PASS][1] -> [DMESG-WARN][2]
[1]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-snb-2520m/igt@i915_selftest@live@gt_lrc.html
[2]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-snb-2520m/igt@i915_selftest@live@gt_lrc.html
* igt@runner@aborted:
- fi-snb-2520m: NOTRUN -> [FAIL][3]
[3]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-snb-2520m/igt@runner@aborted.html
#### Suppressed ####
The following results come from untrusted machines, tests, or statuses.
They do not affect the overall result.
* {igt@i915_selftest@live@ring_submission}:
- fi-snb-2520m: [PASS][4] -> [INCOMPLETE][5]
[4]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-snb-2520m/igt@i915_selftest@live@ring_submission.html
[5]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-snb-2520m/igt@i915_selftest@live@ring_submission.html
Known issues
------------
Here are the changes found in IGTPW_4275 that come from known issues:
### IGT changes ###
#### Issues hit ####
* igt@i915_selftest@live@gt_heartbeat:
- fi-cml-s: [PASS][6] -> [DMESG-FAIL][7] ([i915#541])
[6]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-cml-s/igt@i915_selftest@live@gt_heartbeat.html
[7]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-cml-s/igt@i915_selftest@live@gt_heartbeat.html
* igt@prime_vgem@basic-read:
- fi-tgl-y: [PASS][8] -> [DMESG-WARN][9] ([CI#94] / [i915#402]) +1 similar issue
[8]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-tgl-y/igt@prime_vgem@basic-read.html
[9]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-tgl-y/igt@prime_vgem@basic-read.html
#### Possible fixes ####
* igt@gem_exec_suspend@basic-s4-devices:
- fi-tgl-y: [FAIL][10] ([CI#94]) -> [PASS][11]
[10]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-tgl-y/igt@gem_exec_suspend@basic-s4-devices.html
[11]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-tgl-y/igt@gem_exec_suspend@basic-s4-devices.html
* igt@kms_addfb_basic@addfb25-x-tiled:
- fi-tgl-y: [DMESG-WARN][12] ([CI#94] / [i915#402]) -> [PASS][13] +1 similar issue
[12]: https://intel-gfx-ci.01.org/tree/drm-tip/IGT_5498/fi-tgl-y/igt@kms_addfb_basic@addfb25-x-tiled.html
[13]: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/fi-tgl-y/igt@kms_addfb_basic@addfb25-x-tiled.html
{name}: This element is suppressed. This means it is ignored when computing
the status of the difference (SUCCESS, WARNING, or FAILURE).
[CI#94]: https://gitlab.freedesktop.org/gfx-ci/i915-infra/issues/94
[i915#402]: https://gitlab.freedesktop.org/drm/intel/issues/402
[i915#460]: https://gitlab.freedesktop.org/drm/intel/issues/460
[i915#541]: https://gitlab.freedesktop.org/drm/intel/issues/541
Participating hosts (51 -> 45)
------------------------------
Additional (1): fi-kbl-soraka
Missing (7): fi-ilk-m540 fi-hsw-4200u fi-skl-6770hq fi-byt-squawks fi-bsw-cyan fi-byt-clapper fi-bdw-samus
Build changes
-------------
* CI: CI-20190529 -> None
* IGT: IGT_5498 -> IGTPW_4275
CI-20190529: 20190529
CI_DRM_8085: f731492964aa6510672f43292d4b2216b73eddeb @ git://anongit.freedesktop.org/gfx-ci/linux
IGTPW_4275: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/index.html
IGT_5498: 1bb7a25a09fe3e653d310e8bdfbdde4a1934b326 @ git://anongit.freedesktop.org/xorg/app/intel-gpu-tools
== Testlist changes ==
+igt@core_setmaster@master-drop-set-root
+igt@core_setmaster@master-drop-set-shared-fd
+igt@core_setmaster@master-drop-set-user
== Logs ==
For more details see: https://intel-gfx-ci.01.org/tree/drm-tip/IGTPW_4275/index.html
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics
2020-03-06 17:33 [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics Emil Velikov
2020-03-06 19:36 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
@ 2020-03-09 14:33 ` Petri Latvala
2020-03-09 17:00 ` Emil Velikov
1 sibling, 1 reply; 4+ messages in thread
From: Petri Latvala @ 2020-03-09 14:33 UTC (permalink / raw)
To: Emil Velikov; +Cc: igt-dev
On Fri, Mar 06, 2020 at 05:33:11PM +0000, Emil Velikov wrote:
> From: Emil Velikov <emil.velikov@collabora.com>
>
> This test adds three distinct subtests:
> - drop/set master as root
> - drop/set master as non-root
> - drop/set master for a shared fd
>
> Currently the second subtest will fail, with kernel patch to address
> that has been submitted.
>
> v2: Add to the autotools build
> v3:
> - Add igt_describe()
> - Use igt_fixture() for tweak_perm
> - Enhance comments
>
> v4:
> - More comment tweaks
> - Add close(drm_open_driver()) workaround)
> - use igt_require() for the fd, in final test
>
> Cc: Petri Latvala <petri.latvala@intel.com>
> Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
> ---
> tests/Makefile.sources | 1 +
> tests/core_setmaster.c | 211 +++++++++++++++++++++++++++++++++++++++++
> tests/meson.build | 1 +
> 3 files changed, 213 insertions(+)
> create mode 100644 tests/core_setmaster.c
>
> diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> index b87d6333..5da36a91 100644
> --- a/tests/Makefile.sources
> +++ b/tests/Makefile.sources
> @@ -18,6 +18,7 @@ TESTS_progs = \
> core_getclient \
> core_getstats \
> core_getversion \
> + core_setmaster \
> core_setmaster_vs_auth \
> debugfs_test \
> dmabuf \
> diff --git a/tests/core_setmaster.c b/tests/core_setmaster.c
> new file mode 100644
> index 00000000..7f3b039c
> --- /dev/null
> +++ b/tests/core_setmaster.c
> @@ -0,0 +1,211 @@
> +/*
> + * Copyright © 2020 Collabora, Ltd.
> + *
> + * 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.
> + *
> + * Authors:
> + * Emil Velikov <emil.l.velikov@gmail.com>
> + *
> + */
> +
> +/*
> + * Testcase: Check that drop/setMaster behaves correctly wrt root/user access
> + *
> + * Test checks if the ioctls succeed or fail, depending if the applications was
> + * run with root, user privileges or if we have separate privileged arbitrator.
> + */
> +
> +#include "igt.h"
> +#include <unistd.h>
> +#include <stdlib.h>
> +#include <stdio.h>
> +#include <string.h>
> +#include <sys/stat.h>
> +
> +IGT_TEST_DESCRIPTION("Check that Drop/SetMaster behaves correctly wrt root/user"
> + " access");
> +
> +static bool is_master(int fd)
> +{
> + /* FIXME: replace with drmIsMaster once we bumped libdrm version */
> + return drmAuthMagic(fd, 0) != -EACCES;
> +}
> +
> +static void check_drop_set(void)
> +{
> + int master;
> +
> + master = __drm_open_driver(DRIVER_ANY);
> +
> + /* Ensure we have a valid device. This is _extremely_ unlikely to
> + * trigger as tweak_perm() aims to ensure we have the correct rights.
> + * Although:
> + * - igt_fork() + igt_skip() is broken, aka the igt_skip() is not
> + * propagated to the child and we FAIL with a misleading trace.
> + * - there is _no_ guarantee that we'll open a device handled by
> + * tweak_perm(), because __drm_open_driver() does a modprobe(8)
> + * - successfully opening a device is part of the test
> + */
> + igt_assert_neq(master, -1);
> +
> + /* At this point we're master capable due to:
> + * - being root - always
> + * - normal user - as the only drm only drm client (on this VT)
> + */
> + igt_assert_eq(is_master(master), true);
> +
> + /* If we have SYS_CAP_ADMIN we're in the textbook best-case scenario.
> + *
> + * Otherwise newer kernels allow the application to drop/revoke its
> + * master capability and request it again later.
> + *
> + * In this case, we address two types of issues:
> + * - the application no longer need suid-root (or equivalent) which
> + * was otherwise required _solely_ for these two ioctls
> + * - plenty of applications ignore (or discard) the result of the
> + * calls all together.
> + */
> + igt_assert_eq(drmDropMaster(master), 0);
> + igt_assert_eq(drmSetMaster(master), 0);
> +
> + close(master);
> +}
> +
> +static unsigned tweak_perm(uint8_t *saved_perm, unsigned max_perm, bool save)
> +{
> + char path[256];
> + struct stat st;
> + unsigned i;
> +
> + for (i = 0; i < max_perm; i++) {
> + snprintf(path, sizeof(path), "/dev/dri/card%u", i);
> +
> + /* Existing userspace assumes there's no gaps, do the same. */
> + if (stat(path, &st) != 0)
> + break;
> +
> + if (save) {
> + /* Save and toggle */
> + saved_perm[i] = st.st_mode & (S_IROTH | S_IWOTH);
> + st.st_mode |= S_IROTH | S_IWOTH;
> + } else {
> + /* Clear and restore */
> + st.st_mode &= ~(S_IROTH | S_IWOTH);
> + st.st_mode |= saved_perm[i];
> + }
> +
> + /* There's only one way for chmod to fail - race vs rmmod.
> + * In that case, do _not_ error/skip, since:
> + * - we need to restore the [correct] permissions
> + * - __drm_open_driver() can open another device, aka the
> + * failure may be irrelevant.
> + */
> + chmod(path, st.st_mode);
> + }
> + return i;
> +}
> +
> +
> +igt_main
> +{
> + igt_describe("Ensure that root can Set/DropMaster");
> + igt_subtest("master-drop-set-root") {
> + check_drop_set();
> + }
> +
> +
> + igt_subtest_group {
> + uint8_t saved_perm[255];
> + unsigned num;
> +
> + /* Upon dropping root we end up as random user, which
> + * a) is not in the video group, and
> + * b) lacks ACL (set via logind or otherwise), thus
> + * any open() fill fail.
> + *
> + * As such, save the state of original other rw permissions
> + * and toggle them on.
> + */
> +
> + /* Note: we use a fixture to ensure the permissions are
> + * restored on skip or failure.
> + */
> + igt_fixture {
> + /* In case we're executing after a failed module
> + * reload test, attempt to load all relevant modules.
> + * Otherwise the nodes will be missing.
> + */
> + close(drm_open_driver(DRIVER_ANY));
You know what? I'm going to take you on a back-and-forth ride here and
say that it's absolutely wrong to do this and will cause more problems
than it's ultimately solving. Whoever suggested this line didn't read
drmtest.c and is an idiot (for the audience, it was me).
drm_open_driver() opens the device again so it has an fd for the
atexit handlers. And you need to be able to be the only drm user for
this test.
It still leaves the problem of what-if-module-not-loaded-yet but at
this point I'm more inclined to say that this test as-is is fine
(after removing the close() hack) and the people doing weird things
for their testing (i915) are responsible for figuring out a clean way
for making this foolproof for them.
So, with the close() removed once again,
Reviewed-by: Petri Latvala <petri.latvala@intel.com>
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread* Re: [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics
2020-03-09 14:33 ` [igt-dev] [PATCH i-g-t v4] " Petri Latvala
@ 2020-03-09 17:00 ` Emil Velikov
0 siblings, 0 replies; 4+ messages in thread
From: Emil Velikov @ 2020-03-09 17:00 UTC (permalink / raw)
To: Petri Latvala; +Cc: IGT development
On Mon, 9 Mar 2020 at 14:33, Petri Latvala <petri.latvala@intel.com> wrote:
>
> On Fri, Mar 06, 2020 at 05:33:11PM +0000, Emil Velikov wrote:
> > From: Emil Velikov <emil.velikov@collabora.com>
> >
> > This test adds three distinct subtests:
> > - drop/set master as root
> > - drop/set master as non-root
> > - drop/set master for a shared fd
> >
> > Currently the second subtest will fail, with kernel patch to address
> > that has been submitted.
> >
> > v2: Add to the autotools build
> > v3:
> > - Add igt_describe()
> > - Use igt_fixture() for tweak_perm
> > - Enhance comments
> >
> > v4:
> > - More comment tweaks
> > - Add close(drm_open_driver()) workaround)
> > - use igt_require() for the fd, in final test
> >
> > Cc: Petri Latvala <petri.latvala@intel.com>
> > Signed-off-by: Emil Velikov <emil.velikov@collabora.com>
> > ---
> > tests/Makefile.sources | 1 +
> > tests/core_setmaster.c | 211 +++++++++++++++++++++++++++++++++++++++++
> > tests/meson.build | 1 +
> > 3 files changed, 213 insertions(+)
> > create mode 100644 tests/core_setmaster.c
> >
> > diff --git a/tests/Makefile.sources b/tests/Makefile.sources
> > index b87d6333..5da36a91 100644
> > --- a/tests/Makefile.sources
> > +++ b/tests/Makefile.sources
> > @@ -18,6 +18,7 @@ TESTS_progs = \
> > core_getclient \
> > core_getstats \
> > core_getversion \
> > + core_setmaster \
> > core_setmaster_vs_auth \
> > debugfs_test \
> > dmabuf \
> > diff --git a/tests/core_setmaster.c b/tests/core_setmaster.c
> > new file mode 100644
> > index 00000000..7f3b039c
> > --- /dev/null
> > +++ b/tests/core_setmaster.c
> > @@ -0,0 +1,211 @@
> > +/*
> > + * Copyright © 2020 Collabora, Ltd.
> > + *
> > + * 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.
> > + *
> > + * Authors:
> > + * Emil Velikov <emil.l.velikov@gmail.com>
> > + *
> > + */
> > +
> > +/*
> > + * Testcase: Check that drop/setMaster behaves correctly wrt root/user access
> > + *
> > + * Test checks if the ioctls succeed or fail, depending if the applications was
> > + * run with root, user privileges or if we have separate privileged arbitrator.
> > + */
> > +
> > +#include "igt.h"
> > +#include <unistd.h>
> > +#include <stdlib.h>
> > +#include <stdio.h>
> > +#include <string.h>
> > +#include <sys/stat.h>
> > +
> > +IGT_TEST_DESCRIPTION("Check that Drop/SetMaster behaves correctly wrt root/user"
> > + " access");
> > +
> > +static bool is_master(int fd)
> > +{
> > + /* FIXME: replace with drmIsMaster once we bumped libdrm version */
> > + return drmAuthMagic(fd, 0) != -EACCES;
> > +}
> > +
> > +static void check_drop_set(void)
> > +{
> > + int master;
> > +
> > + master = __drm_open_driver(DRIVER_ANY);
> > +
> > + /* Ensure we have a valid device. This is _extremely_ unlikely to
> > + * trigger as tweak_perm() aims to ensure we have the correct rights.
> > + * Although:
> > + * - igt_fork() + igt_skip() is broken, aka the igt_skip() is not
> > + * propagated to the child and we FAIL with a misleading trace.
> > + * - there is _no_ guarantee that we'll open a device handled by
> > + * tweak_perm(), because __drm_open_driver() does a modprobe(8)
> > + * - successfully opening a device is part of the test
> > + */
> > + igt_assert_neq(master, -1);
> > +
> > + /* At this point we're master capable due to:
> > + * - being root - always
> > + * - normal user - as the only drm only drm client (on this VT)
> > + */
> > + igt_assert_eq(is_master(master), true);
> > +
> > + /* If we have SYS_CAP_ADMIN we're in the textbook best-case scenario.
> > + *
> > + * Otherwise newer kernels allow the application to drop/revoke its
> > + * master capability and request it again later.
> > + *
> > + * In this case, we address two types of issues:
> > + * - the application no longer need suid-root (or equivalent) which
> > + * was otherwise required _solely_ for these two ioctls
> > + * - plenty of applications ignore (or discard) the result of the
> > + * calls all together.
> > + */
> > + igt_assert_eq(drmDropMaster(master), 0);
> > + igt_assert_eq(drmSetMaster(master), 0);
> > +
> > + close(master);
> > +}
> > +
> > +static unsigned tweak_perm(uint8_t *saved_perm, unsigned max_perm, bool save)
> > +{
> > + char path[256];
> > + struct stat st;
> > + unsigned i;
> > +
> > + for (i = 0; i < max_perm; i++) {
> > + snprintf(path, sizeof(path), "/dev/dri/card%u", i);
> > +
> > + /* Existing userspace assumes there's no gaps, do the same. */
> > + if (stat(path, &st) != 0)
> > + break;
> > +
> > + if (save) {
> > + /* Save and toggle */
> > + saved_perm[i] = st.st_mode & (S_IROTH | S_IWOTH);
> > + st.st_mode |= S_IROTH | S_IWOTH;
> > + } else {
> > + /* Clear and restore */
> > + st.st_mode &= ~(S_IROTH | S_IWOTH);
> > + st.st_mode |= saved_perm[i];
> > + }
> > +
> > + /* There's only one way for chmod to fail - race vs rmmod.
> > + * In that case, do _not_ error/skip, since:
> > + * - we need to restore the [correct] permissions
> > + * - __drm_open_driver() can open another device, aka the
> > + * failure may be irrelevant.
> > + */
> > + chmod(path, st.st_mode);
> > + }
> > + return i;
> > +}
> > +
> > +
> > +igt_main
> > +{
> > + igt_describe("Ensure that root can Set/DropMaster");
> > + igt_subtest("master-drop-set-root") {
> > + check_drop_set();
> > + }
> > +
> > +
> > + igt_subtest_group {
> > + uint8_t saved_perm[255];
> > + unsigned num;
> > +
> > + /* Upon dropping root we end up as random user, which
> > + * a) is not in the video group, and
> > + * b) lacks ACL (set via logind or otherwise), thus
> > + * any open() fill fail.
> > + *
> > + * As such, save the state of original other rw permissions
> > + * and toggle them on.
> > + */
> > +
> > + /* Note: we use a fixture to ensure the permissions are
> > + * restored on skip or failure.
> > + */
> > + igt_fixture {
> > + /* In case we're executing after a failed module
> > + * reload test, attempt to load all relevant modules.
> > + * Otherwise the nodes will be missing.
> > + */
> > + close(drm_open_driver(DRIVER_ANY));
>
>
> You know what? I'm going to take you on a back-and-forth ride here and
> say that it's absolutely wrong to do this and will cause more problems
> than it's ultimately solving. Whoever suggested this line didn't read
> drmtest.c and is an idiot (for the audience, it was me).
>
> drm_open_driver() opens the device again so it has an fd for the
> atexit handlers. And you need to be able to be the only drm user for
> this test.
>
> It still leaves the problem of what-if-module-not-loaded-yet but at
> this point I'm more inclined to say that this test as-is is fine
> (after removing the close() hack) and the people doing weird things
> for their testing (i915) are responsible for figuring out a clean way
> for making this foolproof for them.
>
Right makes sense.
> So, with the close() removed once again,
>
> Reviewed-by: Petri Latvala <petri.latvala@intel.com>
Dropped the close() workaround and added the R-B as sent out v5 :-)
Not let's see if we can finish the kernel side and get everything merged.
-Emil
_______________________________________________
igt-dev mailing list
igt-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/igt-dev
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2020-03-09 17:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-03-06 17:33 [igt-dev] [PATCH i-g-t v4] test/core_setmaster: new test for drop/set master semantics Emil Velikov
2020-03-06 19:36 ` [igt-dev] ✗ Fi.CI.BAT: failure for " Patchwork
2020-03-09 14:33 ` [igt-dev] [PATCH i-g-t v4] " Petri Latvala
2020-03-09 17:00 ` Emil Velikov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox