diff --git a/config.cc b/config.cc index 077c1b9..cba8c7a 100644 --- a/config.cc +++ b/config.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -310,24 +311,27 @@ static void logHandler( bool parseFile(nsjconf_t* nsjconf, const char* file) { LOG_D("Parsing configuration from '%s'", file); - int fd = TEMP_FAILURE_RETRY(open(file, O_RDONLY | O_CLOEXEC)); - if (fd == -1) { + google::protobuf::SetLogHandler(logHandler); + + std::ifstream ifs(file); + if (!ifs.is_open()) { PLOG_W("Couldn't open config file '%s'", file); return false; } - google::protobuf::SetLogHandler(logHandler); - google::protobuf::io::FileInputStream input(fd); - input.SetCloseOnDelete(true); + std::string conf((std::istreambuf_iterator(ifs)), (std::istreambuf_iterator())); /* Use static so we can get c_str() pointers, and copy them into the nsjconf struct */ static nsjail::NsJailConfig nsc; - auto parser = google::protobuf::TextFormat::Parser(); - if (!parser.Parse(&input, &nsc)) { - LOG_W("Couldn't parse file '%s' from Text into ProtoBuf", file); - return false; + auto status = google::protobuf::util::JsonStringToMessage(conf, &nsc); + if (!status.ok()) { + if (!google::protobuf::TextFormat::ParseFromString(conf, &nsc)) { + LOG_W("Couldn't parse file '%s' from Text or JSON into ProtoBuf", file); + return false; + } } + if (!parseInternal(nsjconf, nsc)) { LOG_W("Couldn't parse the ProtoBuf from '%s'", file); return false; diff --git a/configs/bash-with-fake-geteuid.json b/configs/bash-with-fake-geteuid.json new file mode 100644 index 0000000..1a06522 --- /dev/null +++ b/configs/bash-with-fake-geteuid.json @@ -0,0 +1,170 @@ +{ + "name": "bash-with-fake-geteuid", + "description": [ + "An example/demo policy which allows to execute /bin/bash and other commands in ", + "a fairly restricted jail containing only some directories from the main ", + "system, and with blocked __NR_syslog syscall. Also, __NR_geteuid returns -1337 ", + "value, which /usr/bin/id will show as euid=4294965959, and ptrace is blocked ", + "but returns success, hence strange behavior of the strace command. ", + "This is an example/demo policy, hence it repeats many default values from the ", + "https://github.com/google/nsjail/blob/master/config.proto PB schema " + ], + "mode": "ONCE", + "hostname": "JAILED-BASH", + "cwd": "/tmp", + "port": 31337, + "bindhost": "127.0.0.1", + "maxConnsPerIp": 10, + "timeLimit": 100, + "daemon": false, + "maxCpus": 1, + "keepEnv": false, + "envar": [ + "ENVAR1=VALUE1", + "ENVAR2=VALUE2", + "TERM=linux", + "HOME=/", + "PS1=[\\H:\\t:\\s-\\V:\\w]\\$ " + ], + "keepCaps": true, + "cap": [ + "CAP_NET_ADMIN", + "CAP_NET_RAW" + ], + "silent": false, + "skipSetsid": true, + "stderrToNull": false, + "passFd": [ + 100, + 3 + ], + "disableNoNewPrivs": false, + "rlimitAs": "128", + "rlimitCore": "0", + "rlimitCpu": "10", + "rlimitFsize": "0", + "rlimitNofile": "32", + "rlimitNprocType": "SOFT", + "rlimitStackType": "SOFT", + "personaAddrCompatLayout": false, + "personaMmapPageZero": false, + "personaReadImpliesExec": false, + "personaAddrLimit3gb": false, + "personaAddrNoRandomize": false, + "cloneNewnet": true, + "cloneNewuser": true, + "cloneNewns": true, + "cloneNewpid": true, + "cloneNewipc": true, + "cloneNewuts": true, + "cloneNewcgroup": true, + "uidmap": [ + { + "insideId": "0", + "outsideId": "", + "count": 1 + } + ], + "gidmap": [ + { + "insideId": "0", + "outsideId": "", + "count": 1 + } + ], + "mountProc": false, + "mount": [ + { + "src": "/lib", + "dst": "/lib", + "isBind": true, + "rw": false + }, + { + "src": "/bin", + "dst": "/bin", + "isBind": true, + "rw": false + }, + { + "src": "/sbin", + "dst": "/sbin", + "isBind": true, + "rw": false + }, + { + "src": "/usr", + "dst": "/usr", + "isBind": true, + "rw": false + }, + { + "src": "/lib64", + "dst": "/lib64", + "isBind": true, + "rw": false, + "mandatory": false + }, + { + "src": "/lib32", + "dst": "/lib32", + "isBind": true, + "rw": false, + "mandatory": false + }, + { + "dst": "/tmp", + "fstype": "tmpfs", + "isBind": false, + "rw": true, + "nosuid": true, + "nodev": true, + "noexec": true + }, + { + "src": "/dev/null", + "dst": "/dev/null", + "isBind": true, + "rw": true + }, + { + "dst": "/proc", + "fstype": "proc", + "rw": false + }, + { + "srcContent": "VGhpcyBmaWxlIHdhcyBjcmVhdGVkIGR5bmFtaWNhbGx5", + "dst": "/DYNAMIC_FILE" + }, + { + "src": "/nonexistent_777", + "dst": "/nonexistent_777", + "isBind": true, + "mandatory": false + }, + { + "src": "/proc/self/fd", + "dst": "/dev/fd", + "isSymlink": true + }, + { + "src": "/some/unimportant/target", + "dst": "/proc/no/symlinks/can/be/created/in/proc", + "mandatory": false, + "isSymlink": true + } + ], + "seccompString": [ + "ERRNO(1337) { geteuid }\t", + "ERRNO(1) { ptrace, sched_setaffinity }\t\t", + "KILL_PROCESS { syslog }\t\t", + "DEFAULT ALLOW\t\t\t" + ], + "execBin": { + "path": "/bin/bash", + "arg": [ + "-i" + ], + "arg0": "sh" + } +}