<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style>
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word">
<div class="WordSection1">
<p class="MsoNormal"><span style="font-family:"Courier New"">Hello,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">We were experiencing the same issue w/r/t group permissions not being respected<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">on directories.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">I did a quick-and-dirty hack to add the SECBIT_NO_SETUID_FIXUP securebit, as<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">suggested by Chirantan and Vivek, and that seems to have done the trick. Looks<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">like if we set the securebits before we setup sandbox we can avoid leaving the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">process with CAP_SETPCAP.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Seems a better approach would just to expose the ability to set securebits at<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">the CLI like what is done with caps. Then anybody affected by this bug can set<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">SECBIT_NO_SETUID_FIXUP themselves. I'd prefer this if the maintainers agree.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Would be happy to clean up my patch and submit it--just want to check if this<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">is an approach y'all are content with.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Current patch is included if anybody wants to try it out. Note that the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">securebits header is lifted from kernel 5.4.0 /usr/include/linux/securebits.h<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">Ameer Ghani<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">---<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">include/standard-headers/linux/securebits.h | 61 +++++++++++++++++++++<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">tools/virtiofsd/passthrough_ll.c            | 15 +++++<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">2 files changed, 76 insertions(+)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">create mode 100644 include/standard-headers/linux/securebits.h<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">diff --git a/include/standard-headers/linux/securebits.h b/include/standard-headers/linux/securebits.h<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">new file mode 100644<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">index 0000000000..69c11a49c5<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">--- /dev/null<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+++ b/include/standard-headers/linux/securebits.h<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">@@ -0,0 +1,61 @@<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#ifndef _LINUX_SECUREBITS_H<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define _LINUX_SECUREBITS_H<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* Each securesetting is implemented using two bits. One bit specifies<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   whether the setting is on or off. The other bit specify whether the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   setting is locked or not. A setting which is locked cannot be<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   changed from user-level. */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define issecure_mask(X)  (1 << (X))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECUREBITS_DEFAULT 0x00000000<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* When set UID 0 has no special privileges. When unset, we support<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   inheritance of root-permissions and suid-root executable under<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   compatibility mode. We raise the effective and inheritable bitmasks<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   *of the executable file* if the effective uid of the new process is<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   0. If the real uid is 0, we raise the effective (legacy) bit of the<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   executable file. */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NOROOT                0<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NOROOT_LOCKED         1  /* make bit-0 immutable */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NOROOT          (issecure_mask(SECURE_NOROOT))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NOROOT_LOCKED    (issecure_mask(SECURE_NOROOT_LOCKED))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* When set, setuid to/from uid 0 does not trigger capability-"fixup".<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   When unset, to provide compatiblility with old programs relying on<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   set*uid to gain/lose privilege, transitions to/from uid 0 cause<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   capabilities to be gained/lost. */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NO_SETUID_FIXUP       2<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NO_SETUID_FIXUP_LOCKED 3  /* make bit-2 immutable */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NO_SETUID_FIXUP  (issecure_mask(SECURE_NO_SETUID_FIXUP))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NO_SETUID_FIXUP_LOCKED \<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+               (issecure_mask(SECURE_NO_SETUID_FIXUP_LOCKED))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* When set, a process can retain its capabilities even after<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   transitioning to a non-root user (the set-uid fixup suppressed by<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   bit 2). Bit-4 is cleared when a process calls exec(); setting both<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   bit 4 and 5 will create a barrier through exec that no exec()'d<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+   child can use this feature again. */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_KEEP_CAPS        4<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_KEEP_CAPS_LOCKED      5  /* make bit-4 immutable */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_KEEP_CAPS  (issecure_mask(SECURE_KEEP_CAPS))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_KEEP_CAPS_LOCKED (issecure_mask(SECURE_KEEP_CAPS_LOCKED))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+/* When set, a process cannot add new capabilities to its ambient set. */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NO_CAP_AMBIENT_RAISE       6<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_NO_CAP_AMBIENT_RAISE_LOCKED 7  /* make bit-6 immutable */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NO_CAP_AMBIENT_RAISE (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECBIT_NO_CAP_AMBIENT_RAISE_LOCKED \<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+               (issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE_LOCKED))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_ALL_BITS         (issecure_mask(SECURE_NOROOT) | \<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+                    issecure_mask(SECURE_NO_SETUID_FIXUP) | \<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+                    issecure_mask(SECURE_KEEP_CAPS) | \<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+                    issecure_mask(SECURE_NO_CAP_AMBIENT_RAISE))<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#define SECURE_ALL_LOCKS  (SECURE_ALL_BITS << 1)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#endif /* _LINUX_SECUREBITS_H */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">diff --git a/tools/virtiofsd/passthrough_ll.c b/tools/virtiofsd/passthrough_ll.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">index 49c21fd855..afec9a6567 100644<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">--- a/tools/virtiofsd/passthrough_ll.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+++ b/tools/virtiofsd/passthrough_ll.c<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">@@ -43,6 +43,7 @@<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include "fuse_log.h"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include "fuse_lowlevel.h"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include "standard-headers/linux/fuse.h"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+#include "standard-headers/linux/securebits.h"<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include <cap-ng.h><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include <dirent.h><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">#include <pthread.h><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">@@ -3515,6 +3516,17 @@ static void setup_chroot(struct lo_data *lo)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">     }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+static void setup_securebits(void)<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+{<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    int status;<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    status = prctl(PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    if (status == -1) {<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+        fuse_log(FUSE_LOG_ERR, "prctl(PR_SET_SECUREBITS): %m\n");<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+        exit(1);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    }<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+}<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">/*<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  * Lock down this process to prevent access to other processes or files outside<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">  * source directory.  This reduces the impact of arbitrary code execution bugs.<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">@@ -3869,6 +3881,9 @@ int main(int argc, char *argv[])<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">     setup_nofile_rlimit(opts.rlimit_nofile);<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    /* Set securebits before we drop CAP_SETPCAP */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+    setup_securebits();<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">+<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">     /* Must be before sandbox since it wants /proc */<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">     setup_capng();<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">-- <o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New"">2.25.1<o:p></o:p></span></p>
<p class="MsoNormal"><span style="font-family:"Courier New""><o:p> </o:p></span></p>
</div>
</body>
</html>