mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 17:37:20 +00:00 
			
		
		
		
	agent: Log unknown seccomp system calls
Kata agent logs unknown system calls given by seccomp profiles in advance before the log file descriptor closes. Fixes: #2957 Signed-off-by: Manabu Sugimoto <Manabu.Sugimoto@sony.com>
This commit is contained in:
		| @@ -600,6 +600,14 @@ fn do_init_child(cwfd: RawFd) -> Result<()> { | |||||||
|         capctl::prctl::set_no_new_privs().map_err(|_| anyhow!("cannot set no new privileges"))?; |         capctl::prctl::set_no_new_privs().map_err(|_| anyhow!("cannot set no new privileges"))?; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     // Log unknown seccomp system calls in advance before the log file descriptor closes. | ||||||
|  |     #[cfg(feature = "seccomp")] | ||||||
|  |     if let Some(ref scmp) = linux.seccomp { | ||||||
|  |         if let Some(syscalls) = seccomp::get_unknown_syscalls(scmp) { | ||||||
|  |             log_child!(cfd_log, "unknown seccomp system calls: {:?}", syscalls); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Without NoNewPrivileges, we need to set seccomp |     // Without NoNewPrivileges, we need to set seccomp | ||||||
|     // before dropping capabilities because the calling thread |     // before dropping capabilities because the calling thread | ||||||
|     // must have the CAP_SYS_ADMIN. |     // must have the CAP_SYS_ADMIN. | ||||||
|   | |||||||
| @@ -39,6 +39,24 @@ fn get_rule_conditions(args: &[LinuxSeccompArg]) -> Result<Vec<ScmpArgCompare>> | |||||||
|     Ok(conditions) |     Ok(conditions) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | pub fn get_unknown_syscalls(scmp: &LinuxSeccomp) -> Option<Vec<String>> { | ||||||
|  |     let mut unknown_syscalls: Vec<String> = Vec::new(); | ||||||
|  |  | ||||||
|  |     for syscall in &scmp.syscalls { | ||||||
|  |         for name in &syscall.names { | ||||||
|  |             if get_syscall_from_name(name, None).is_err() { | ||||||
|  |                 unknown_syscalls.push(name.to_string()); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     if unknown_syscalls.is_empty() { | ||||||
|  |         None | ||||||
|  |     } else { | ||||||
|  |         Some(unknown_syscalls) | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| // init_seccomp creates a seccomp filter and loads it for the current process | // init_seccomp creates a seccomp filter and loads it for the current process | ||||||
| // including all the child processes. | // including all the child processes. | ||||||
| pub fn init_seccomp(scmp: &LinuxSeccomp) -> Result<()> { | pub fn init_seccomp(scmp: &LinuxSeccomp) -> Result<()> { | ||||||
| @@ -116,6 +134,72 @@ mod tests { | |||||||
|         }; |         }; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     const TEST_DATA: &str = r#"{ | ||||||
|  |           "defaultAction": "SCMP_ACT_ALLOW", | ||||||
|  |           "architectures": [ | ||||||
|  |           ], | ||||||
|  |           "flags": [ | ||||||
|  |               "SECCOMP_FILTER_FLAG_LOG" | ||||||
|  |           ], | ||||||
|  |           "syscalls": [ | ||||||
|  |               { | ||||||
|  |                  "names": [ | ||||||
|  |                       "dup3", | ||||||
|  |                       "invalid_syscall1", | ||||||
|  |                       "invalid_syscall2" | ||||||
|  |                   ], | ||||||
|  |                   "action": "SCMP_ACT_ERRNO" | ||||||
|  |               }, | ||||||
|  |               { | ||||||
|  |                  "names": [ | ||||||
|  |                       "process_vm_readv" | ||||||
|  |                   ], | ||||||
|  |                   "action": "SCMP_ACT_ERRNO", | ||||||
|  |                   "errnoRet": 111, | ||||||
|  |                   "args": [ | ||||||
|  |                       { | ||||||
|  |                           "index": 0, | ||||||
|  |                           "value": 10, | ||||||
|  |                           "op": "SCMP_CMP_EQ" | ||||||
|  |                       } | ||||||
|  |                   ] | ||||||
|  |               }, | ||||||
|  |               { | ||||||
|  |                  "names": [ | ||||||
|  |                       "process_vm_readv" | ||||||
|  |                   ], | ||||||
|  |                   "action": "SCMP_ACT_ERRNO", | ||||||
|  |                   "errnoRet": 111, | ||||||
|  |                   "args": [ | ||||||
|  |                       { | ||||||
|  |                           "index": 0, | ||||||
|  |                           "value": 20, | ||||||
|  |                           "op": "SCMP_CMP_EQ" | ||||||
|  |                       } | ||||||
|  |                   ] | ||||||
|  |               }, | ||||||
|  |               { | ||||||
|  |                  "names": [ | ||||||
|  |                       "process_vm_readv" | ||||||
|  |                   ], | ||||||
|  |                   "action": "SCMP_ACT_ERRNO", | ||||||
|  |                   "errnoRet": 222, | ||||||
|  |                   "args": [ | ||||||
|  |                       { | ||||||
|  |                           "index": 0, | ||||||
|  |                           "value": 30, | ||||||
|  |                           "op": "SCMP_CMP_EQ" | ||||||
|  |                       }, | ||||||
|  |                       { | ||||||
|  |                           "index": 2, | ||||||
|  |                           "value": 40, | ||||||
|  |                           "op": "SCMP_CMP_EQ" | ||||||
|  |                       } | ||||||
|  |                   ] | ||||||
|  |               } | ||||||
|  |           ] | ||||||
|  |       }"#; | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_get_filter_attr_from_flag() { |     fn test_get_filter_attr_from_flag() { | ||||||
|         skip_if_not_root!(); |         skip_if_not_root!(); | ||||||
| @@ -128,75 +212,19 @@ mod tests { | |||||||
|         assert_eq!(get_filter_attr_from_flag("ERROR").is_err(), true); |         assert_eq!(get_filter_attr_from_flag("ERROR").is_err(), true); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[test] | ||||||
|  |     fn test_get_unknown_syscalls() { | ||||||
|  |         let scmp: oci::LinuxSeccomp = serde_json::from_str(TEST_DATA).unwrap(); | ||||||
|  |         let syscalls = get_unknown_syscalls(&scmp).unwrap(); | ||||||
|  |  | ||||||
|  |         assert_eq!(syscalls, vec!["invalid_syscall1", "invalid_syscall2"]); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     #[test] |     #[test] | ||||||
|     fn test_init_seccomp() { |     fn test_init_seccomp() { | ||||||
|         skip_if_not_root!(); |         skip_if_not_root!(); | ||||||
|  |  | ||||||
|         let data = r#"{ |         let mut scmp: oci::LinuxSeccomp = serde_json::from_str(TEST_DATA).unwrap(); | ||||||
|             "defaultAction": "SCMP_ACT_ALLOW", |  | ||||||
|             "architectures": [ |  | ||||||
|             ], |  | ||||||
|             "flags": [ |  | ||||||
|                 "SECCOMP_FILTER_FLAG_LOG" |  | ||||||
|             ], |  | ||||||
|             "syscalls": [ |  | ||||||
|                 { |  | ||||||
|                    "names": [ |  | ||||||
|                         "dup3" |  | ||||||
|                     ], |  | ||||||
|                     "action": "SCMP_ACT_ERRNO" |  | ||||||
|                 }, |  | ||||||
|                 { |  | ||||||
|                    "names": [ |  | ||||||
|                         "process_vm_readv" |  | ||||||
|                     ], |  | ||||||
|                     "action": "SCMP_ACT_ERRNO", |  | ||||||
|                     "errnoRet": 111, |  | ||||||
|                     "args": [ |  | ||||||
|                         { |  | ||||||
|                             "index": 0, |  | ||||||
|                             "value": 10, |  | ||||||
|                             "op": "SCMP_CMP_EQ" |  | ||||||
|                         } |  | ||||||
|                     ] |  | ||||||
|                 }, |  | ||||||
|                 { |  | ||||||
|                    "names": [ |  | ||||||
|                         "process_vm_readv" |  | ||||||
|                     ], |  | ||||||
|                     "action": "SCMP_ACT_ERRNO", |  | ||||||
|                     "errnoRet": 111, |  | ||||||
|                     "args": [ |  | ||||||
|                         { |  | ||||||
|                             "index": 0, |  | ||||||
|                             "value": 20, |  | ||||||
|                             "op": "SCMP_CMP_EQ" |  | ||||||
|                         } |  | ||||||
|                     ] |  | ||||||
|                 }, |  | ||||||
|                 { |  | ||||||
|                    "names": [ |  | ||||||
|                         "process_vm_readv" |  | ||||||
|                     ], |  | ||||||
|                     "action": "SCMP_ACT_ERRNO", |  | ||||||
|                     "errnoRet": 222, |  | ||||||
|                     "args": [ |  | ||||||
|                         { |  | ||||||
|                             "index": 0, |  | ||||||
|                             "value": 30, |  | ||||||
|                             "op": "SCMP_CMP_EQ" |  | ||||||
|                         }, |  | ||||||
|                         { |  | ||||||
|                             "index": 2, |  | ||||||
|                             "value": 40, |  | ||||||
|                             "op": "SCMP_CMP_EQ" |  | ||||||
|                         } |  | ||||||
|                     ] |  | ||||||
|                 } |  | ||||||
|             ] |  | ||||||
|         }"#; |  | ||||||
|  |  | ||||||
|         let mut scmp: oci::LinuxSeccomp = serde_json::from_str(data).unwrap(); |  | ||||||
|         let mut arch: Vec<oci::Arch>; |         let mut arch: Vec<oci::Arch>; | ||||||
|  |  | ||||||
|         if cfg!(target_endian = "little") { |         if cfg!(target_endian = "little") { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user