Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: make upgrading demo accounts available via a config option. #3614

Draft
wants to merge 3 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/sandstorm/config.c++
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,8 @@ Config readConfig(const char *path, bool parseUids) {
config.allowDemoAccounts = value == "true" || value == "yes";
} else if (key == "ALLOW_DEV_ACCOUNTS") {
config.allowDevAccounts = value == "true" || value == "yes";
} else if (key == "ALLOW_UNINVITED") {
config.allowUninvited = value == "true" || value == "yes";
} else if (key == "IS_TESTING") {
config.isTesting = value == "true" || value == "yes";
} else if (key == "HIDE_TROUBLESHOOTING") {
Expand Down
1 change: 1 addition & 0 deletions src/sandstorm/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ struct Config {
kj::String sandcatsHostname = nullptr;
bool allowDemoAccounts = false;
bool isTesting = false;
bool allowUninvited = false;
bool allowDevAccounts = false;
bool hideTroubleshooting = false;
uint smtpListenPort = 30025;
Expand Down
50 changes: 35 additions & 15 deletions src/sandstorm/run-bundle.c++
Original file line number Diff line number Diff line change
Expand Up @@ -1396,23 +1396,21 @@ private:
}
}

void idMapUidNamespace(uid_t uid, gid_t gid) {
// Identity-map the given uid & gid in the current uid namespace.
writeSetgroupsIfPresent("deny\n");
writeUserNSMap("uid", kj::str(uid, " ", uid, " 1\n"));
writeUserNSMap("gid", kj::str(gid, " ", gid, " 1\n"));
}

void unshareUidNamespaceOnce() {
if (!unsharedUidNamespace) {
uid_t uid = getuid();
gid_t gid = getgid();

KJ_SYSCALL(unshare(CLONE_NEWUSER));

// Set up the UID namespace. We map ourselves as UID zero because this allows capabilities
// to be inherited through exec(), which we need to support update and restart. With any
// other UID, capabilities can only be inherited through exec() if the target exec'd file
// has its inheritable capabilities set filled. By default, the inheritable capability set
// for all files is empty, and only the filesystem's superuser (i.e. not us) can change them.
// But if our UID is zero, then the file's attributes are ignored and all capabilities are
// inherited.
writeSetgroupsIfPresent("deny\n");
writeUserNSMap("uid", kj::str("0 ", uid, " 1\n"));
writeUserNSMap("gid", kj::str("0 ", gid, " 1\n"));
idMapUidNamespace(uid, gid);

unsharedUidNamespace = true;
}
Expand Down Expand Up @@ -1951,10 +1949,23 @@ private:

pid_t updaterPid = startUpdater(config, fdBundle, false);

pid_t sandstormPid = fork();
if (sandstormPid == 0) {
runServerMonitor(config, fdBundle);
KJ_UNREACHABLE;
// Start the server monitor.
pid_t sandstormPid;
{
int cloneFlags = CLONE_PARENT_SETTID | SIGCHLD;
if(!runningAsRoot) {
cloneFlags |= CLONE_NEWUSER|CLONE_NEWPID;
unsharedUidNamespace = true;
}

uid_t uid = getuid();
gid_t gid = getgid();

KJ_SYSCALL(syscall(SYS_clone, cloneFlags, nullptr, &sandstormPid, 0));
if(sandstormPid == 0) {
runServerMonitor(config, fdBundle, uid, gid);
KJ_UNREACHABLE;
}
}

for (;;) {
Expand Down Expand Up @@ -2019,11 +2030,19 @@ private:
}
}

[[noreturn]] void runServerMonitor(const Config& config, FdBundle& fdBundle) {
[[noreturn]] void runServerMonitor(const Config& config, FdBundle& fdBundle,
uid_t uid, gid_t gid) {
// Run the server monitor, which runs node and mongo and deals with them dying.
// The uid and gid should be the uid and gid for the parent process in its own
// user namespace (if user namespaces are in use).

setProcessName("montr", "(server monitor)");

if(!runningAsRoot) {
// We were cloned into a new user namespace, so we need to set up a mapping:
idMapUidNamespace(uid, gid);
}

enterChroot(config.uids, true);

// Make sure socket directory exists (since the installer doesn't create it).
Expand Down Expand Up @@ -2640,6 +2659,7 @@ private:
"{ \"build\":", buildstamp,
", \"allowDemoAccounts\":", config.allowDemoAccounts ? "true" : "false",
", \"allowDevAccounts\":", config.allowDevAccounts ? "true" : "false",
", \"allowUninvited\":", config.allowUninvited ? "true" : "false",
", \"isTesting\":", config.isTesting ? "true" : "false",
", \"hideTroubleshooting\":", config.hideTroubleshooting ? "true" : "false",
", \"wildcardHost\":\"", config.wildcardHost, "\"",
Expand Down
1 change: 1 addition & 0 deletions tests/run-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ rm -rf "$SANDSTORM_DIR"

echo "IS_TESTING=true
ALLOW_DEMO_ACCOUNTS=true
ALLOW_UNINVITED=true
BASE_URL=http://local.sandstorm.io:$PORT
WILDCARD_HOST=*.local.sandstorm.io:$PORT
PORT=$PORT
Expand Down