@@ -20,6 +20,7 @@ use cap_std_ext::cap_tempfile::TempDir;
2020use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
2121use cap_std_ext:: dirext:: CapStdExtDirExt ;
2222use fn_error_context:: context;
23+ use ostree_ext:: ostree:: { self } ;
2324use std:: os:: fd:: OwnedFd ;
2425use tokio:: process:: Command as AsyncCommand ;
2526
@@ -35,6 +36,8 @@ pub(crate) const STORAGE_ALIAS_DIR: &str = "/run/bootc/storage";
3536/// We pass this via /proc/self/fd to the child process.
3637const STORAGE_RUN_FD : i32 = 3 ;
3738
39+ const LABELED : & str = ".bootc_labeled" ;
40+
3841/// The path to the image storage, relative to the bootc root directory.
3942pub ( crate ) const SUBPATH : & str = "storage" ;
4043/// The path to the "runroot" with transient runtime state; this is
@@ -161,24 +164,68 @@ impl Storage {
161164 Ok ( ( ) )
162165 }
163166
167+ #[ context( "Labeling imgstorage dirs" ) ]
168+ fn label_dirs ( root : & Dir , sepolicy : Option < & ostree:: SePolicy > ) -> Result < ( ) > {
169+ if root. try_exists ( LABELED ) ? {
170+ return Ok ( ( ) ) ;
171+ }
172+ let Some ( sepolicy) = sepolicy else {
173+ return Ok ( ( ) ) ;
174+ } ;
175+
176+ // recursively set the labels because they were previously set to usr_t,
177+ // and there is no policy defined to set them to the c/storage labels
178+ crate :: lsm:: ensure_dir_labeled_recurse_policy (
179+ & root,
180+ "." ,
181+ Some ( Utf8Path :: new ( "/var/lib/containers/storage" ) ) ,
182+ 0o755 . into ( ) ,
183+ Some ( sepolicy) ,
184+ )
185+ . context ( "labeling storage root" ) ?;
186+
187+ let paths = [ "overlay" , "overlay-images" , "overlay-layers" , "volumes" ] ;
188+ for p in paths {
189+ let full_label_path = format ! ( "/var/lib/containers/storage/{}" , p) ;
190+ crate :: lsm:: ensure_dir_labeled_recurse_policy (
191+ & root,
192+ p,
193+ Some ( Utf8Path :: new ( full_label_path. as_str ( ) ) ) ,
194+ 0o755 . into ( ) ,
195+ Some ( sepolicy) ,
196+ )
197+ . context ( format ! ( "labeling storage subpath: {}" , p) ) ?;
198+ }
199+
200+ root. create ( LABELED ) ?;
201+
202+ Ok ( ( ) )
203+ }
204+
164205 #[ context( "Creating imgstorage" ) ]
165- pub ( crate ) fn create ( sysroot : & Dir , run : & Dir ) -> Result < Self > {
206+ pub ( crate ) fn create (
207+ sysroot : & Dir ,
208+ run : & Dir ,
209+ sepolicy : Option < & ostree:: SePolicy > ,
210+ ) -> Result < Self > {
166211 Self :: init_globals ( ) ?;
167212 let subpath = & Self :: subpath ( ) ;
168213
169214 // SAFETY: We know there's a parent
170215 let parent = subpath. parent ( ) . unwrap ( ) ;
216+ let tmp = format ! ( "{subpath}.tmp" ) ;
171217 if !sysroot
172218 . try_exists ( subpath)
173219 . with_context ( || format ! ( "Querying {subpath}" ) ) ?
174220 {
175- let tmp = format ! ( "{subpath}.tmp" ) ;
176221 sysroot. remove_all_optional ( & tmp) . context ( "Removing tmp" ) ?;
177222 sysroot
178223 . create_dir_all ( parent)
179224 . with_context ( || format ! ( "Creating {parent}" ) ) ?;
180225 sysroot. create_dir_all ( & tmp) . context ( "Creating tmpdir" ) ?;
181226 let storage_root = sysroot. open_dir ( & tmp) . context ( "Open tmp" ) ?;
227+ Self :: label_dirs ( & storage_root, sepolicy) ?;
228+
182229 // There's no explicit API to initialize a containers-storage:
183230 // root, simply passing a path will attempt to auto-create it.
184231 // We run "podman images" in the new root.
@@ -192,7 +239,12 @@ impl Storage {
192239 . rename ( & tmp, sysroot, subpath)
193240 . context ( "Renaming tmpdir" ) ?;
194241 tracing:: debug!( "Created image store" ) ;
242+ } else {
243+ // the storage already exists, make sure it has selinux labels
244+ let storage_root = sysroot. open_dir ( subpath) . context ( "opening storage dir" ) ?;
245+ Self :: label_dirs ( & storage_root, sepolicy) ?;
195246 }
247+
196248 Self :: open ( sysroot, run)
197249 }
198250
0 commit comments