From 8d6c6ceab558ae6eb37d24956dee02eb82a3c3aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Wed, 1 Dec 2021 18:38:39 +0100 Subject: [PATCH 1/4] Add new allowed syscalls --- src/seccomp/policy/DefaultPolicy.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/seccomp/policy/DefaultPolicy.cc b/src/seccomp/policy/DefaultPolicy.cc index f901f2c..957c7d8 100644 --- a/src/seccomp/policy/DefaultPolicy.cc +++ b/src/seccomp/policy/DefaultPolicy.cc @@ -44,7 +44,9 @@ void DefaultPolicy::addExecutionControlRules(bool allowFork) { "clock_nanosleep", "open", "epoll_create1", - "openat"}); + "openat", + "newfstatat", + "pread64"}); rules_.emplace_back(SeccompRule( "set_thread_area", action::ActionTrace([](auto& /* tracee */) { From b042a8308c9a5481de0ad3faaf27dd3bc8f6e5a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Wed, 1 Dec 2021 18:55:54 +0100 Subject: [PATCH 2/4] Add oireal output --- src/limits/TimeLimitListener.cc | 27 +++++++++++----- src/limits/TimeLimitListener.h | 12 +++++-- src/printer/OIModelOutputBuilder.cc | 6 ++++ src/printer/OIModelOutputBuilder.h | 2 ++ src/printer/OutputBuilder.h | 3 ++ src/printer/RealTimeOIOutputBuilder.cc | 44 ++++++++++++++++++++++++++ src/printer/RealTimeOIOutputBuilder.h | 20 ++++++++++++ src/s2japp/ApplicationSettings.cc | 6 +++- 8 files changed, 108 insertions(+), 12 deletions(-) create mode 100644 src/printer/RealTimeOIOutputBuilder.cc create mode 100644 src/printer/RealTimeOIOutputBuilder.h diff --git a/src/limits/TimeLimitListener.cc b/src/limits/TimeLimitListener.cc index bd10563..845fe63 100644 --- a/src/limits/TimeLimitListener.cc +++ b/src/limits/TimeLimitListener.cc @@ -88,24 +88,27 @@ executor::ExecuteAction TimeLimitListener::onSigalrmSignal() { if (!isTimerCreated_) { return executor::ExecuteAction::CONTINUE; } - return verifyTimeUsage(); + auto time = getTimeUsage(); + return verifyTimeUsage(move(time)); } void TimeLimitListener::onPostExecute() { // TODO: run this just after child exit - verifyTimeUsage(); - // TODO Save time usage to OutputBuilder. + auto time = getTimeUsage(); + outputBuilder_->setRealTimeMicroseconds(time->realTimeUs); + verifyTimeUsage(move(time)); } -executor::ExecuteAction TimeLimitListener::verifyTimeUsage() { - if (rTimelimitUs_ != 0 && getRealTimeUsage() > rTimelimitUs_) { +executor::ExecuteAction TimeLimitListener::verifyTimeUsage(std::unique_ptr timeUsage) { + if (rTimelimitUs_ != 0 && timeUsage->realTimeUs > rTimelimitUs_) { outputBuilder_->setKillReason( printer::OutputBuilder::KillReason::TLE, "real time limit exceeded"); return executor::ExecuteAction::KILL; } if (uTimelimitUs_ != 0 || sTimelimitUs_ != 0 || usTimelimitUs_ != 0) { - ProcessTimeUsage ptu = getProcessTimeUsage(); + ProcessTimeUsage& ptu = timeUsage->processTimeUs; + if (uTimelimitUs_ != 0 && ptu.uTimeUs > uTimelimitUs_) { outputBuilder_->setKillReason( printer::OutputBuilder::KillReason::TLE, @@ -128,7 +131,7 @@ executor::ExecuteAction TimeLimitListener::verifyTimeUsage() { return executor::ExecuteAction::CONTINUE; } -uint64_t TimeLimitListener::getRealTimeUsage() { +uint64_t TimeLimitListener::getRealTimeUsage() const { std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now(); std::chrono::steady_clock::duration realTimeUsage = now - startRealTime_; @@ -138,7 +141,7 @@ uint64_t TimeLimitListener::getRealTimeUsage() { return realTimeUsageUs; } -TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() { +TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() const { std::ifstream stat("/proc/" + std::to_string(childPid_) + "/stat"); if (!stat.good()) { throw SystemException("Error reading /proc/childPid_/stat"); @@ -164,6 +167,14 @@ TimeLimitListener::ProcessTimeUsage TimeLimitListener::getProcessTimeUsage() { return result; } +std::unique_ptr TimeLimitListener::getTimeUsage() const { + return std::make_unique( + TimeUsage{ + .realTimeUs = getRealTimeUsage(), + .processTimeUs = getProcessTimeUsage() + } + ); +} } // namespace limits } // namespace s2j diff --git a/src/limits/TimeLimitListener.h b/src/limits/TimeLimitListener.h index 75371f7..69b543e 100644 --- a/src/limits/TimeLimitListener.h +++ b/src/limits/TimeLimitListener.h @@ -29,12 +29,18 @@ class TimeLimitListener uint64_t sTimeUs; // system time in [us] }; + struct TimeUsage { + uint64_t realTimeUs; + ProcessTimeUsage processTimeUs; + }; + static const uint64_t TIMER_TICKING_INTERVAL_US; static const long CLOCK_TICKS_PER_SECOND; - executor::ExecuteAction verifyTimeUsage(); - uint64_t getRealTimeUsage(); - ProcessTimeUsage getProcessTimeUsage(); + executor::ExecuteAction verifyTimeUsage(std::unique_ptr); + uint64_t getRealTimeUsage() const; + ProcessTimeUsage getProcessTimeUsage() const; + std::unique_ptr getTimeUsage() const; uint64_t rTimelimitUs_; // real time limit in [us] uint64_t uTimelimitUs_; // user time limit in [us] diff --git a/src/printer/OIModelOutputBuilder.cc b/src/printer/OIModelOutputBuilder.cc index facebd3..8df46ed 100644 --- a/src/printer/OIModelOutputBuilder.cc +++ b/src/printer/OIModelOutputBuilder.cc @@ -5,6 +5,7 @@ namespace printer { OIModelOutputBuilder::OIModelOutputBuilder() : milliSecondsElapsed_(0) + , realMilliSecondsElapsed_(0) , memoryPeakKb_(0) , syscallsCounter_(0) , exitStatus_(0) @@ -15,6 +16,11 @@ OutputBuilder& OIModelOutputBuilder::setCyclesUsed(uint64_t cyclesUsed) { return *this; } +OutputBuilder& OIModelOutputBuilder::setRealTimeMicroseconds(uint64_t time) { + realMilliSecondsElapsed_ = time / 1000; + return *this; +} + OutputBuilder& OIModelOutputBuilder::setMemoryPeak(uint64_t memoryPeakKb) { memoryPeakKb_ = memoryPeakKb; return *this; diff --git a/src/printer/OIModelOutputBuilder.h b/src/printer/OIModelOutputBuilder.h index 8b8f138..3ca5b4c 100644 --- a/src/printer/OIModelOutputBuilder.h +++ b/src/printer/OIModelOutputBuilder.h @@ -10,6 +10,7 @@ class OIModelOutputBuilder : public OutputBuilder { OIModelOutputBuilder(); OutputBuilder& setCyclesUsed(uint64_t cyclesUsed) override; + OutputBuilder& setRealTimeMicroseconds(uint64_t time) override; OutputBuilder& setMemoryPeak(uint64_t memoryPeakKb) override; OutputBuilder& setExitStatus(uint32_t exitStatus) override; OutputBuilder& setKillSignal(uint32_t killSignal) override; @@ -20,6 +21,7 @@ class OIModelOutputBuilder : public OutputBuilder { static const uint64_t CYCLES_PER_SECOND = 2'000'000'000; uint64_t milliSecondsElapsed_; + uint64_t realMilliSecondsElapsed_; uint64_t memoryPeakKb_; uint64_t syscallsCounter_; uint32_t exitStatus_; diff --git a/src/printer/OutputBuilder.h b/src/printer/OutputBuilder.h index 1b06a54..546dddd 100644 --- a/src/printer/OutputBuilder.h +++ b/src/printer/OutputBuilder.h @@ -32,6 +32,9 @@ class OutputBuilder { virtual OutputBuilder& setCyclesUsed(uint64_t cyclesUsed) { return *this; } + virtual OutputBuilder& setRealTimeMicroseconds(uint64_t time) { + return *this; + } virtual OutputBuilder& setMemoryPeak(uint64_t memoryPeakKb) { return *this; } diff --git a/src/printer/RealTimeOIOutputBuilder.cc b/src/printer/RealTimeOIOutputBuilder.cc new file mode 100644 index 0000000..2d25d5e --- /dev/null +++ b/src/printer/RealTimeOIOutputBuilder.cc @@ -0,0 +1,44 @@ +#include "RealTimeOIOutputBuilder.h" + +#include + +namespace s2j { +namespace printer { + +const std::string RealTimeOIOutputBuilder::FORMAT_NAME = "oireal"; + +std::string RealTimeOIOutputBuilder::dump() const { + KillReason reason = killReason_; + if (reason == KillReason::NONE) { + if (killSignal_ > 0 || exitStatus_ > 0) { + reason = KillReason::RE; + } + } + + std::stringstream ss; + ss << killReasonName(reason) << " " << exitStatus_ << " " + << milliSecondsElapsed_ << " " << realMilliSecondsElapsed_ << " " + << 0ULL << " " << memoryPeakKb_ << " " + << syscallsCounter_ << std::endl; + dumpStatus(ss); + ss << std::endl; + return ss.str(); +} + +void RealTimeOIOutputBuilder::dumpStatus(std::ostream& ss) const { + if (killReason_ != KillReason::NONE) { + ss << killReasonComment_; + } + else if (killSignal_ > 0) { + ss << "process exited due to signal " << killSignal_; + } + else if (exitStatus_ > 0) { + ss << "runtime error " << exitStatus_; + } + else { + ss << "ok"; + } +} + +} // namespace printer +} // namespace s2j diff --git a/src/printer/RealTimeOIOutputBuilder.h b/src/printer/RealTimeOIOutputBuilder.h new file mode 100644 index 0000000..14b6fdc --- /dev/null +++ b/src/printer/RealTimeOIOutputBuilder.h @@ -0,0 +1,20 @@ +#pragma once + +#include "OIModelOutputBuilder.h" + +namespace s2j { +namespace printer { + +class RealTimeOIOutputBuilder : public OIModelOutputBuilder { +public: + std::string dump() const override; + + const static std::string FORMAT_NAME; + +private: + void dumpStatus(std::ostream& ss) const; + int encodeStatusCode() const; +}; + +} // namespace printer +} // namespace s2j diff --git a/src/s2japp/ApplicationSettings.cc b/src/s2japp/ApplicationSettings.cc index d62912d..093bc19 100644 --- a/src/s2japp/ApplicationSettings.cc +++ b/src/s2japp/ApplicationSettings.cc @@ -5,6 +5,7 @@ #include "common/Utils.h" #include "printer/AugmentedOIOutputBuilder.h" #include "printer/OITimeToolOutputBuilder.h" +#include "printer/RealTimeOIOutputBuilder.h" #include "seccomp/policy/DefaultPolicy.h" #include "seccomp/policy/PermissivePolicy.h" @@ -90,7 +91,10 @@ const FactoryMap {{"oitt", std::make_shared}, {"oiaug", - std::make_shared}}); + std::make_shared}, + {"oireal", + std::make_shared} + }); const std::string ApplicationSettings::DEFAULT_OUTPUT_FORMAT = "oitt"; const FactoryMap From 3bbe7de699d3d67bab77e629509da187a00f530b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Wed, 1 Dec 2021 18:56:26 +0100 Subject: [PATCH 3/4] Bump sio2jail to 1.4.2 --- src/s2japp/ApplicationSettings.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/s2japp/ApplicationSettings.cc b/src/s2japp/ApplicationSettings.cc index 093bc19..81a7810 100644 --- a/src/s2japp/ApplicationSettings.cc +++ b/src/s2japp/ApplicationSettings.cc @@ -81,7 +81,7 @@ class StringOutputGenerator : public TCLAP::StdOutput { namespace s2j { namespace app { -const std::string ApplicationSettings::VERSION = "1.4.1-beta"; +const std::string ApplicationSettings::VERSION = "1.4.2"; const std::string ApplicationSettings::DESCRIPTION = "SIO2jail, a sandbox for programming contests."; From 61a6131fade35d986f799489e044fd677e84a068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Chmiel?= Date: Wed, 1 Dec 2021 21:12:52 +0100 Subject: [PATCH 4/4] Fix oireal format and sysalls --- src/printer/RealTimeOIOutputBuilder.cc | 2 +- src/seccomp/policy/DefaultPolicy.cc | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/printer/RealTimeOIOutputBuilder.cc b/src/printer/RealTimeOIOutputBuilder.cc index 2d25d5e..aa9852c 100644 --- a/src/printer/RealTimeOIOutputBuilder.cc +++ b/src/printer/RealTimeOIOutputBuilder.cc @@ -17,7 +17,7 @@ std::string RealTimeOIOutputBuilder::dump() const { std::stringstream ss; ss << killReasonName(reason) << " " << exitStatus_ << " " - << milliSecondsElapsed_ << " " << realMilliSecondsElapsed_ << " " + << realMilliSecondsElapsed_ << " " << 0ULL << " " << memoryPeakKb_ << " " << syscallsCounter_ << std::endl; dumpStatus(ss); diff --git a/src/seccomp/policy/DefaultPolicy.cc b/src/seccomp/policy/DefaultPolicy.cc index 957c7d8..b209978 100644 --- a/src/seccomp/policy/DefaultPolicy.cc +++ b/src/seccomp/policy/DefaultPolicy.cc @@ -44,9 +44,8 @@ void DefaultPolicy::addExecutionControlRules(bool allowFork) { "clock_nanosleep", "open", "epoll_create1", - "openat", - "newfstatat", - "pread64"}); + "openat" + }); rules_.emplace_back(SeccompRule( "set_thread_area", action::ActionTrace([](auto& /* tracee */) { @@ -130,7 +129,7 @@ void DefaultPolicy::addInputOutputRules() { "dup2", action::ActionAllow(), filter::SyscallArg(1) >= 3)); // Allow reading from any file descriptor - allowSyscalls({"read", "readv", "dup", "fcntl", "fcntl64"}); + allowSyscalls({"read", "readv", "dup", "fcntl", "fcntl64", "pread64"}); rules_.emplace_back(SeccompRule("ioctl", action::ActionErrno(ENOTTY))); @@ -152,6 +151,7 @@ void DefaultPolicy::addFileSystemAccessRules(bool readOnly) { "stat64", "fstat", "fstat64", + "newfstatat", "lstat", "lstat64", "listxattr",