Skip to content

Commit d36abe5

Browse files
committed
nsjail.h/all - reduce size of nsjail_t and stop duplicating nsjail::NsJailConfig fields. Now nsjail::NsJailConfig is the source of truth for jails' configuraiton
1 parent 0635041 commit d36abe5

File tree

9 files changed

+312
-312
lines changed

9 files changed

+312
-312
lines changed

caps.cc

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,12 @@ bool initNs(nsj_t* nsj) {
235235
/* Set all requested caps in the inheritable set if these are present in the permitted set
236236
*/
237237
std::string dbgmsg;
238-
for (const auto& cap : nsj->caps) {
238+
for (ssize_t i = 0; i < nsj->njc.cap_size(); i++) {
239+
int cap = nameToVal(nsj->njc.cap(i).c_str());
240+
if (cap == -1) {
241+
LOG_W("Unknown capability: %s", nsj->njc.cap(i).c_str());
242+
continue;
243+
}
239244
if (!getPermitted(cap_data, cap)) {
240245
LOG_W("Capability %s is not permitted in the namespace",
241246
capToStr(cap).c_str());
@@ -277,7 +282,11 @@ bool initNs(nsj_t* nsj) {
277282

278283
/* Make sure inheritable set is preserved across execve via the modified ambient set */
279284
dbgmsg.clear();
280-
for (const auto& cap : nsj->caps) {
285+
for (ssize_t i = 0; i < nsj->njc.cap_size(); i++) {
286+
int cap = nameToVal(nsj->njc.cap(i).c_str());
287+
if (cap == -1) {
288+
continue;
289+
}
281290
if (prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, (unsigned long)cap, 0UL, 0UL) ==
282291
-1) {
283292
PLOG_W("prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, %s)",

cmdline.cc

Lines changed: 80 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,15 @@ static void cmdlineUsage(const char* pname) {
252252

253253
void addEnv(nsj_t* nsj, const std::string& env) {
254254
if (env.find('=') != std::string::npos) {
255-
nsj->envs.push_back(env);
255+
nsj->njc.add_envar(env);
256256
return;
257257
}
258258
char* e = getenv(env.c_str());
259259
if (!e) {
260260
LOG_W("Requested to use the %s envar, but it's not set. It'll be ignored", QC(env));
261261
return;
262262
}
263-
nsj->envs.push_back(std::string(env).append("=").append(e));
263+
nsj->njc.add_envar(std::string(env).append("=").append(e));
264264
}
265265

266266
void logParams(nsj_t* nsj) {
@@ -284,28 +284,24 @@ void logParams(nsj_t* nsj) {
284284

285285
LOG_I("Jail parameters: hostname:'%s', chroot:%s, process:'%s', "
286286
"bind:[%s]:%d, "
287-
"max_conns:%u, max_conns_per_ip:%u, time_limit:%u"
288-
", personality:%#lx, daemonize:%s, clone_newnet:%s, "
287+
"max_conns:%u, max_conns_per_ip:%u, time_limit:%u, daemonize:%s, clone_newnet:%s, "
289288
"clone_newuser:%s, clone_newns:%s, clone_newpid:%s, clone_newipc:%s, "
290-
"clone_newuts:%s, "
291-
"clone_newcgroup:%s, clone_newtime:%s, keep_caps:%s, "
292-
"disable_no_new_privs:%s, "
293-
"max_cpus:%u",
289+
"clone_newuts:%s, cgroupv2:%s, keep_caps:%s, "
290+
"disable_no_new_privs:%s, max_cpus:%u",
294291
nsj->njc.hostname().c_str(), QC(nsj->chroot),
295292
nsj->njc.exec_bin().path().empty() ? nsj->argv[0].c_str()
296293
: nsj->njc.exec_bin().path().c_str(),
297294
nsj->njc.bindhost().c_str(), nsj->njc.port(), nsj->njc.max_conns(),
298-
nsj->njc.max_conns_per_ip(), nsj->njc.time_limit(), nsj->personality,
299-
logYesNo(nsj->njc.daemon()), logYesNo(nsj->njc.clone_newnet()),
300-
logYesNo(nsj->njc.clone_newuser()), logYesNo(nsj->njc.clone_newns()),
301-
logYesNo(nsj->njc.clone_newpid()), logYesNo(nsj->njc.clone_newipc()),
302-
logYesNo(nsj->njc.clone_newuts()), logYesNo(nsj->njc.clone_newcgroup()),
303-
logYesNo(nsj->njc.clone_newtime()), logYesNo(nsj->njc.keep_caps()),
295+
nsj->njc.max_conns_per_ip(), nsj->njc.time_limit(), logYesNo(nsj->njc.daemon()),
296+
logYesNo(nsj->njc.clone_newnet()), logYesNo(nsj->njc.clone_newuser()),
297+
logYesNo(nsj->njc.clone_newns()), logYesNo(nsj->njc.clone_newpid()),
298+
logYesNo(nsj->njc.clone_newipc()), logYesNo(nsj->njc.clone_newuts()),
299+
logYesNo(nsj->njc.use_cgroupv2()), logYesNo(nsj->njc.keep_caps()),
304300
logYesNo(nsj->njc.disable_no_new_privs()), nsj->njc.max_cpus());
305301

306-
for (const auto& p : nsj->mountpts) {
307-
LOG_I(
308-
"%s: %s", p.is_symlink ? "Symlink" : "Mount", mnt::describeMountPt(p).c_str());
302+
for (const auto& p : nsj->njc.mount()) {
303+
LOG_I("%s: %s", p.is_symlink() ? "Symlink" : "Mount",
304+
mnt::describeMountPt(p).c_str());
309305
}
310306
for (const auto& uid : nsj->uids) {
311307
LOG_I("Uid map: inside_uid:%lu outside_uid:%lu count:%zu newuidmap:%s",
@@ -344,9 +340,8 @@ uint64_t parseRLimit(int res, const char* optarg, unsigned long mul) {
344340
return cur.rlim_max;
345341
}
346342
if (!util::isANumber(optarg)) {
347-
LOG_F(
348-
"RLIMIT %s (%d) needs a numeric value or 'max'/'hard'/'def'/'soft'/'inf' value "
349-
"(%s provided)",
343+
LOG_F("RLIMIT %s (%d) needs a numeric value or 'max'/'hard'/'def'/'soft'/'inf' "
344+
"value (%s provided)",
350345
util::rLimName(res).c_str(), res, QC(optarg));
351346
}
352347
errno = 0;
@@ -403,34 +398,33 @@ static bool setupArgv(nsj_t* nsj, int argc, char** argv, int optind) {
403398

404399
static bool setupMounts(nsj_t* nsj) {
405400
if (!(nsj->chroot.empty())) {
406-
if (!mnt::addMountPtHead(nsj, nsj->chroot, "/", /* fstype= */ "",
407-
/* options= */ "",
408-
nsj->is_root_rw ? (MS_BIND | MS_REC | MS_PRIVATE)
409-
: (MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY),
410-
/* is_dir= */ mnt::NS_DIR_YES,
411-
/* is_mandatory= */ true, /* src_env= */ "",
412-
/* dst_env= */ "", /* src_content= */ "",
413-
/* is_symlink= */ false)) {
414-
return false;
401+
nsjail::MountPt* p = nsj->njc.add_mount();
402+
p->set_src(nsj->chroot);
403+
p->set_dst("/");
404+
p->set_is_bind(true);
405+
p->set_rw(nsj->is_root_rw);
406+
p->set_is_dir(true);
407+
/* Insert at the beginning */
408+
for (int i = nsj->njc.mount_size() - 1; i > 0; i--) {
409+
nsj->njc.mutable_mount()->SwapElements(i, i - 1);
415410
}
416411
} else {
417-
if (!mnt::addMountPtHead(nsj, /* src= */ "", "/", "tmpfs",
418-
/* options= */ "", nsj->is_root_rw ? 0 : MS_RDONLY,
419-
/* is_dir= */ mnt::NS_DIR_YES,
420-
/* is_mandatory= */ true, /* src_env= */ "", /* dst_env= */ "",
421-
/* src_content= */ "", /* is_symlink= */ false)) {
422-
return false;
412+
nsjail::MountPt* p = nsj->njc.add_mount();
413+
p->set_dst("/");
414+
p->set_fstype("tmpfs");
415+
p->set_rw(nsj->is_root_rw);
416+
p->set_is_dir(true);
417+
/* Insert at the beginning */
418+
for (int i = nsj->njc.mount_size() - 1; i > 0; i--) {
419+
nsj->njc.mutable_mount()->SwapElements(i, i - 1);
423420
}
424421
}
425422
if (!nsj->proc_path.empty()) {
426-
if (!mnt::addMountPtTail(nsj, /* src= */ "", nsj->proc_path, "proc",
427-
/* options= */ "", nsj->njc.mount_proc() ? 0 : MS_RDONLY,
428-
/* is_dir= */ mnt::NS_DIR_YES,
429-
/* is_mandatory= */ true, /* src_env= */ "",
430-
/* dst_env= */ "", /* src_content= */ "",
431-
/* is_symlink= */ false)) {
432-
return false;
433-
}
423+
nsjail::MountPt* p = nsj->njc.add_mount();
424+
p->set_dst(nsj->proc_path);
425+
p->set_fstype("proc");
426+
p->set_rw(nsj->njc.mount_proc());
427+
p->set_is_dir(true);
434428
}
435429

436430
return true;
@@ -606,19 +600,19 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
606600
nsj->njc.set_disable_rl(true);
607601
break;
608602
case 0x0301:
609-
nsj->personality |= ADDR_COMPAT_LAYOUT;
603+
nsj->njc.set_persona_addr_compat_layout(true);
610604
break;
611605
case 0x0302:
612-
nsj->personality |= MMAP_PAGE_ZERO;
606+
nsj->njc.set_persona_mmap_page_zero(true);
613607
break;
614608
case 0x0303:
615-
nsj->personality |= READ_IMPLIES_EXEC;
609+
nsj->njc.set_persona_read_implies_exec(true);
616610
break;
617611
case 0x0304:
618-
nsj->personality |= ADDR_LIMIT_3GB;
612+
nsj->njc.set_persona_addr_limit_3gb(true);
619613
break;
620614
case 0x0305:
621-
nsj->personality |= ADDR_NO_RANDOMIZE;
615+
nsj->njc.set_persona_addr_no_randomize(true);
622616
break;
623617
case 'N':
624618
nsj->njc.set_clone_newnet(false);
@@ -670,7 +664,8 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
670664
if (cap == -1) {
671665
return nullptr;
672666
}
673-
nsj->caps.push_back(cap);
667+
668+
nsj->njc.add_cap(optarg);
674669
} break;
675670
case 0x0600:
676671
nsj->njc.set_no_pivotroot(true);
@@ -754,38 +749,35 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
754749
if (dst.empty()) {
755750
dst = src;
756751
}
757-
if (!mnt::addMountPtTail(nsj.get(), src, dst, /* fstype= */ "",
758-
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE | MS_RDONLY,
759-
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
760-
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
761-
/* is_symlink= */ false)) {
762-
return nullptr;
763-
}
764-
}; break;
752+
nsjail::MountPt* p = nsj->njc.add_mount();
753+
p->set_src(src);
754+
p->set_dst(dst);
755+
p->set_rw(false);
756+
p->set_is_bind(true);
757+
} break;
765758
case 'B': {
766759
std::vector<std::string> subopts = util::strSplit(optarg, ':');
767760
std::string src = argFromVec(subopts, 0);
768761
std::string dst = argFromVec(subopts, 1);
769762
if (dst.empty()) {
770763
dst = src;
771764
}
772-
if (!mnt::addMountPtTail(nsj.get(), src, dst, /* fstype= */ "",
773-
/* options= */ "", MS_BIND | MS_REC | MS_PRIVATE,
774-
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
775-
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
776-
/* is_symlink= */ false)) {
777-
return nullptr;
778-
}
779-
}; break;
765+
std::string options = argFromVec(subopts, 2);
766+
nsjail::MountPt* p = nsj->njc.add_mount();
767+
p->set_src(src);
768+
p->set_dst(dst);
769+
p->set_options(options);
770+
p->set_rw(true);
771+
p->set_is_bind(true);
772+
} break;
780773
case 'T': {
781-
if (!mnt::addMountPtTail(nsj.get(), "", optarg, /* fstype= */ "tmpfs",
782-
/* options= */ "size=4194304", 0,
783-
/* is_dir= */ mnt::NS_DIR_YES, /* is_mandatory= */ true,
784-
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
785-
/* is_symlink= */ false)) {
786-
return nullptr;
787-
}
788-
}; break;
774+
nsjail::MountPt* p = nsj->njc.add_mount();
775+
p->set_dst(optarg);
776+
p->set_fstype("tmpfs");
777+
p->set_options("size=4194304");
778+
p->set_rw(true);
779+
p->set_is_dir(true);
780+
} break;
789781
case 'm': {
790782
std::vector<std::string> subopts = util::strSplit(optarg, ':');
791783
std::string src = argFromVec(subopts, 0);
@@ -800,26 +792,26 @@ std::unique_ptr<nsj_t> parseArgs(int argc, char* argv[]) {
800792
optionsStream << ":" << subopts[i];
801793
}
802794
std::string options = optionsStream.str();
803-
if (!mnt::addMountPtTail(nsj.get(), src, dst, /* fstype= */ fs_type,
804-
/* options= */ options, /* flags= */ 0,
805-
/* is_dir= */ mnt::NS_DIR_MAYBE, /* is_mandatory= */ true,
806-
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
807-
/* is_symlink= */ false)) {
808-
return nullptr;
809-
}
810-
}; break;
795+
nsjail::MountPt* p = nsj->njc.add_mount();
796+
p->set_src(src);
797+
p->set_dst(dst);
798+
p->set_fstype(fs_type);
799+
p->set_options(options);
800+
p->set_rw(true);
801+
} break;
811802
case 's': {
812803
std::vector<std::string> subopts = util::strSplit(optarg, ':');
813804
std::string src = argFromVec(subopts, 0);
814805
std::string dst = argFromVec(subopts, 1);
815-
if (!mnt::addMountPtTail(nsj.get(), src, dst, /* fstype= */ "",
816-
/* options= */ "", /* flags= */ 0,
817-
/* is_dir= */ mnt::NS_DIR_NO, /* is_mandatory= */ true,
818-
/* src_env= */ "", /* dst_env= */ "", /* src_content= */ "",
819-
/* is_symlink= */ true)) {
820-
return nullptr;
806+
if (dst.empty()) {
807+
dst = src;
821808
}
822-
}; break;
809+
nsjail::MountPt* p = nsj->njc.add_mount();
810+
p->set_src(src);
811+
p->set_dst(dst);
812+
p->set_is_symlink(true);
813+
p->set_rw(true);
814+
} break;
823815
case 'M':
824816
switch (optarg[0]) {
825817
case 'l':

config.cc

Lines changed: 0 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@
2727
#include <google/protobuf/util/json_util.h>
2828
#include <stdio.h>
2929
#include <sys/mount.h>
30-
#include <sys/personality.h>
3130
#include <sys/resource.h>
3231
#include <sys/stat.h>
3332
#include <sys/types.h>
@@ -102,35 +101,9 @@ static bool parseInternal(nsj_t* nsj, const nsjail::NsJailConfig& njc) {
102101
for (ssize_t i = 0; i < njc.envar_size(); i++) {
103102
cmdline::addEnv(nsj, njc.envar(i));
104103
}
105-
106-
for (ssize_t i = 0; i < njc.cap_size(); i++) {
107-
int cap = caps::nameToVal(njc.cap(i).c_str());
108-
if (cap == -1) {
109-
return false;
110-
}
111-
nsj->caps.push_back(cap);
112-
}
113-
114104
for (ssize_t i = 0; i < njc.pass_fd_size(); i++) {
115105
nsj->openfds.push_back(njc.pass_fd(i));
116106
}
117-
118-
if (njc.persona_addr_compat_layout()) {
119-
nsj->personality |= ADDR_COMPAT_LAYOUT;
120-
}
121-
if (njc.persona_mmap_page_zero()) {
122-
nsj->personality |= MMAP_PAGE_ZERO;
123-
}
124-
if (njc.persona_read_implies_exec()) {
125-
nsj->personality |= READ_IMPLIES_EXEC;
126-
}
127-
if (njc.persona_addr_limit_3gb()) {
128-
nsj->personality |= ADDR_LIMIT_3GB;
129-
}
130-
if (njc.persona_addr_no_randomize()) {
131-
nsj->personality |= ADDR_NO_RANDOMIZE;
132-
}
133-
134107
for (ssize_t i = 0; i < njc.uidmap_size(); i++) {
135108
if (!user::parseId(nsj, njc.uidmap(i).inside_id(), njc.uidmap(i).outside_id(),
136109
njc.uidmap(i).count(), false /* is_gid */, njc.uidmap(i).use_newidmap())) {
@@ -147,43 +120,9 @@ static bool parseInternal(nsj_t* nsj, const nsjail::NsJailConfig& njc) {
147120
if (!njc.mount_proc()) {
148121
nsj->proc_path.clear();
149122
}
150-
for (ssize_t i = 0; i < njc.mount_size(); i++) {
151-
std::string src = njc.mount(i).src();
152-
std::string src_env = njc.mount(i).prefix_src_env();
153-
std::string dst = njc.mount(i).dst();
154-
std::string dst_env = njc.mount(i).prefix_dst_env();
155-
std::string fstype = njc.mount(i).fstype();
156-
std::string options = njc.mount(i).options();
157-
158-
uintptr_t flags = (!njc.mount(i).rw()) ? MS_RDONLY : 0;
159-
flags |= njc.mount(i).is_bind() ? (MS_BIND | MS_REC | MS_PRIVATE) : 0;
160-
flags |= njc.mount(i).nosuid() ? MS_NOSUID : 0;
161-
flags |= njc.mount(i).nodev() ? MS_NODEV : 0;
162-
flags |= njc.mount(i).noexec() ? MS_NOEXEC : 0;
163-
bool is_mandatory = njc.mount(i).mandatory();
164-
bool is_symlink = njc.mount(i).is_symlink();
165-
std::string src_content = njc.mount(i).src_content();
166-
167-
mnt::isDir_t is_dir = mnt::NS_DIR_MAYBE;
168-
if (njc.mount(i).has_is_dir()) {
169-
is_dir = njc.mount(i).is_dir() ? mnt::NS_DIR_YES : mnt::NS_DIR_NO;
170-
}
171-
172-
if (!mnt::addMountPtTail(nsj, src, dst, fstype, options, flags, is_dir,
173-
is_mandatory, src_env, dst_env, src_content, is_symlink)) {
174-
LOG_E("Couldn't add mountpoint for src:%s dst:%s", QC(src), QC(dst));
175-
return false;
176-
}
177-
}
178-
179123
if (njc.has_seccomp_policy_file()) {
180124
nsj->njc.set_seccomp_policy_file(njc.seccomp_policy_file());
181125
}
182-
/* seccomp_string is handled via nsj->njc.CopyFrom(njc) above */
183-
184-
for (ssize_t i = 0; i < njc.iface_own().size(); i++) {
185-
nsj->ifaces.push_back(njc.iface_own(i));
186-
}
187126

188127
if (njc.has_exec_bin()) {
189128
if (njc.exec_bin().has_path()) {

configs/bash-with-fake-geteuid.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ clone_newuts: true
6262
clone_newcgroup: true
6363

6464
user_net {
65-
enable: true
65+
enable: true
6666
tcp_ports: "auto"
6767
udp_ports: "auto"
6868
}

0 commit comments

Comments
 (0)