<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<p>Actually I'm stupid, the stat() call is required and should
happen after realpath() because it's required for
selabel_lookup(): the expected context may differ based on the
type of the inode.<br>
</p>
<div class="moz-cite-prefix">On 12/29/21 09:52, Renaud Métrich
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:472d375e-8f3e-ac89-7d5c-372968e5caf0@redhat.com">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<p>See inline<br>
</p>
<div class="moz-cite-prefix">On 12/29/21 00:45, Dmitry V. Levin
wrote:<br>
</div>
<blockquote type="cite"
cite="mid:20211228234553.GA17229@altlinux.org">
<pre class="moz-quote-pre" wrap="">On Tue, Dec 28, 2021 at 01:12:16PM +0100, Renaud Métrich wrote:
[...]
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">diff --git a/m4/st_selinux.m4 b/m4/st_selinux.m4
index 8b524896d..09a15e9d2 100644
--- a/m4/st_selinux.m4
+++ b/m4/st_selinux.m4
@@ -48,6 +48,24 @@ AS_IF([test "x$with_libselinux" != xno],
)
]
)
+ AC_CHECK_LIB([selinux],[selabel_open],
+ [libselinux_LIBS="-lselinux"
+ enable_secontext=yes
+ ],
+ [if test "x$with_libselinux" != xcheck; then
+ AC_MSG_FAILURE([failed to find selabel_open in libselinux])
+ fi
+ ]
+ )
+ AC_CHECK_LIB([selinux],[selabel_lookup],
+ [libselinux_LIBS="-lselinux"
+ enable_secontext=yes
+ ],
+ [if test "x$with_libselinux" != xcheck; then
+ AC_MSG_FAILURE([failed to find selabel_lookup in libselinux])
+ fi
+ ]
+ )
LDFLAGS="$saved_LDFLAGS"
],
[AS_IF([test "x$with_libselinux" != xcheck],
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">After commit v5.15~18 this could be re-written as follows:
--- a/m4/st_selinux.m4
+++ b/m4/st_selinux.m4
@@ -35,7 +35,7 @@ AS_IF([test "x$with_libselinux" != xno],
[saved_LDFLAGS="$LDFLAGS"
LDFLAGS="$LDFLAGS $libselinux_LDFLAGS"
missing=
- for func in getpidcon getfilecon; do
+ for func in getpidcon getfilecon selabel_open selabel_lookup; do
AC_CHECK_LIB([selinux], [$func], [:],
[missing="$missing $func"])
done
</pre>
</blockquote>
OK<br>
<blockquote type="cite"
cite="mid:20211228234553.GA17229@altlinux.org">
<pre class="moz-quote-pre" wrap="">[...]
</pre>
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">+static int
+get_expected_filecontext(const char *path, char **result)
+{
+ static struct selabel_handle *hdl = NULL;
+ static bool disabled = false;
+
+ if (disabled)
+ return -1;
+
+ if (!hdl) {
+ hdl = selabel_open(SELABEL_CTX_FILE, NULL, 0);
+ if (!hdl) {
+ error_msg("Could not open SELinux database, disabling "
+ "context mismatch checking: %s",
+ strerror(errno));
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">perror_msg should be used instead of error_msg(..., strerror(errno)).
</pre>
</blockquote>
OK<br>
<blockquote type="cite"
cite="mid:20211228234553.GA17229@altlinux.org">
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">+ disabled = true;
+ return -1;
+ }
+ }
+
+ /*
+ * We need to fully resolve the path, because selabel_lookup() isn't
+ * smart enough to automatically resolve
+ */
+
+ char *resolved = realpath(path, NULL);
+ if (!resolved)
+ return -1;
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">realpath looks like overkill, it may issue quite a few syscalls while
a simple readlink should be enough to resolve the symlink in /proc/.
</pre>
</blockquote>
<p>Unfortunately readlink() is not working here because readlink()
doesn't resolve fully but selabel_lookup() really requires
knowing the path, because it just checks in its database for the
corresponding regex.</p>
<p>Example:</p>
<pre>$ cd /tmp
$ ln -s /home/rmetrich symlinkdir
$ touch /home/rmetrich/bar
$ ln -s /tmp/symlinkdir/bar
$ matchpathcon $(readlink bar)
/tmp/symlinkdir/bar <<none>>
---> WRONG
$ matchpathcon $(realpath bar)
/home/rmetrich/bar unconfined_u:object_r:user_home_t:s0
---> RIGHT
</pre>
<blockquote type="cite"
cite="mid:20211228234553.GA17229@altlinux.org">
<blockquote type="cite">
<pre class="moz-quote-pre" wrap="">+ struct stat statbuf;
+ if (stat(resolved, &statbuf) == -1) {
+ free(resolved);
+ return -1;
+ }
</pre>
</blockquote>
</blockquote>
Actually I think stat() is not needed, if realpath() fails because
the file doesn't exist/isn't accessible, we will return in error
as well.<br>
<blockquote type="cite"
cite="mid:20211228234553.GA17229@altlinux.org">
<pre class="moz-quote-pre" wrap="">Maybe stat should be called before readlink.
</pre>
</blockquote>
</blockquote>
</body>
</html>