minijail: Add support for building constants through masks
This change adds support for building numeric constants through
bitmasks. Things like "O_WRONLY|O_CREAT" are now valid constants.
Since this change works at the atom level, there can be no spaces around
the "|" character.
BUG=chromium:516701
TEST=syscall_filter_unittest passes.
Change-Id: Ia74957f4c5661c9dff7df072684cc6d725c83c10
Reviewed-on: https://chromium-review.googlesource.com/290468
Tested-by: Luis Hector Chavez <lhchavez@google.com>
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
Commit-Queue: Luis Hector Chavez <lhchavez@google.com>
diff --git a/util.c b/util.c
index 6b16a23..90ac9f0 100644
--- a/util.c
+++ b/util.c
@@ -40,6 +40,8 @@
const size_t log_syscalls_len = sizeof(log_syscalls)/sizeof(log_syscalls[0]);
+long int parse_single_constant(char *constant_str, char **endptr);
+
int lookup_syscall(const char *name)
{
const struct syscall_entry *entry = syscall_table;
@@ -60,6 +62,36 @@
long int parse_constant(char *constant_str, char **endptr)
{
+ long int value = 0;
+ char *group, *lastpos = constant_str;
+ char *original_constant_str = constant_str;
+
+ /*
+ * Try to parse constants separated by pipes. Note that since
+ * |constant_str| is an atom, there can be no spaces between the
+ * constant and the pipe. Constants can be either a named constant
+ * defined in libconstants.gen.c or a number parsed with strtol.
+ *
+ * If there is an error parsing any of the constants, the whole process
+ * fails.
+ */
+ while ((group = tokenize(&constant_str, "|")) != NULL) {
+ char *end = group;
+ value |= parse_single_constant(group, &end);
+ if (end == group) {
+ lastpos = original_constant_str;
+ value = 0;
+ break;
+ }
+ lastpos = end;
+ }
+ if (endptr)
+ *endptr = lastpos;
+ return value;
+}
+
+long int parse_single_constant(char *constant_str, char **endptr)
+{
const struct constant_entry *entry = constant_table;
for (; entry->name; ++entry) {
if (!strcmp(entry->name, constant_str)) {