Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package nsjail for openSUSE:Factory checked in at 2023-08-23 14:58:48 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/nsjail (Old) and /work/SRC/openSUSE:Factory/.nsjail.new.1766 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "nsjail" Wed Aug 23 14:58:48 2023 rev:10 rq:1105446 version:3.3+git14.8308b91 Changes: -------- --- /work/SRC/openSUSE:Factory/nsjail/nsjail.changes 2023-01-09 17:23:43.943134618 +0100 +++ /work/SRC/openSUSE:Factory/.nsjail.new.1766/nsjail.changes 2023-08-23 14:59:56.502239804 +0200 @@ -1,0 +2,18 @@ +Wed Aug 23 08:54:02 UTC 2023 - wolfgang.fri...@suse.com + +- Fixed Tumbleweed build error caused by an incompatible libprotobuf. +- Update to version 3.3+git14.8308b91: + * subproc: mark cloneFunc as [[noreturn]] + * subproc: support CLONE_CLEAR_SIGHAND + * subproc: display additional clone3 flags + * configs/: formatting + * configs/telegram: telegram is 64 bit only + * configs/telegram: a new config for the telegram-desktop + * formatting fix + * Better output formatting for --help + * cgroup2.cc: improve note about using Docker + * logs: respect getenv(NO_COLOR) + * configs/hexchat: new config based on xchat + * Mount read-only directly if mounting rw fails + +------------------------------------------------------------------- Old: ---- nsjail-3.3+git1.5b48117.tar.xz New: ---- nsjail-3.3+git14.8308b91.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ nsjail.spec ++++++ --- /var/tmp/diff_new_pack.lNRXo9/_old 2023-08-23 14:59:57.090240855 +0200 +++ /var/tmp/diff_new_pack.lNRXo9/_new 2023-08-23 14:59:57.098240869 +0200 @@ -17,7 +17,7 @@ Name: nsjail -Version: 3.3+git1.5b48117 +Version: 3.3+git14.8308b91 Release: 0 Summary: A light-weight process isolation tool License: Apache-2.0 @@ -33,7 +33,11 @@ BuildRequires: libnl3-devel BuildRequires: make BuildRequires: pkgconfig +%if 0%{?suse_version} < 1550 BuildRequires: protobuf-devel +%else +BuildRequires: protobuf21-devel +%endif ExclusiveArch: x86_64 %description ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.lNRXo9/_old 2023-08-23 14:59:57.154240969 +0200 +++ /var/tmp/diff_new_pack.lNRXo9/_new 2023-08-23 14:59:57.162240984 +0200 @@ -1,6 +1,6 @@ <servicedata> <service name="tar_scm"> <param name="url">https://github.com/google/nsjail.git</param> - <param name="changesrevision">5b48117a09d5255f751f7d2387efc44bd6cd39d4</param></service></servicedata> + <param name="changesrevision">8308b91c04e60f0db8186030d6b576968f2eb246</param></service></servicedata> (No newline at EOF) ++++++ nsjail-3.3+git1.5b48117.tar.xz -> nsjail-3.3+git14.8308b91.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/cgroup2.cc new/nsjail-3.3+git14.8308b91/cgroup2.cc --- old/nsjail-3.3+git1.5b48117/cgroup2.cc 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/cgroup2.cc 2023-08-18 13:34:09.000000000 +0200 @@ -93,8 +93,11 @@ } } LOG_E( - "Could not apply '%s' to cgroup.subtree_control in '%s'. If you are running in Docker, " - "nsjail MUST be the root process to use cgroups.", + "Could not apply '%s' to cgroup.subtree_control in '%s'. nsjail MUST be run from root " + "and the cgroup mount path must refer to the root/host cgroup to use cgroupv2. If you " + "use Docker, you may need to run the container with --cgroupns=host so that nsjail can" + " access the host/root cgroupv2 hierarchy. An alternative is mounting (or remounting) " + "the cgroupv2 filesystem but using the flag is just simpler.", val.c_str(), cgroup_path.c_str()); return false; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/cmdline.cc new/nsjail-3.3+git14.8308b91/cmdline.cc --- old/nsjail-3.3+git1.5b48117/cmdline.cc 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/cmdline.cc 2023-08-18 13:34:09.000000000 +0200 @@ -42,6 +42,7 @@ #include <sys/types.h> #include <unistd.h> +#include <cstddef> #include <memory> #include <sstream> #include <string> @@ -61,7 +62,7 @@ struct custom_option { struct option opt; - const char* descr; + const char *descr; }; // clang-format off @@ -69,10 +70,10 @@ { { "help", no_argument, NULL, 'h' }, "Help plz.." }, { { "mode", required_argument, NULL, 'M' }, "Execution mode (default: 'o' [MODE_STANDALONE_ONCE]):\n" - "\tl: Wait for connections on a TCP port (specified with --port) [MODE_LISTEN_TCP]\n" - "\to: Launch a single process on the console using clone/execve [MODE_STANDALONE_ONCE]\n" - "\te: Launch a single process on the console using execve [MODE_STANDALONE_EXECVE]\n" - "\tr: Launch a single process on the console with clone/execve, keep doing it forever [MODE_STANDALONE_RERUN]" }, + " l: [MODE_LISTEN_TCP]\n\tWait for connections on a TCP port (specified with --port)\n" + " o: [MODE_STANDALONE_ONCE]\n\tLaunch a single process on the console using clone/execve\n" + " e: [MODE_STANDALONE_EXECVE]\n\tLaunch a single process on the console using execve\n" + " r: [MODE_STANDALONE_RERUN]\n\tLaunch a single process on the console with clone/execve, keep doing it forever" }, { { "config", required_argument, NULL, 'C' }, "Configuration file in the config.proto ProtoBuf format (see configs/ directory for examples)" }, { { "exec_file", required_argument, NULL, 'x' }, "File to exec (default: argv[0])" }, { { "execute_fd", no_argument, NULL, 0x0607 }, "Use execveat() to execute a file-descriptor instead of executing the binary path. In such case argv[0]/exec_file denotes a file path before mount namespacing" }, @@ -172,11 +173,55 @@ }; // clang-format on -static const char* logYesNo(bool yes) { +static const char *logYesNo(bool yes) { return (yes ? "true" : "false"); } -static void cmdlineOptUsage(struct custom_option* option) { +size_t GetConsoleLength(const std::string &str) { + int result = 0; + for (char c : str) { + if (c == '\t') { + result += 8; + } else { + ++result; + } + } + return result; +} + +std::string FormatLine(const std::string &line, size_t max_len = 80) { + std::string indent = line.substr(0, line.find_first_not_of(" \t")); + size_t indent_len = GetConsoleLength(indent); + size_t cursor = 0; + std::string formatted; + std::vector<std::string> words = util::strSplit(line.c_str(), ' '); + for (const auto &word : words) { + size_t wlen = GetConsoleLength(word); + std::string separator = cursor == 0 ? "" : " "; + size_t slen = GetConsoleLength(separator); + if (cursor != 0 && cursor + slen + wlen >= max_len) { + util::StrAppend(&formatted, "\n"); + cursor = 0; + separator = indent; + slen = indent_len; + } + util::StrAppend(&formatted, "%s%s", separator.c_str(), word.c_str()); + cursor += slen + wlen; + } + return formatted; +} + +std::string FormatDescription(const char *descr) { + std::string formatted; + std::vector<std::string> lines = util::strSplit(descr, '\n'); + + for (const auto &line : lines) { + util::StrAppend(&formatted, "%s\n", FormatLine(std::string("\t") + line).c_str()); + } + return formatted; +} + +static void cmdlineOptUsage(struct custom_option *option) { if (option->opt.val < 0x80) { LOG_HELP_BOLD(" --%s%s%c %s", option->opt.name, "|-", option->opt.val, option->opt.has_arg == required_argument ? "VALUE" : ""); @@ -184,10 +229,10 @@ LOG_HELP_BOLD(" --%s %s", option->opt.name, option->opt.has_arg == required_argument ? "VALUE" : ""); } - LOG_HELP("\t%s", option->descr); + LOG_HELP("%s", FormatDescription(option->descr).c_str()); } -static void cmdlineUsage(const char* pname) { +static void cmdlineUsage(const char *pname) { LOG_HELP_BOLD("Usage: %s [options] -- path_to_command [args]", pname); LOG_HELP_BOLD("Options:"); for (size_t i = 0; i < ARR_SZ(custom_opts); i++) { @@ -204,12 +249,12 @@ LOG_HELP_BOLD(" nsjail -Me --chroot / --disable_proc -- /bin/echo \"ABC\""); } -void addEnv(nsjconf_t* nsjconf, const std::string& env) { +void addEnv(nsjconf_t *nsjconf, const std::string &env) { if (env.find('=') != std::string::npos) { nsjconf->envs.push_back(env); return; } - char* e = getenv(env.c_str()); + char *e = getenv(env.c_str()); if (!e) { LOG_W("Requested to use the %s envar, but it's not set. It'll be ignored", QC(env)); return; @@ -217,7 +262,7 @@ nsjconf->envs.push_back(std::string(env).append("=").append(e)); } -void logParams(nsjconf_t* nsjconf) { +void logParams(nsjconf_t *nsjconf) { switch (nsjconf->mode) { case MODE_LISTEN_TCP: LOG_I("Mode: LISTEN_TCP"); @@ -237,11 +282,14 @@ } LOG_I( - "Jail parameters: hostname:'%s', chroot:%s, process:'%s', bind:[%s]:%d, " + "Jail parameters: hostname:'%s', chroot:%s, process:'%s', " + "bind:[%s]:%d, " "max_conns:%u, max_conns_per_ip:%u, time_limit:%" PRId64 ", personality:%#lx, daemonize:%s, clone_newnet:%s, " - "clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, clone_newuts:%s, " - "clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, disable_no_new_privs:%s, " + "clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, " + "clone_newuts:%s, " + "clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, " + "disable_no_new_privs:%s, " "max_cpus:%zu", nsjconf->hostname.c_str(), QC(nsjconf->chroot), nsjconf->exec_file.empty() ? nsjconf->argv[0].c_str() : nsjconf->exec_file.c_str(), @@ -254,33 +302,35 @@ logYesNo(nsjconf->keep_caps), logYesNo(nsjconf->disable_no_new_privs), nsjconf->max_cpus); - for (const auto& p : nsjconf->mountpts) { + for (const auto &p : nsjconf->mountpts) { LOG_I( "%s: %s", p.is_symlink ? "Symlink" : "Mount", mnt::describeMountPt(p).c_str()); } - for (const auto& uid : nsjconf->uids) { + for (const auto &uid : nsjconf->uids) { LOG_I("Uid map: inside_uid:%lu outside_uid:%lu count:%zu newuidmap:%s", (unsigned long)uid.inside_id, (unsigned long)uid.outside_id, uid.count, uid.is_newidmap ? "true" : "false"); if (uid.outside_id == 0 && nsjconf->clone_newuser) { LOG_W( - "Process will be UID/EUID=0 in the global user namespace, and will " + "Process will be UID/EUID=0 in the global user namespace, and " + "will " "have user root-level access to files"); } } - for (const auto& gid : nsjconf->gids) { + for (const auto &gid : nsjconf->gids) { LOG_I("Gid map: inside_gid:%lu outside_gid:%lu count:%zu newgidmap:%s", (unsigned long)gid.inside_id, (unsigned long)gid.outside_id, gid.count, gid.is_newidmap ? "true" : "false"); if (gid.outside_id == 0 && nsjconf->clone_newuser) { LOG_W( - "Process will be GID/EGID=0 in the global user namespace, and will " + "Process will be GID/EGID=0 in the global user namespace, and " + "will " "have group root-level access to files"); } } } -uint64_t parseRLimit(int res, const char* optarg, unsigned long mul) { +uint64_t parseRLimit(int res, const char *optarg, unsigned long mul) { if (strcasecmp(optarg, "inf") == 0) { return RLIM64_INFINITY; } @@ -296,7 +346,9 @@ } if (!util::isANumber(optarg)) { LOG_F( - "RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' value ('%s' " + "RLIMIT %d needs a numeric or 'max'/'hard'/'def'/'soft'/'inf' " + "value " + "('%s' " "provided)", res, optarg); } @@ -308,17 +360,17 @@ return val * mul; } -static std::string argFromVec(const std::vector<std::string>& vec, size_t pos) { +static std::string argFromVec(const std::vector<std::string> &vec, size_t pos) { if (pos >= vec.size()) { return ""; } return vec[pos]; } -static bool setupArgv(nsjconf_t* nsjconf, int argc, char** argv, int optind) { +static bool setupArgv(nsjconf_t *nsjconf, int argc, char **argv, int optind) { /* - * If user provided cmdline via nsjail [opts] -- [cmdline], then override the one from the - * config file + * If user provided cmdline via nsjail [opts] -- [cmdline], then override + * the one from the config file */ if (optind < argc) { nsjconf->argv.clear(); @@ -326,7 +378,7 @@ nsjconf->argv.push_back(argv[i]); } } - if (nsjconf->exec_file.empty() && nsjconf->argv.size() > 0) { + if (nsjconf->exec_file.empty() && !nsjconf->argv.empty()) { nsjconf->exec_file = nsjconf->argv[0]; } if (nsjconf->exec_file.empty()) { @@ -338,7 +390,9 @@ if (nsjconf->use_execveat) { #if !defined(__NR_execveat) LOG_E( - "Your nsjail is compiled without support for the execveat() syscall, yet you " + "Your nsjail is compiled without support for the execveat() " + "syscall, " + "yet you " "specified the --execute_fd flag"); return false; #endif /* !defined(__NR_execveat) */ @@ -351,14 +405,16 @@ return true; } -static bool setupMounts(nsjconf_t* nsjconf) { +static bool setupMounts(nsjconf_t *nsjconf) { if (!(nsjconf->chroot.empty())) { if (!mnt::addMountPtHead(nsjconf, nsjconf->chroot, "/", /* fstype= */ "", /* options= */ "", nsjconf->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE) : (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY), - /* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true, /* src_env= */ "", - /* dst_env= */ "", /* src_content= */ "", /* is_symlink= */ false)) { + /* is_dir= */ mnt::NS_DIR_YES, + /* is_mandatory= */ true, /* src_env= */ "", + /* dst_env= */ "", /* src_content= */ "", + /* is_symlink= */ false)) { return false; } } else { @@ -373,8 +429,10 @@ if (!nsjconf->proc_path.empty()) { if (!mnt::addMountPtTail(nsjconf, /* src= */ "", nsjconf->proc_path, "proc", /* options= */ "", nsjconf->is_proc_rw ? 0 : MS_RDONLY, - /* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true, /* src_env= */ "", - /* dst_env= */ "", /* src_content= */ "", /* is_symlink= */ false)) { + /* is_dir= */ mnt::NS_DIR_YES, + /* is_mandatory= */ true, /* src_env= */ "", + /* dst_env= */ "", /* src_content= */ "", + /* is_symlink= */ false)) { return false; } } @@ -382,7 +440,7 @@ return true; } -void setupUsers(nsjconf_t* nsjconf) { +void setupUsers(nsjconf_t *nsjconf) { if (nsjconf->uids.empty()) { idmap_t uid; uid.inside_id = getuid(); @@ -401,7 +459,7 @@ } } -std::string parseMACVlanMode(const char* optarg) { +std::string parseMACVlanMode(const char *optarg) { if (strcasecmp(optarg, "private") != 0 && strcasecmp(optarg, "vepa") != 0 && strcasecmp(optarg, "bridge") != 0 && strcasecmp(optarg, "passthru") != 0) { LOG_F( @@ -413,7 +471,7 @@ return std::string(optarg); } -std::unique_ptr<nsjconf_t> parseArgs(int argc, char* argv[]) { +std::unique_ptr<nsjconf_t> parseArgs(int argc, char *argv[]) { std::unique_ptr<nsjconf_t> nsjconf(new nsjconf_t); nsjconf->use_execveat = false; @@ -701,7 +759,8 @@ std::string o_id = argFromVec(subopts, 1); std::string cnt = argFromVec(subopts, 2); size_t count = strtoul(cnt.c_str(), nullptr, 0); - if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false, + if (!user::parseId(nsjconf.get(), i_id, o_id, count, + /* is_gid= */ false, /* is_newidmap= */ false)) { return nullptr; } @@ -712,7 +771,8 @@ std::string o_id = argFromVec(subopts, 1); std::string cnt = argFromVec(subopts, 2); size_t count = strtoul(cnt.c_str(), nullptr, 0); - if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true, + if (!user::parseId(nsjconf.get(), i_id, o_id, count, + /* is_gid= */ true, /* is_newidmap= */ false)) { return nullptr; } @@ -723,7 +783,8 @@ std::string o_id = argFromVec(subopts, 1); std::string cnt = argFromVec(subopts, 2); size_t count = strtoul(cnt.c_str(), nullptr, 0); - if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ false, + if (!user::parseId(nsjconf.get(), i_id, o_id, count, + /* is_gid= */ false, /* is_newidmap= */ true)) { return nullptr; } @@ -734,7 +795,8 @@ std::string o_id = argFromVec(subopts, 1); std::string cnt = argFromVec(subopts, 2); size_t count = strtoul(cnt.c_str(), nullptr, 0); - if (!user::parseId(nsjconf.get(), i_id, o_id, count, /* is_gid= */ true, + if (!user::parseId(nsjconf.get(), i_id, o_id, count, + /* is_gid= */ true, /* is_newidmap= */ true)) { return nullptr; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/configs/hexchat-with-net.cfg new/nsjail-3.3+git14.8308b91/configs/hexchat-with-net.cfg --- old/nsjail-3.3+git1.5b48117/configs/hexchat-with-net.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/configs/hexchat-with-net.cfg 2023-08-18 13:34:09.000000000 +0200 @@ -0,0 +1,157 @@ +# Example config for nsjail + +name: "hexchat-with-net" + +description: "This policy allows to run hexchat inside a jail. Access to networking is" +description: "permitted with this setup (clone_newnet: false)." +description: "" +description: "The only permitted home directory is $HOME/.hexchat and $HOME/Documents." +description: "The rest of available on the FS files/dires are libs and X-related files/dirs." +description: "" +description: "Run as:" +description: "./nsjail --config configs/hexchat-with-net.cfg" + +mode: ONCE +hostname: "HEXCHAT" +cwd: "/user" +daemon: true + +time_limit: 0 +max_cpus: 2 + +envar: "HOME=/user" +envar: "DISPLAY" +envar: "TMP=/tmp" +envar: "FONTCONFIG_FILE=/etc/fonts/fonts.conf" +envar: "FC_CONFIG_FILE=/etc/fonts/fonts.conf" +envar: "LANG" + +rlimit_as: 4096 +rlimit_cpu_type: INF +rlimit_fsize: 4096 +rlimit_nofile: 128 + +clone_newnet: false + +mount { + dst: "/proc" + fstype: "proc" +} + +mount { + src: "/lib" + dst: "/lib" + is_bind: true +} + +mount { + src: "/usr/lib" + dst: "/usr/lib" + is_bind: true +} + +mount { + src: "/lib64" + dst: "/lib64" + is_bind: true + mandatory: false +} + +mount { + src: "/lib32" + dst: "/lib32" + is_bind: true + mandatory: false +} + +mount { + src_content: "<?xml version=\"1.0\"?>\n<!DOCTYPE fontconfig SYSTEM \"fonts.dtd\">\n<fontconfig><dir>/usr/share/fonts</dir><cachedir>/tmp/fontconfig</cachedir></fontconfig>" + dst: "/etc/fonts/fonts.conf" +} + +mount { + src: "/usr/share" + dst: "/usr/share" + is_bind: true +} + +mount { + src: "/dev/urandom" + dst: "/dev/urandom" + is_bind: true + rw: true +} + +mount { + src_content: "nameserver 8.8.8.8" + dst: "/etc/resolv.conf" +} + +mount { + dst: "/tmp" + fstype: "tmpfs" + rw: true + is_bind: false +} + +mount { + dst: "/dev/shm" + fstype: "tmpfs" + rw: true + is_bind: false +} + +mount { + dst: "/user" + fstype: "tmpfs" + rw: true +} + +mount { + prefix_src_env: "HOME" + src: "/Documents" + dst: "/user/Documents" + rw: true + is_bind: true + mandatory: false +} + +mount { + prefix_src_env: "HOME" + src: "/.config/hexchat" + dst: "/user/.config/hexchat" + is_bind: true + rw: true + mandatory: false +} + +mount { + prefix_src_env: "XAUTHORITY" + src: "" + dst: "/user/.Xauthority" + is_bind: true + rw: false + mandatory: false +} + +mount { + src: "/tmp/.X11-unix" + dst: "/tmp/.X11-unix" + is_bind: true + mandatory: false +} + +seccomp_string: "KILL_PROCESS { " +seccomp_string: " ptrace, " +seccomp_string: " process_vm_readv, " +seccomp_string: " process_vm_writev " +seccomp_string: "}, " +seccomp_string: "ERRNO(1) { " +seccomp_string: " sched_setaffinity " +seccomp_string: "} " +seccomp_string: "DEFAULT ALLOW " + +exec_bin { + path: "/usr/bin/hexchat" + exec_fd: true +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/configs/telegram.cfg new/nsjail-3.3+git14.8308b91/configs/telegram.cfg --- old/nsjail-3.3+git1.5b48117/configs/telegram.cfg 1970-01-01 01:00:00.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/configs/telegram.cfg 2023-08-18 13:34:09.000000000 +0200 @@ -0,0 +1,143 @@ +# Example config for nsjail + +name: "telegram-with-net" + +description: "This policy allows to run telegram inside a jail. Access to networking is" +description: "permitted with this setup (clone_newnet: false)." +description: "" +description: "The only permitted home directory is $HOME/.local/share/TelegramDesktop/" +description: "The rest of available on the FS files/dires are libs and wayland-related files/dirs." +description: "" +description: "Run as:" +description: "./nsjail --config configs/telegram.cfg" + +mode: ONCE +hostname: "TELEGRAM" +cwd: "/user" +daemon: true + +time_limit: 0 +max_cpus: 2 + +envar: "HOME=/user" +envar: "WAYLAND_DISPLAY" +envar: "TMP=/tmp" +envar: "LANG" +envar: "XDG_RUNTIME_DIR=/run/user/1000" +envar: "QT_QPA_PLATFORM=wayland" + +rlimit_as: 4096 +rlimit_cpu_type: INF +rlimit_fsize: 4096 +rlimit_nofile: 128 + +clone_newnet: false + +mount { + dst: "/proc" + fstype: "proc" +} + +mount { + src: "/lib" + dst: "/lib" + is_bind: true +} + +mount { + src: "/usr/lib" + dst: "/usr/lib" + is_bind: true +} + +mount { + src: "/lib64" + dst: "/lib64" + is_bind: true + mandatory: false +} + +mount { + src: "/usr/share" + dst: "/usr/share" + is_bind: true +} + +mount { + src: "/dev/urandom" + dst: "/dev/urandom" + is_bind: true + rw: true +} + +mount { + src_content: "nameserver 8.8.8.8" + dst: "/etc/resolv.conf" +} + +mount { + dst: "/tmp" + fstype: "tmpfs" + rw: true + is_bind: false +} + +mount { + dst: "/dev/shm" + fstype: "tmpfs" + rw: true + is_bind: false +} + +mount { + dst: "/user" + fstype: "tmpfs" + rw: true +} + +mount { + prefix_src_env: "HOME" + src: "/.local/share/TelegramDesktop/" + dst: "/user/.local/share/TelegramDesktop/" + is_bind: true + rw: true + mandatory: false +} + +mount { + dst: "/run/user/1000" + fstype: "tmpfs" + rw: true + is_bind: false +} + +mount { + src: "/run/user/1000/wayland-0" + dst: "/run/user/1000/wayland-0" + is_bind: true + rw: false + mandatory: true +} + +mount { + src: "/run/user/1000/pulse/native" + dst: "/run/user/1000/pulse/native" + is_bind: true + rw: false + mandatory: false +} + +seccomp_string: "KILL_PROCESS { " +seccomp_string: " ptrace, " +seccomp_string: " process_vm_readv, " +seccomp_string: " process_vm_writev " +seccomp_string: "}, " +seccomp_string: "ERRNO(1) { " +seccomp_string: " sched_setaffinity " +seccomp_string: "} " +seccomp_string: "DEFAULT ALLOW " + +exec_bin { + path: "/usr/bin/telegram-desktop" + exec_fd: true +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/configs/xchat-with-net.cfg new/nsjail-3.3+git14.8308b91/configs/xchat-with-net.cfg --- old/nsjail-3.3+git1.5b48117/configs/xchat-with-net.cfg 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/configs/xchat-with-net.cfg 2023-08-18 13:34:09.000000000 +0200 @@ -152,6 +152,6 @@ seccomp_string: "DEFAULT ALLOW " exec_bin { - path: "/usr/bin/xchat" - exec_fd: true + path: "/usr/bin/xchat" + exec_fd: true } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/logs.cc new/nsjail-3.3+git14.8308b91/logs.cc --- old/nsjail-3.3+git1.5b48117/logs.cc 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/logs.cc 2023-08-18 13:34:09.000000000 +0200 @@ -55,6 +55,9 @@ _log_fd = orfd; } _log_fd_isatty = (isatty(_log_fd) == 1); + if (getenv("NO_COLOR")) { + _log_fd_isatty = false; + } errno = saved_errno; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/mnt.cc new/nsjail-3.3+git14.8308b91/mnt.cc --- old/nsjail-3.3+git1.5b48117/mnt.cc 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/mnt.cc 2023-08-18 13:34:09.000000000 +0200 @@ -128,6 +128,19 @@ return false; } +static int mountRWIfPossible(mount_t* mpt, const char* src, const char* dst) { + int res = + mount(src, dst, mpt->fs_type.c_str(), mpt->flags & ~(MS_RDONLY), mpt->options.c_str()); + if ((mpt->flags & MS_RDONLY) && res == -1 && errno == EPERM) { + LOG_W( + "mount('%s') src: '%s' dstpath: '%s' could not mount read-write, falling back " + "to mounting read-only directly", + describeMountPt(*mpt).c_str(), src, dst); + res = mount(src, dst, mpt->fs_type.c_str(), mpt->flags, mpt->options.c_str()); + } + return res; +} + static bool mountPt(mount_t* mpt, const char* newroot, const char* tmpdir) { LOG_D("Mounting %s", describeMountPt(*mpt).c_str()); @@ -199,8 +212,7 @@ /* * Initially mount it as RW, it will be remounted later on if needed */ - unsigned long flags = mpt->flags & ~(MS_RDONLY); - if (mount(srcpath, dstpath, mpt->fs_type.c_str(), flags, mpt->options.c_str()) == -1) { + if (mountRWIfPossible(mpt, srcpath, dstpath) == -1) { if (errno == EACCES) { PLOG_W( "mount('%s') src:'%s' dstpath:'%s' failed. " diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/nsjail-3.3+git1.5b48117/subproc.cc new/nsjail-3.3+git14.8308b91/subproc.cc --- old/nsjail-3.3+git1.5b48117/subproc.cc 2023-01-03 08:11:47.000000000 +0100 +++ new/nsjail-3.3+git14.8308b91/subproc.cc 2023-08-18 13:34:09.000000000 +0200 @@ -98,6 +98,14 @@ NS_VALSTR_STRUCT(CLONE_NEWPID), NS_VALSTR_STRUCT(CLONE_NEWNET), NS_VALSTR_STRUCT(CLONE_IO), +#if !defined(CLONE_CLEAR_SIGHAND) +#define CLONE_CLEAR_SIGHAND 0x100000000ULL +#endif /* !defined(CLONE_CLEAR_SIGHAND) */ + NS_VALSTR_STRUCT(CLONE_CLEAR_SIGHAND), +#if !defined(CLONE_INTO_CGROUP) +#define CLONE_INTO_CGROUP 0x200000000ULL +#endif /* !defined(CLONE_INTO_CGROUP) */ + NS_VALSTR_STRUCT(CLONE_INTO_CGROUP), }; uint64_t knownFlagMask = 0; @@ -517,9 +525,9 @@ /* Cannot be on the stack, as the child's stack pointer will change after clone() */ static __thread jmp_buf env; -static int cloneFunc(void* arg __attribute__((unused))) { +[[noreturn]] static int cloneFunc(void* arg __attribute__((unused))) { longjmp(env, 1); - return 0; + LOG_F("Execution past longjmp"); } /* @@ -544,10 +552,20 @@ #if defined(__NR_clone3) struct clone_args ca = {}; - ca.flags = flags; ca.exit_signal = (uint64_t)exit_signal; + ca.flags = flags | CLONE_CLEAR_SIGHAND; pid_t ret = util::syscall(__NR_clone3, (uintptr_t)&ca, sizeof(ca)); + if (ret != -1) { + return ret; + } + + /* + * Now try without CLONE_CLEAR_SIGHAND as it's supported since Linux 5.5, while clone3 + * appeared in Linux 5.3 + */ + ca.flags = flags; + ret = util::syscall(__NR_clone3, (uintptr_t)&ca, sizeof(ca)); if (ret != -1 || errno != ENOSYS) { return ret; } ++++++ nsjail.obsinfo ++++++ --- /var/tmp/diff_new_pack.lNRXo9/_old 2023-08-23 14:59:57.330241284 +0200 +++ /var/tmp/diff_new_pack.lNRXo9/_new 2023-08-23 14:59:57.334241291 +0200 @@ -1,5 +1,5 @@ name: nsjail -version: 3.3+git1.5b48117 -mtime: 1672729907 -commit: 5b48117a09d5255f751f7d2387efc44bd6cd39d4 +version: 3.3+git14.8308b91 +mtime: 1692358449 +commit: 8308b91c04e60f0db8186030d6b576968f2eb246