Repositories / jai.git

jai.git

Clone (read-only): git clone http://git.guha-anderson.com/git/jai.git

Branch

Mount an isolated tmpfs at /dev/shm inside each jail

Previously /dev/shm was left readonly (inherited from the blanket
MOUNT_ATTR_RDONLY applied to /). Now each jail gets a fresh private
tmpfs at /dev/shm, giving jailed processes writable shared memory
that is fully isolated from the host and from other jails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
Arjun Guha <a.guha@northeastern.edu>
Date
2026-04-02 13:13:27 -0400
Commit
3edf7c2431f0fae7f47decf8ecdd64cc6cc91147
jai.cc
index a1f393b..1eb3984 100644
--- a/jai.cc
+++ b/jai.cc
@@ -438,6 +438,7 @@ Config::make_mnt_ns()
       .propagation = MS_PRIVATE,
   };
   Fd tmp = clone_tree(*mp_holder_.emplace_back(make_private_tmp()));
+  Fd shm = make_tmpfs("jai-shm", "mode", "01777", "size", "50%");
 
   Fd passwd;
   if (mode_ == kStrict)
@@ -468,6 +469,7 @@ Config::make_mnt_ns()
     home = clone_tree(*ensure_udir(storage(), cat(sandbox_name_, ".home")));
   }
   xmnt_setattr(*tmp, attr);
+  xmnt_setattr(*shm, attr);
   xmnt_setattr(*home, attr);
   if (passwd)
     xmnt_setattr(*passwd, attr);
@@ -487,7 +489,9 @@ Config::make_mnt_ns()
     syserr("umount2({}, MNT_DETACH)", kRunRoot);
   umount2("/tmp", MNT_DETACH);     // ignore error
   umount2("/var/tmp", MNT_DETACH); // ignore error
+  umount2("/dev/shm", MNT_DETACH); // ignore error
   xmnt_move(*tmp, -1, "/tmp");
+  xmnt_move(*shm, -1, "/dev/shm");
   xmnt_move(*clone_tree(-1, "/tmp"), -1, "/var/tmp", 0);
   xmnt_move(*home, -1, homepath_);
   if (passwd)