minijail: accept named uid/gid.
This will let us stop hardcoding uids everywhere.
TEST=platform_MiniJailUidGid
BUG=chromium-os:5327
Change-Id: I9b8029ac4e3a3cb6c80740ba4c60d1aaba4831d6
Signed-off-by: Elly Jones <ellyjones@chromium.org>
Reviewed-on: http://gerrit.chromium.org/gerrit/3744
Reviewed-by: Chris Masone <cmasone@chromium.org>
diff --git a/minijail_main.cc b/minijail_main.cc
index ab8bf27..5cae413 100644
--- a/minijail_main.cc
+++ b/minijail_main.cc
@@ -9,9 +9,12 @@
#include "minijail/minijail.h"
#include <errno.h>
+#include <grp.h>
#include <linux/capability.h>
+#include <pwd.h>
#include <stdio.h>
#include <sys/prctl.h>
+#include <sys/types.h>
#include <unistd.h>
#include <iostream>
@@ -74,6 +77,46 @@
} // namespace switches
+static bool ParseUid(const std::string& str, uid_t *uid) {
+ int32 v;
+ if (base::StringToInt(str, &v)) {
+ *uid = v;
+ return true;
+ }
+
+ // Not an integer. Let's try for a user.
+ // Any character except ':' is valid in a username.
+ if (strchr(str.c_str(), ':'))
+ return false;
+ struct passwd *user = getpwnam(str.c_str());
+ if (user) {
+ *uid = user->pw_uid;
+ return true;
+ }
+
+ return false;
+}
+
+static bool ParseGid(const std::string& str, gid_t *gid) {
+ int32 v;
+ if (base::StringToInt(str, &v)) {
+ *gid = v;
+ return true;
+ }
+
+ // Not an integer, look for a group
+ // Any character except ':' is valid in a group name.
+ if (strchr(str.c_str(), ':'))
+ return false;
+ struct group *group = getgrnam(str.c_str());
+ if (group) {
+ *gid = group->gr_gid;
+ return true;
+ }
+
+ return false;
+}
+
static void ProcessSwitches(CommandLine *cl,
chromeos::MiniJailOptions *jail_opts) {
if (cl->HasSwitch(switches::kHelp)) {
@@ -108,17 +151,21 @@
std::string uid_string = cl->GetSwitchValueASCII(switches::kUid);
if (!uid_string.empty()) {
- errno = 0;
- uid_t uid = static_cast<uid_t>(strtol(uid_string.c_str(), NULL, 0));
- PLOG_IF(WARNING, errno) << "failed to parse uid";
+ uid_t uid;
+ if (!ParseUid(uid_string.c_str(), &uid)) {
+ LOG(ERROR) << "Failed to parse uid: " << uid_string;
+ exit(1);
+ }
jail_opts->set_uid(uid);
}
std::string gid_string = cl->GetSwitchValueASCII(switches::kGid);
if (!gid_string.empty()) {
- errno = 0;
- gid_t gid = static_cast<gid_t>(strtol(gid_string.c_str(), NULL, 0));
- PLOG_IF(WARNING, errno) << "failed to parse gid";
+ gid_t gid;
+ if (!ParseGid(gid_string.c_str(), &gid)) {
+ LOG(ERROR) << "Failed to parse gid: " << gid_string;
+ exit(1);
+ }
jail_opts->set_gid(gid);
}