Snap for 4574286 from 4dcfe93e345084bd0f5b9760e134a4722efee122 to pi-release

Change-Id: Id3e318809f6f7618ca360cf2d0cd8fd8d5f3e0d7
diff --git a/libminijail.c b/libminijail.c
index 9cf3232..900acd5 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -84,8 +84,8 @@
 
 struct minijail_rlimit {
 	int type;
-	uint32_t cur;
-	uint32_t max;
+	rlim_t cur;
+	rlim_t max;
 };
 
 struct mountpoint {
@@ -662,8 +662,7 @@
 	return 0;
 }
 
-int API minijail_rlimit(struct minijail *j, int type, uint32_t cur,
-			uint32_t max)
+int API minijail_rlimit(struct minijail *j, int type, rlim_t cur, rlim_t max)
 {
 	size_t i;
 
diff --git a/libminijail.h b/libminijail.h
index 46dc311..04e4153 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -16,6 +16,7 @@
 #define _LIBMINIJAIL_H_
 
 #include <stdint.h>
+#include <sys/resource.h>
 #include <sys/types.h>
 
 #ifdef __cplusplus
@@ -128,7 +129,7 @@
 int minijail_use_alt_syscall(struct minijail *j, const char *table);
 
 /* Sets the given runtime limit. See getrlimit(2). */
-int minijail_rlimit(struct minijail *j, int type, uint32_t cur, uint32_t max);
+int minijail_rlimit(struct minijail *j, int type, rlim_t cur, rlim_t max);
 
 /*
  * Adds the jailed process to the cgroup given by |path|.  |path| should be the
diff --git a/minijail0.1 b/minijail0.1
index 52f98e2..9c962b4 100644
--- a/minijail0.1
+++ b/minijail0.1
@@ -119,8 +119,10 @@
 that even if the process has write access to a system config knob in /proc
 (e.g., in /sys/kernel), it cannot change the value.
 .TP
-\fB-R <rlim_type, rlim_cur, rlim_max>\fR
-Set an rlimit value, see \fBgetrlimit\fR(2) for allowed values.
+\fB-R <rlim_type>,<rlim_cur>,<rlim_max>\fR
+Set an rlimit value, see \fBgetrlimit\fR(2) for allowed values. The string
+\fBunlimited\fR can be used for \fBrlim_cur\fR and \fBrlim_max\fR, which will
+translate to \fBRLIM_INFINITY\fR.
 .TP
 \fB-s\fR
 Enable \fBseccomp\fR(2) in mode 1, which restricts the child process to a very
diff --git a/minijail0_cli.c b/minijail0_cli.c
index dc83c8b..ea4b6cc 100644
--- a/minijail0_cli.c
+++ b/minijail0_cli.c
@@ -115,12 +115,35 @@
 	char *type = tokenize(&arg, ",");
 	char *cur = tokenize(&arg, ",");
 	char *max = tokenize(&arg, ",");
+	char *end;
 	if (!type || type[0] == '\0' || !cur || cur[0] == '\0' ||
 	    !max || max[0] == '\0' || arg != NULL) {
 		fprintf(stderr, "Bad rlimit '%s'.\n", arg);
 		exit(1);
 	}
-	if (minijail_rlimit(j, atoi(type), atoi(cur), atoi(max))) {
+	rlim_t cur_rlim;
+	rlim_t max_rlim;
+	if (!strcmp(cur, "unlimited")) {
+		cur_rlim = RLIM_INFINITY;
+	} else {
+		end = NULL;
+		cur_rlim = strtoul(cur, &end, 10);
+		if (*end) {
+			fprintf(stderr, "Bad soft limit: '%s'.\n", cur);
+			exit(1);
+		}
+	}
+	if (!strcmp(max, "unlimited")) {
+		max_rlim = RLIM_INFINITY;
+	} else {
+		end = NULL;
+		max_rlim = strtoul(max, &end, 10);
+		if (*end) {
+			fprintf(stderr, "Bad hard limit: '%s'.\n", max);
+			exit(1);
+		}
+	}
+	if (minijail_rlimit(j, atoi(type), cur_rlim, max_rlim)) {
 		fprintf(stderr, "minijail_rlimit '%s,%s,%s' failed.\n", type,
 			cur, max);
 		exit(1);
diff --git a/minijail0_cli_unittest.cc b/minijail0_cli_unittest.cc
index 856243a..e6cf544 100644
--- a/minijail0_cli_unittest.cc
+++ b/minijail0_cli_unittest.cc
@@ -215,6 +215,12 @@
 
   argv[1] = "0,1,2";
   ASSERT_TRUE(parse_args_(argv));
+
+  argv[1] = "1,1,unlimited";
+  ASSERT_TRUE(parse_args_(argv));
+
+  argv[1] = "2,unlimited,2";
+  ASSERT_TRUE(parse_args_(argv));
 }
 
 // Invalid calls to the rlimit option.
@@ -234,8 +240,12 @@
   argv[1] = "0,0,0,0";
   ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
 
-  // TODO: We probably should reject non-numbers, but the current CLI ignores
-  // them and converts them to zeros.  Oops.
+  // Non-numeric limits
+  argv[1] = "0,0,invalid-limit";
+  ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
+
+  argv[1] = "0,0,0j";
+  ASSERT_EXIT(parse_args_(argv), testing::ExitedWithCode(1), "");
 }
 
 // Valid calls to the profile option.