mirror of
https://github.com/google/nsjail.git
synced 2026-08-30 18:41:30 -07:00
Merge pull request #293 from carrerasdarren-cell/unotify-atomic-reports
unotify: write reports privately and atomically
This commit is contained in:
@@ -1,11 +1,15 @@
|
|||||||
#include "unotify/stats.h"
|
#include "unotify/stats.h"
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <google/protobuf/text_format.h>
|
#include <google/protobuf/text_format.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include "logs.h"
|
#include "logs.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@@ -17,6 +21,41 @@ static std::mutex stats_mu;
|
|||||||
* Uses std::map which requires SyscallRecord to have operator<. */
|
* Uses std::map which requires SyscallRecord to have operator<. */
|
||||||
static std::map<SyscallRecord, size_t> stats;
|
static std::map<SyscallRecord, size_t> stats;
|
||||||
|
|
||||||
|
/* Reports can contain traced argv and environment data. Write privately and replace the
|
||||||
|
* destination instead of following it. */
|
||||||
|
static bool writeReportAtomically(const std::string& path, const std::string& report) {
|
||||||
|
std::string tmp_template = path + ".tmp.XXXXXX";
|
||||||
|
std::vector<char> tmp_path(tmp_template.begin(), tmp_template.end());
|
||||||
|
tmp_path.push_back('\0');
|
||||||
|
|
||||||
|
int fd = mkostemp(tmp_path.data(), O_CLOEXEC);
|
||||||
|
if (fd == -1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!util::writeToFd(fd, report.data(), report.size())) {
|
||||||
|
int saved_errno = errno != 0 ? errno : EIO;
|
||||||
|
close(fd);
|
||||||
|
unlink(tmp_path.data());
|
||||||
|
errno = saved_errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (close(fd) == -1) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
unlink(tmp_path.data());
|
||||||
|
errno = saved_errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rename(tmp_path.data(), path.c_str()) == -1) {
|
||||||
|
int saved_errno = errno;
|
||||||
|
unlink(tmp_path.data());
|
||||||
|
errno = saved_errno;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void addStat(const SyscallRecord& rec) {
|
void addStat(const SyscallRecord& rec) {
|
||||||
std::lock_guard<std::mutex> lock(stats_mu);
|
std::lock_guard<std::mutex> lock(stats_mu);
|
||||||
stats[rec]++;
|
stats[rec]++;
|
||||||
@@ -178,8 +217,7 @@ void printStats(nsj_t* nsj) {
|
|||||||
LOG_I("unotify report:\n%s", text_report.c_str());
|
LOG_I("unotify report:\n%s", text_report.c_str());
|
||||||
|
|
||||||
if (!nsj->njc.seccomp_unotify_report().empty()) {
|
if (!nsj->njc.seccomp_unotify_report().empty()) {
|
||||||
if (!util::writeBufToFile(nsj->njc.seccomp_unotify_report().c_str(),
|
if (!writeReportAtomically(nsj->njc.seccomp_unotify_report(), text_report)) {
|
||||||
text_report.data(), text_report.size(), O_CREAT | O_WRONLY | O_TRUNC)) {
|
|
||||||
PLOG_W("Failed to write unotify report to %s",
|
PLOG_W("Failed to write unotify report to %s",
|
||||||
nsj->njc.seccomp_unotify_report().c_str());
|
nsj->njc.seccomp_unotify_report().c_str());
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user