On 27/06/2022 19:13, Pádraig Brady wrote:
On 27/06/2022 16:04, наб wrote:
Package: coreutils
Version: 8.32-4+b1
Severity: normal

Dear Maintainer,

The strace for runcon -c true true (after a > true) contains
    getxattr("true", "security.selinux", "unconfined_u:object_r:user_tmp_t", 
255) = 36
    execve("/usr/local/sbin/true", ["true", "true"]) = -1 ENOENT
    execve("/usr/local/bin/true", ["true", "true"]) = -1 ENOENT
    execve("/sbin/true", ["true", "true"]) = -1 ENOENT
    execve("/bin/true", ["true", "true"]) = 0

This corresponds to getfscon("true"), execvp("true", ["true", NULL]).
(of course, this also errors if ./true doesn't exist).

So, uh: is this intentional? It certainly feels wrong? All invocations
take a PATH executable except this one which takes a PATH executable
that must *also* be a valid file? And also invites a trivial trojan
because the precomputed transition is to the file in the cwd, but the
program executed lives somewhere in PATH? Should -c just execv()
instead? Am I misunderstanding the usefulness of this?

Best,
наб

This is a fair point.
I.e. the following patch would be more correct operation.
I'll propose this upstream.

Now existing scripts would need to pass absolute paths to `runcon -c`
to work in the first place, so I don't know how much of a security
issue this is in practice.

thanks,
Pádraig

iff --git a/src/runcon.c b/src/runcon.c
index c4227c784..d85411c79 100644
--- a/src/runcon.c
+++ b/src/runcon.c
@@ -255,7 +255,7 @@ main (int argc, char **argv)
     if (cur_context != NULL)
       freecon (cur_context);

-  execvp (argv[optind], argv + optind);
+  (compute_trans ? execv : execvp) (argv[optind], argv + optind);

     int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
     error (0, errno, "%s", quote (argv[optind]));

Pushed the attached upstream.

thanks,
Pádraig
From 96c149941357186abcbd8da914544a7867cab01e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?= <p...@draigbrady.com>
Date: Sun, 24 Jul 2022 18:46:10 +0100
Subject: [PATCH] runcon: ensure --compute runs the file it inspects

* src/runcon.c (main): With -c avoid searching the path
to ensure the file specified to --compute is executed.
* tests/misc/runcon-compute.sh: Add a new test.
* tests/local.mk: Reference the new test.
* NEWS: Mention the bug fix.
Reported in https://bugs.debian.org/1013924
---
 NEWS                         |  4 ++++
 src/runcon.c                 |  2 +-
 tests/local.mk               |  1 +
 tests/misc/runcon-compute.sh | 28 ++++++++++++++++++++++++++++
 4 files changed, 34 insertions(+), 1 deletion(-)
 create mode 100755 tests/misc/runcon-compute.sh

diff --git a/NEWS b/NEWS
index 816025255..b5b8990f8 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ GNU coreutils NEWS                                    -*- outline -*-
   'mv --backup=simple f d/' no longer mistakenly backs up d/f to f~.
   [bug introduced in coreutils-9.1]
 
+  runcon --compute no longer looks up the specified command in the $PATH
+  so that there is no mismatch between the inspected and executed file.
+  [bug introduced when runcon was introduced in coreutils-6.9.90]
+
   'sort -g' no longer infloops when given multiple NaNs on platforms
   like x86_64 where 'long double' has padding bits in memory.
   Although the fix alters sort -g's NaN ordering, that ordering has
diff --git a/src/runcon.c b/src/runcon.c
index c4227c784..d85411c79 100644
--- a/src/runcon.c
+++ b/src/runcon.c
@@ -255,7 +255,7 @@ main (int argc, char **argv)
   if (cur_context != NULL)
     freecon (cur_context);
 
-  execvp (argv[optind], argv + optind);
+  (compute_trans ? execv : execvp) (argv[optind], argv + optind);
 
   int exit_status = errno == ENOENT ? EXIT_ENOENT : EXIT_CANNOT_INVOKE;
   error (0, errno, "%s", quote (argv[optind]));
diff --git a/tests/local.mk b/tests/local.mk
index 0f7778619..0496c2873 100644
--- a/tests/local.mk
+++ b/tests/local.mk
@@ -351,6 +351,7 @@ all_tests =					\
   tests/misc/readlink-fp-loop.sh		\
   tests/misc/readlink-root.sh			\
   tests/misc/realpath.sh			\
+  tests/misc/runcon-compute.sh			\
   tests/misc/runcon-no-reorder.sh		\
   tests/misc/sha1sum.pl				\
   tests/misc/sha1sum-vec.pl			\
diff --git a/tests/misc/runcon-compute.sh b/tests/misc/runcon-compute.sh
new file mode 100755
index 000000000..1c4e0c060
--- /dev/null
+++ b/tests/misc/runcon-compute.sh
@@ -0,0 +1,28 @@
+#!/bin/sh
+# Ensure that runcon -c uses absolute file names
+
+# Copyright (C) 2022 Free Software Foundation, Inc.
+
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <https://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
+print_ver_ runcon
+
+# Create an executable that's sure to fail
+printf '%s\n' '#!/bin/sh' 'exit 1' >> 'true' || framework_failure_
+chmod a+x 'true' || framework_failure_
+
+returns_ 1 runcon -c true || fail=1
+
+Exit $fail
-- 
2.26.2

Reply via email to