mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-11-04 03:29:55 +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,23 +134,7 @@ mod tests {
 | 
				
			|||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    #[test]
 | 
					    const TEST_DATA: &str = r#"{
 | 
				
			||||||
    fn test_get_filter_attr_from_flag() {
 | 
					 | 
				
			||||||
        skip_if_not_root!();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert_eq!(
 | 
					 | 
				
			||||||
            get_filter_attr_from_flag("SECCOMP_FILTER_FLAG_TSYNC").unwrap(),
 | 
					 | 
				
			||||||
            ScmpFilterAttr::CtlTsync
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        assert_eq!(get_filter_attr_from_flag("ERROR").is_err(), true);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    #[test]
 | 
					 | 
				
			||||||
    fn test_init_seccomp() {
 | 
					 | 
				
			||||||
        skip_if_not_root!();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        let data = r#"{
 | 
					 | 
				
			||||||
          "defaultAction": "SCMP_ACT_ALLOW",
 | 
					          "defaultAction": "SCMP_ACT_ALLOW",
 | 
				
			||||||
          "architectures": [
 | 
					          "architectures": [
 | 
				
			||||||
          ],
 | 
					          ],
 | 
				
			||||||
@@ -142,7 +144,9 @@ mod tests {
 | 
				
			|||||||
          "syscalls": [
 | 
					          "syscalls": [
 | 
				
			||||||
              {
 | 
					              {
 | 
				
			||||||
                 "names": [
 | 
					                 "names": [
 | 
				
			||||||
                        "dup3"
 | 
					                      "dup3",
 | 
				
			||||||
 | 
					                      "invalid_syscall1",
 | 
				
			||||||
 | 
					                      "invalid_syscall2"
 | 
				
			||||||
                  ],
 | 
					                  ],
 | 
				
			||||||
                  "action": "SCMP_ACT_ERRNO"
 | 
					                  "action": "SCMP_ACT_ERRNO"
 | 
				
			||||||
              },
 | 
					              },
 | 
				
			||||||
@@ -196,7 +200,31 @@ mod tests {
 | 
				
			|||||||
          ]
 | 
					          ]
 | 
				
			||||||
      }"#;
 | 
					      }"#;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut scmp: oci::LinuxSeccomp = serde_json::from_str(data).unwrap();
 | 
					    #[test]
 | 
				
			||||||
 | 
					    fn test_get_filter_attr_from_flag() {
 | 
				
			||||||
 | 
					        skip_if_not_root!();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        assert_eq!(
 | 
				
			||||||
 | 
					            get_filter_attr_from_flag("SECCOMP_FILTER_FLAG_TSYNC").unwrap(),
 | 
				
			||||||
 | 
					            ScmpFilterAttr::CtlTsync
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        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]
 | 
				
			||||||
 | 
					    fn test_init_seccomp() {
 | 
				
			||||||
 | 
					        skip_if_not_root!();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut scmp: oci::LinuxSeccomp = serde_json::from_str(TEST_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