@@ -6,6 +6,8 @@ use log4rs::append::file::FileAppender;
66use log4rs:: config:: { runtime:: ConfigErrors , Appender , Config , Root } ;
77use uuid:: Uuid ;
88
9+ use lockc_uprobes:: { add_container, add_process, delete_container} ;
10+
911// TODO: To be used for cri-o.
1012// static ANNOTATION_K8S_LABELS: &str = "io.kubernetes.cri-o.Labels";
1113
@@ -140,13 +142,13 @@ struct Mount {
140142 destination : String ,
141143 r#type : String ,
142144 source : String ,
143- options : Vec < String >
145+ options : Vec < String > ,
144146}
145147
146148#[ derive( Debug , Deserialize ) ]
147149#[ serde( rename_all = "camelCase" ) ]
148150struct Mounts {
149- mounts : Vec < Mount >
151+ mounts : Vec < Mount > ,
150152}
151153
152154fn docker_config < P : AsRef < std:: path:: Path > > (
@@ -161,9 +163,9 @@ fn docker_config<P: AsRef<std::path::Path>>(
161163
162164 for test in m. mounts {
163165 let source: Vec < & str > = test. source . split ( '/' ) . collect ( ) ;
164- if source. len ( ) > 1 && source[ source. len ( ) - 1 ] == "hostname" {
165- let config_v2= str:: replace ( & test. source , "hostname" , "config.v2.json" ) ;
166- return Ok ( std:: path:: PathBuf :: from ( config_v2) ) ;
166+ if source. len ( ) > 1 && source[ source. len ( ) - 1 ] == "hostname" {
167+ let config_v2 = str:: replace ( & test. source , "hostname" , "config.v2.json" ) ;
168+ return Ok ( std:: path:: PathBuf :: from ( config_v2) ) ;
167169 }
168170 }
169171
@@ -185,15 +187,11 @@ fn docker_label<P: AsRef<std::path::Path>>(
185187
186188 match x {
187189 Some ( x) => match x {
188- "restricted" => {
189- Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_RESTRICTED)
190- }
190+ "restricted" => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_RESTRICTED) ,
191191 "baseline" => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_BASELINE) ,
192- "privileged" => {
193- Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_PRIVILEGED)
194- }
195- _ => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_BASELINE)
196- }
192+ "privileged" => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_PRIVILEGED) ,
193+ _ => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_BASELINE) ,
194+ } ,
197195 None => Ok ( lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_BASELINE) ,
198196 }
199197}
@@ -265,12 +263,33 @@ fn setup_logging() -> Result<(), SetupLoggingError> {
265263 Ok ( ( ) )
266264}
267265
266+ #[ derive( thiserror:: Error , Debug ) ]
267+ enum UprobeError {
268+ #[ error( "failed to call into uprobe, BPF programs are most likely not running" ) ]
269+ Call ,
270+
271+ #[ error( "BPF program error" ) ]
272+ BPF ,
273+
274+ #[ error( "unknown error" ) ]
275+ Unknown ,
276+ }
277+
278+ fn check_uprobe_ret ( ret : i32 ) -> Result < ( ) , UprobeError > {
279+ match ret {
280+ 0 => Ok ( ( ) ) ,
281+ n if n == -libc:: EAGAIN => Err ( UprobeError :: Call ) ,
282+ n if n == -libc:: EINVAL => Err ( UprobeError :: BPF ) ,
283+ _ => Err ( UprobeError :: Unknown ) ,
284+ }
285+ }
286+
268287#[ tokio:: main]
269288async fn main ( ) -> anyhow:: Result < ( ) > {
270289 setup_logging ( ) ?;
271290
272291 let pid = nix:: unistd:: getpid ( ) ;
273- let pid_u = u32 :: try_from ( libc:: pid_t:: from ( pid) ) ? ;
292+ let pid_u = libc:: pid_t:: from ( pid) ;
274293
275294 let mut opt_parsing_action = OptParsingAction :: NoPositional ;
276295 let mut arg_parsing_action = ArgParsingAction :: None ;
@@ -356,22 +375,53 @@ async fn main() -> anyhow::Result<()> {
356375 match container_id_o {
357376 Some ( v) => {
358377 let container_key = lockc:: hash ( & v) ?;
359- lockc:: add_process ( container_key, pid_u) ?;
360- cmd. status ( ) . await ?;
361- lockc:: delete_process ( pid_u) ?;
378+
379+ let mut ret: i32 = -libc:: EAGAIN ;
380+ add_process ( & mut ret as * mut i32 , container_key, pid_u) ;
381+ check_uprobe_ret ( ret) ?;
382+
383+ let output = cmd. output ( ) . await ;
384+ match output {
385+ Ok ( output) => {
386+ info ! ( "status: {}" , output. status) ;
387+ info ! (
388+ "stdout: {}" ,
389+ std:: string:: String :: from_utf8_lossy( & output. stdout)
390+ ) ;
391+ info ! (
392+ "stderr: {}" ,
393+ std:: string:: String :: from_utf8_lossy( & output. stderr)
394+ ) ;
395+ }
396+ Err ( e) => info ! ( "error: {}" , e) ,
397+ }
362398 }
363399 None => {
364400 // The purpose of this fake "container" is only to allow the runc
365401 // subcommand to be detected as wrapped and thus allowed by
366402 // the LSM program to execute. It's only to handle subcommands
367403 // like `init`, `list` or `spec`, so we make it restricted.
368- lockc:: add_container (
369- 0 ,
370- pid_u,
371- lockc:: bpfstructs:: container_policy_level_POLICY_LEVEL_RESTRICTED,
372- ) ?;
373- cmd. status ( ) . await ?;
374- lockc:: delete_container ( 0 ) ?;
404+ // lockc::add_container(
405+ // 0,
406+ // pid_u,
407+ // lockc::bpfstructs::container_policy_level_POLICY_LEVEL_RESTRICTED,
408+ // )?;
409+ let output = cmd. output ( ) . await ;
410+ match output {
411+ Ok ( output) => {
412+ info ! ( "status: {}" , output. status) ;
413+ info ! (
414+ "stdout: {}" ,
415+ std:: string:: String :: from_utf8_lossy( & output. stdout)
416+ ) ;
417+ info ! (
418+ "stderr: {}" ,
419+ std:: string:: String :: from_utf8_lossy( & output. stderr)
420+ ) ;
421+ }
422+ Err ( e) => info ! ( "error: {}" , e) ,
423+ }
424+ // lockc::delete_container(0)?;
375425 }
376426 }
377427 }
@@ -392,16 +442,68 @@ async fn main() -> anyhow::Result<()> {
392442 policy = docker_label ( docker_conf) ?;
393443 }
394444 } ;
395- lockc:: add_container ( container_key, pid_u, policy) ?;
396- cmd. status ( ) . await ?;
445+
446+ let mut ret: i32 = -libc:: EAGAIN ;
447+ add_container ( & mut ret as * mut i32 , container_key, pid_u, policy) ;
448+ check_uprobe_ret ( ret) ?;
449+
450+ info ! ( "executing create" ) ;
451+ let output = cmd. output ( ) . await ;
452+ info ! ( "executed create" ) ;
453+ match output {
454+ Ok ( output) => {
455+ info ! ( "status: {}" , output. status) ;
456+ info ! (
457+ "stdout: {}" ,
458+ std:: string:: String :: from_utf8_lossy( & output. stdout)
459+ ) ;
460+ info ! (
461+ "stderr: {}" ,
462+ std:: string:: String :: from_utf8_lossy( & output. stderr)
463+ ) ;
464+ }
465+ Err ( e) => info ! ( "error: {}" , e) ,
466+ }
397467 }
398468 ContainerAction :: Delete => {
399469 let container_key = lockc:: hash ( & container_id_o. unwrap ( ) ) ?;
400- lockc:: delete_container ( container_key) ?;
401- cmd. status ( ) . await ?;
470+
471+ let output = cmd. output ( ) . await ;
472+ match output {
473+ Ok ( output) => {
474+ info ! ( "status: {}" , output. status) ;
475+ info ! (
476+ "stdout: {}" ,
477+ std:: string:: String :: from_utf8_lossy( & output. stdout)
478+ ) ;
479+ info ! (
480+ "stderr: {}" ,
481+ std:: string:: String :: from_utf8_lossy( & output. stderr)
482+ ) ;
483+ }
484+ Err ( e) => info ! ( "error: {}" , e) ,
485+ }
486+
487+ let mut ret: i32 = -libc:: EAGAIN ;
488+ delete_container ( & mut ret as * mut i32 , container_key) ;
489+ check_uprobe_ret ( ret) ?;
402490 }
403491 ContainerAction :: Start => {
404- cmd. status ( ) . await ?;
492+ let output = cmd. output ( ) . await ;
493+ match output {
494+ Ok ( output) => {
495+ info ! ( "status: {}" , output. status) ;
496+ info ! (
497+ "stdout: {}" ,
498+ std:: string:: String :: from_utf8_lossy( & output. stdout)
499+ ) ;
500+ info ! (
501+ "stderr: {}" ,
502+ std:: string:: String :: from_utf8_lossy( & output. stderr)
503+ ) ;
504+ }
505+ Err ( e) => info ! ( "error: {}" , e) ,
506+ }
405507 }
406508 }
407509
0 commit comments