minijail: Check correct executable file

When the chroot and pivot_root options are used the path to the binary
to put in jail is given relative to the new root.  However the checks
for the program existing and how it is linked were still done relative
the original rootfs.  This "worked" as long as there was a similar file
outside of the chroot.  Add the ability to get the full path of the
program from libminijail and use that path to check the file.

This allows chrooting to a system that has init in / instead of /sbin.

Don't try to check the binary if there are bind mounts specified.  This
avoids having to parse the mounts and check if the binary is in a bind
mounted path.

Change-Id: I2e3af14f5e8fd478963bcb56a3a6ae5908e78524
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/300320
Reviewed-by: Jorge Lucangeli Obes <jorgelo@chromium.org>
diff --git a/libminijail.h b/libminijail.h
index 07f0762..d6c3c42 100644
--- a/libminijail.h
+++ b/libminijail.h
@@ -77,6 +77,18 @@
 int minijail_enter_chroot(struct minijail *j, const char *dir);
 int minijail_enter_pivot_root(struct minijail *j, const char *dir);
 
+/* minijail_get_original_path: returns the path of a given file outside of the
+ * chroot.
+ * @j           minijail to obtain the path from.
+ * @chroot_path path inside of the chroot() to.
+ *
+ * When executing a binary in a chroot or pivot_root, return path to the binary
+ * outside of the chroot.
+ *
+ * Returns a string containing the path.  This must be freed by the caller.
+ */
+char *minijail_get_original_path(struct minijail *j, const char *chroot_path);
+
 /* minijail_mount_tmp: enables mounting of a tmpfs filesystem on /tmp.
  * As be rules of bind mounts, /tmp must exist in chroot.
  */
@@ -94,6 +106,11 @@
 int minijail_bind(struct minijail *j, const char *src, const char *dest,
 		  int writeable);
 
+/* minijail_has_bind_mounts: Checks if there are any bind mounts configured.
+ * @j         minijail to check
+ */
+int minijail_has_bind_mounts(const struct minijail *j);
+
 /* Lock this process into the given minijail. Note that this procedure cannot fail,
  * since there is no way to undo privilege-dropping; therefore, if any part of
  * the privilege-drop fails, minijail_enter() will abort the entire process.