minijail0: honor readonly bind mounts

linux-kernel commit 2e4b7fcd926006531935a4c79a5e9349fe51125b introduced support
for readonly bind mounts, but you can't just supply MS_RDONLY along with
MS_BIND; you have to construct an MS_BIND mount first, then do another mount
with MS_REMOUNT | MS_RDONLY.

BUG=None
TEST=platform_Minijail0

Change-Id: I1a8e2c603589b2eddcdb7a6d87059fabe17c60ba
Signed-off-by: Elly Jones <ellyjones@chromium.org>
Reviewed-on: https://gerrit.chromium.org/gerrit/13000
Reviewed-by: Will Drewry <wad@chromium.org>
diff --git a/libminijail.c b/libminijail.c
index 5d6d7c4..708c68c 100644
--- a/libminijail.c
+++ b/libminijail.c
@@ -575,15 +575,20 @@
 int bind_one(const struct minijail *j, struct binding *b) {
 	int ret = 0;
 	char *dest = NULL;
-	int mflags = MS_BIND | (b->writeable ? 0 : MS_RDONLY);
 	if (ret)
 		return ret;
 	/* dest has a leading "/" */
 	if (asprintf(&dest, "%s%s", j->chrootdir, b->dest) < 0)
 		return -ENOMEM;
-	ret = mount(b->src, dest, NULL, mflags, NULL);
+	ret = mount(b->src, dest, NULL, MS_BIND, NULL);
 	if (ret)
 		pdie("bind: %s -> %s", b->src, dest);
+	if (!b->writeable) {
+		ret = mount(b->src, dest, NULL,
+		            MS_BIND | MS_REMOUNT | MS_RDONLY, NULL);
+		if (ret)
+			pdie("bind ro: %s -> %s", b->src, dest);
+	}
 	free(dest);
 	if (b->next)
 		return bind_one(j, b->next);