@@ -34,7 +34,7 @@ pub enum Error {
3434 source : io:: Error ,
3535 } ,
3636 #[ error( "kernel source must be under {}: {path}" , . base. display( ) ) ]
37- OutsideBase { base : & ' static Path , path : PathBuf } ,
37+ OutsideBase { base : PathBuf , path : PathBuf } ,
3838 #[ error( "open kernel source {path}: {source}" ) ]
3939 OpenSrc {
4040 path : PathBuf ,
@@ -103,41 +103,53 @@ impl<K> ChrootJail<K, Unset> {
103103}
104104
105105impl ChrootJail < Kernel , Rootfs > {
106- /// Realize the jail on disk: confined walk to the chroot dir, then stage the
107- /// kernel and create the rootfs node relative to that fd.
106+ /// Realize the jail on disk under the configured `JAIL_BASE`/`HYPER_BASE`.
108107 pub fn build ( self ) -> Result < ( ) , Error > {
109- let chroot = open_chroot ( & self . chroot ) ?;
110- stage_kernel ( & chroot, & self . kernel . 0 , self . uid , self . gid ) ?;
108+ let cfg = Config :: get ( ) ;
109+ self . build_under ( & cfg. jail_base ( ) , cfg. hyper_base ( ) )
110+ }
111+
112+ /// Realize the jail relative to explicit base directories: confined walk to
113+ /// the chroot dir, then stage the kernel and create the rootfs node relative
114+ /// to that fd. The public [`build`](Self::build) wires `Config` into this.
115+ pub fn build_under ( self , jail_base : & Path , hyper_base : & Path ) -> Result < ( ) , Error > {
116+ let chroot = open_chroot_under ( jail_base, & self . chroot ) ?;
117+ stage_kernel_under ( & chroot, & self . kernel . 0 , hyper_base, self . uid , self . gid ) ?;
111118 make_rootfs ( & chroot, & self . rootfs . 0 , self . uid , self . gid ) ?;
112119 Ok ( ( ) )
113120 }
114121}
115122
116- /// Open the chroot directory by walking it from `JAIL_BASE ` with `O_NOFOLLOW`, so
123+ /// Open the chroot directory by walking it from `jail_base ` with `O_NOFOLLOW`, so
117124/// a symlinked component cannot redirect outside the jail.
118- fn open_chroot ( chroot : & Path ) -> Result < SafeDir , Error > {
119- let jail_base = Config :: get ( ) . jail_base ( ) ;
125+ pub fn open_chroot_under ( jail_base : & Path , chroot : & Path ) -> Result < SafeDir , Error > {
120126 let path: SafePath < IsAbsolute , StrictComponents > = chroot. to_path_buf ( ) . try_into ( ) ?;
121- let ( parents, leaf) = path. relative_to ( & jail_base) ?;
122- let anchor: SafePath < IsAbsolute , StrictComponents > = jail_base. try_into ( ) ?;
127+ let ( parents, leaf) = path. relative_to ( jail_base) ?;
128+ let anchor: SafePath < IsAbsolute , StrictComponents > = jail_base. to_path_buf ( ) . try_into ( ) ?;
123129
124130 let mut components = parents;
125131 components. push ( leaf) ;
126132 Ok ( SafeDir :: open ( & anchor) ?. descend ( & components) ?)
127133}
128134
129135/// Stage host file `src` into `chroot` as `vmlinux`: confine the source under
130- /// `HYPER_BASE`, hard-link it (copy across filesystems), then chown to `uid:gid`.
131- fn stage_kernel ( chroot : & SafeDir , src : & Path , uid : u32 , gid : u32 ) -> Result < ( ) , Error > {
136+ /// `hyper_base` (after canonicalization), hard-link it (copy across filesystems),
137+ /// then chown to `uid:gid`.
138+ pub fn stage_kernel_under (
139+ chroot : & SafeDir ,
140+ src : & Path ,
141+ hyper_base : & Path ,
142+ uid : u32 ,
143+ gid : u32 ,
144+ ) -> Result < ( ) , Error > {
132145 let kernel = Path :: new ( KERNEL_NAME ) ;
133146 let src_canon = std:: fs:: canonicalize ( src) . map_err ( |source| Error :: Source {
134147 path : src. to_path_buf ( ) ,
135148 source,
136149 } ) ?;
137- let base = Config :: get ( ) . hyper_base ( ) ;
138- if !src_canon. starts_with ( base) {
150+ if !src_canon. starts_with ( hyper_base) {
139151 return Err ( Error :: OutsideBase {
140- base,
152+ base : hyper_base . to_path_buf ( ) ,
141153 path : src_canon,
142154 } ) ;
143155 }
0 commit comments