<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>