@@ -20,6 +20,7 @@ use cap_std_ext::cap_tempfile::TempDir;
20
20
use cap_std_ext:: cmdext:: CapStdExtCommandExt ;
21
21
use cap_std_ext:: dirext:: CapStdExtDirExt ;
22
22
use fn_error_context:: context;
23
+ use ostree_ext:: ostree:: { self } ;
23
24
use std:: os:: fd:: OwnedFd ;
24
25
use tokio:: process:: Command as AsyncCommand ;
25
26
@@ -35,6 +36,8 @@ pub(crate) const STORAGE_ALIAS_DIR: &str = "/run/bootc/storage";
35
36
/// We pass this via /proc/self/fd to the child process.
36
37
const STORAGE_RUN_FD : i32 = 3 ;
37
38
39
+ const LABELED : & str = ".bootc_labeled" ;
40
+
38
41
/// The path to the image storage, relative to the bootc root directory.
39
42
pub ( crate ) const SUBPATH : & str = "storage" ;
40
43
/// The path to the "runroot" with transient runtime state; this is
@@ -161,24 +164,68 @@ impl Storage {
161
164
Ok ( ( ) )
162
165
}
163
166
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
+
164
205
#[ 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 > {
166
211
Self :: init_globals ( ) ?;
167
212
let subpath = & Self :: subpath ( ) ;
168
213
169
214
// SAFETY: We know there's a parent
170
215
let parent = subpath. parent ( ) . unwrap ( ) ;
216
+ let tmp = format ! ( "{subpath}.tmp" ) ;
171
217
if !sysroot
172
218
. try_exists ( subpath)
173
219
. with_context ( || format ! ( "Querying {subpath}" ) ) ?
174
220
{
175
- let tmp = format ! ( "{subpath}.tmp" ) ;
176
221
sysroot. remove_all_optional ( & tmp) . context ( "Removing tmp" ) ?;
177
222
sysroot
178
223
. create_dir_all ( parent)
179
224
. with_context ( || format ! ( "Creating {parent}" ) ) ?;
180
225
sysroot. create_dir_all ( & tmp) . context ( "Creating tmpdir" ) ?;
181
226
let storage_root = sysroot. open_dir ( & tmp) . context ( "Open tmp" ) ?;
227
+ Self :: label_dirs ( & storage_root, sepolicy) ?;
228
+
182
229
// There's no explicit API to initialize a containers-storage:
183
230
// root, simply passing a path will attempt to auto-create it.
184
231
// We run "podman images" in the new root.
@@ -192,7 +239,12 @@ impl Storage {
192
239
. rename ( & tmp, sysroot, subpath)
193
240
. context ( "Renaming tmpdir" ) ?;
194
241
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) ?;
195
246
}
247
+
196
248
Self :: open ( sysroot, run)
197
249
}
198
250
0 commit comments