1
1
use std:: pin:: pin;
2
+ use std:: sync:: { Arc , Mutex } ;
2
3
use std:: time:: Duration ;
3
4
4
- use super :: { IoStream , IoStreamSource } ;
5
-
6
5
use anyhow:: { anyhow, Context , Error , Result } ;
7
6
use bollard:: service:: EventMessage ;
8
7
use futures:: future:: { BoxFuture , Shared } ;
9
8
use futures:: FutureExt ;
10
- use tokio:: io:: AsyncWriteExt ;
11
9
use tokio:: signal:: unix:: { signal, SignalKind } ;
12
10
use tokio:: task:: { spawn, JoinHandle } ;
13
11
use tokio_stream:: StreamExt ;
14
12
13
+ use super :: cgroup:: { Access , DeviceAccessController , DeviceAccessControllerV1 , DeviceType } ;
14
+ use super :: { IoStream , IoStreamSource } ;
15
+
15
16
#[ derive( Clone ) ]
16
17
pub struct Container {
17
18
id : String ,
18
19
docker : bollard:: Docker ,
19
20
remove_event : Shared < BoxFuture < ' static , Option < EventMessage > > > ,
21
+ cgroup_device_filter : Arc < Mutex < Box < dyn DeviceAccessController + Send > > > ,
20
22
}
21
23
22
24
impl Container {
@@ -37,10 +39,14 @@ impl Container {
37
39
. boxed ( )
38
40
. shared ( ) ;
39
41
42
+ let cgroup_device_filter: Box < dyn DeviceAccessController + Send > =
43
+ Box :: new ( DeviceAccessControllerV1 :: new ( id) ?) ;
44
+
40
45
Ok ( Self {
41
46
id : id. to_owned ( ) ,
42
47
docker : docker. clone ( ) ,
43
48
remove_event : remove_evevnt,
49
+ cgroup_device_filter : Arc :: new ( Mutex :: new ( cgroup_device_filter) ) ,
44
50
} )
45
51
}
46
52
@@ -76,6 +82,7 @@ impl Container {
76
82
. await
77
83
. context ( "no destroy event" ) ?;
78
84
}
85
+
79
86
Ok ( ( ) )
80
87
}
81
88
@@ -219,24 +226,21 @@ impl Container {
219
226
( major, minor) : ( u32 , u32 ) ,
220
227
( r, w, m) : ( bool , bool , bool ) ,
221
228
) -> Result < ( ) > {
222
- let mut permissions = String :: new ( ) ;
223
- if r {
224
- permissions. push ( 'r' ) ;
225
- }
226
- if w {
227
- permissions. push ( 'w' ) ;
228
- }
229
- if m {
230
- permissions. push ( 'm' ) ;
231
- }
232
-
233
- deny_device_cgroup1 ( & self . id , major, minor, "rwm" ) . await ?;
229
+ let controller = self . cgroup_device_filter . clone ( ) ;
230
+ tokio:: task:: spawn_blocking ( move || -> Result < ( ) > {
231
+ let mut controller = controller. lock ( ) . unwrap ( ) ;
232
+ controller. set_permission (
233
+ DeviceType :: Character ,
234
+ major,
235
+ minor,
236
+ if r { Access :: READ } else { Access :: empty ( ) }
237
+ | if w { Access :: WRITE } else { Access :: empty ( ) }
238
+ | if m { Access :: MKNOD } else { Access :: empty ( ) } ,
239
+ ) ?;
234
240
235
- if permissions != "" {
236
- allow_device_cgroup1 ( & self . id , major, minor, permissions. as_ref ( ) ) . await ?;
237
- }
238
-
239
- Ok ( ( ) )
241
+ Ok ( ( ) )
242
+ } )
243
+ . await ?
240
244
}
241
245
242
246
pub async fn pipe_signals ( & self ) -> JoinHandle < Result < ( ) > > {
@@ -270,32 +274,6 @@ impl Container {
270
274
}
271
275
}
272
276
273
- async fn allow_device_cgroup1 (
274
- container_id : & str ,
275
- major : u32 ,
276
- minor : u32 ,
277
- permissions : & str ,
278
- ) -> Result < ( ) > {
279
- let path = format ! ( "/sys/fs/cgroup/devices/docker/{container_id}/devices.allow" ) ;
280
- let mut file = tokio:: fs:: OpenOptions :: new ( ) . write ( true ) . open ( path) . await ?;
281
- let mut data = bytes:: Bytes :: from ( format ! ( "c {major}:{minor} {permissions}" ) ) ;
282
- file. write_all_buf ( & mut data) . await ?;
283
- Ok ( ( ) )
284
- }
285
-
286
- async fn deny_device_cgroup1 (
287
- container_id : & str ,
288
- major : u32 ,
289
- minor : u32 ,
290
- permissions : & str ,
291
- ) -> Result < ( ) > {
292
- let path = format ! ( "/sys/fs/cgroup/devices/docker/{container_id}/devices.deny" ) ;
293
- let mut file = tokio:: fs:: OpenOptions :: new ( ) . write ( true ) . open ( path) . await ?;
294
- let mut data = bytes:: Bytes :: from ( format ! ( "c {major}:{minor} {permissions}" ) ) ;
295
- file. write_all_buf ( & mut data) . await ?;
296
- Ok ( ( ) )
297
- }
298
-
299
277
fn signal_stream ( kind : SignalKind ) -> impl tokio_stream:: Stream < Item = Result < SignalKind > > {
300
278
async_stream:: try_stream! {
301
279
let sig_kind = SignalKind :: hangup( ) ;
0 commit comments