mirror of
				https://github.com/kata-containers/kata-containers.git
				synced 2025-10-31 09:26:52 +00:00 
			
		
		
		
	agent: Validate CID
Validate the container ID as we cannot / should not rely on the container manager / runtime to do this. Fixes: #1520. Signed-off-by: James O. D. Hunt <james.o.hunt@intel.com>
This commit is contained in:
		| @@ -80,6 +80,23 @@ pub struct AgentService { | |||||||
|     sandbox: Arc<Mutex<Sandbox>>, |     sandbox: Arc<Mutex<Sandbox>>, | ||||||
| } | } | ||||||
|  |  | ||||||
|  | // A container ID must match this regex: | ||||||
|  | // | ||||||
|  | //     ^[a-zA-Z0-9][a-zA-Z0-9_.-]+$ | ||||||
|  | // | ||||||
|  | fn verify_cid(id: &str) -> Result<()> { | ||||||
|  |     let valid = id.len() > 1 | ||||||
|  |         && id.chars().next().unwrap().is_alphanumeric() | ||||||
|  |         && id | ||||||
|  |             .chars() | ||||||
|  |             .all(|c| (c.is_alphanumeric() || ['.', '-', '_'].contains(&c))); | ||||||
|  |  | ||||||
|  |     match valid { | ||||||
|  |         true => Ok(()), | ||||||
|  |         false => Err(anyhow!("invalid container ID: {:?}", id)), | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
| impl AgentService { | impl AgentService { | ||||||
|     async fn do_create_container( |     async fn do_create_container( | ||||||
|         &self, |         &self, | ||||||
| @@ -87,6 +104,8 @@ impl AgentService { | |||||||
|     ) -> Result<()> { |     ) -> Result<()> { | ||||||
|         let cid = req.container_id.clone(); |         let cid = req.container_id.clone(); | ||||||
|  |  | ||||||
|  |         let _ = verify_cid(&cid)?; | ||||||
|  |  | ||||||
|         let mut oci_spec = req.OCI.clone(); |         let mut oci_spec = req.OCI.clone(); | ||||||
|         let use_sandbox_pidns = req.get_sandbox_pidns(); |         let use_sandbox_pidns = req.get_sandbox_pidns(); | ||||||
|  |  | ||||||
| @@ -1773,4 +1792,231 @@ mod tests { | |||||||
|  |  | ||||||
|         assert!(result.is_err(), "expected add arp neighbors to fail"); |         assert!(result.is_err(), "expected add arp neighbors to fail"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     #[tokio::test] | ||||||
|  |     async fn test_verify_cid() { | ||||||
|  |         #[derive(Debug)] | ||||||
|  |         struct TestData<'a> { | ||||||
|  |             id: &'a str, | ||||||
|  |             expect_error: bool, | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         let tests = &[ | ||||||
|  |             TestData { | ||||||
|  |                 // Cannot be blank | ||||||
|  |                 id: "", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Cannot be a space | ||||||
|  |                 id: " ", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: ".", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "-", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "_", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: " a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: ".a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "-a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "_a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "..", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "z", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "A", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "Z", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "0", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Too short | ||||||
|  |                 id: "9", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 // Must start with an alphanumeric | ||||||
|  |                 id: "-1", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "/", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "a/", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "a/../", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "../a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "../../a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "../../../a", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "foo/../bar", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "foo bar", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "a.", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "a..", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "aa", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "aa.", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "hello..world", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "hello/../world", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "aa1245124sadfasdfgasdga.", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "aAzZ0123456789_.-", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "abcdefghijklmnopqrstuvwxyz0123456789.-_", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "0123456789abcdefghijklmnopqrstuvwxyz.-_", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: " abcdefghijklmnopqrstuvwxyz0123456789.-_", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: ".abcdefghijklmnopqrstuvwxyz0123456789.-_", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ.-_", | ||||||
|  |                 expect_error: false, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: " ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: ".ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.-_", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "/a/b/c", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "a/b/c", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "foo/../../../etc/passwd", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "../../../../../../etc/motd", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |             TestData { | ||||||
|  |                 id: "/etc/passwd", | ||||||
|  |                 expect_error: true, | ||||||
|  |             }, | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         for (i, d) in tests.iter().enumerate() { | ||||||
|  |             let msg = format!("test[{}]: {:?}", i, d); | ||||||
|  |  | ||||||
|  |             let result = verify_cid(d.id); | ||||||
|  |  | ||||||
|  |             let msg = format!("{}, result: {:?}", msg, result); | ||||||
|  |  | ||||||
|  |             if result.is_ok() { | ||||||
|  |                 assert!(!d.expect_error, msg); | ||||||
|  |             } else { | ||||||
|  |                 assert!(d.expect_error, msg); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user