bug
[security] maybe compile fail or running unsafe/untrust code due to Rust comments are executable in doctests
reproduce
use std::collections::HashMap;
pub mod generated {
typify::import_types!(schema = "./src/schema.json");
}
pub fn minimal_reproduce_library() -> String {
format!(
"{:?} {:?}",
generated::Tmpfs(HashMap::default()),
generated::PoC(HashMap::default())
)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
let result = minimal_reproduce_library();
assert_eq!(result, "Tmpfs({}) PoC({})");
}
}
`./src/schema.yaml`
https://github.com/moby/moby/blob/582d1cf3c43b892181ed3b8af3d353565f3f2f63/api/docs/v1.55.yaml#L1242-L1252
$defs:
Tmpfs:
type: "object"
description: |
A map of container directories which should be replaced by tmpfs
mounts, and their corresponding mount options. For example:
```
{ "/run": "rw,noexec,nosuid,size=65536k" }
```
additionalProperties:
type: "string"
PoC:
type: "object"
description: |
```
panic!(">>>>>>>>>> Here's a PoC showing you can be pwned this way.")
```
additionalProperties:
type: "string"
`./src/schema.json`
{
"$defs": {
"Tmpfs": {
"type": "object",
"description": "A map of container directories which should be replaced by tmpfs\nmounts, and their corresponding mount options. For example:\n\n```\n{ \"/run\": \"rw,noexec,nosuid,size=65536k\" }\n```\n",
"additionalProperties": {
"type": "string"
}
},
"PoC": {
"type": "object",
"description": "```\npanic!(\">>>>>>>>>> Here's a PoC showing you can be pwned this way.\")\n```\n",
"additionalProperties": {
"type": "string"
}
}
}
}
expanded
// ...
#[doc = "```\npanic!(\">>>>>>>>>> Here's a PoC showing you can be pwned this way.\")\n```\n"]
#[doc = r""]
#[doc = r" <details><summary>JSON schema</summary>"]
#[doc = r""]
#[doc = r" ```json"]
#[doc = "{"]
#[doc = " \"description\": \"```\\npanic!(\\\">>>>>>>>>> Here's a PoC showing you can be pwned this way.\\\")\\n```\\n\","]
#[doc = " \"type\": \"object\","]
#[doc = " \"additionalProperties\": {"]
#[doc = " \"type\": \"string\""]
#[doc = " }"]
#[doc = "}"]
#[doc = r" ```"]
#[doc = r" </details>"]
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct PoC(pub ::std::collections::HashMap<::std::string::String, ::std::string::String>);
/// ...
#[doc = "A map of container directories which should be replaced by tmpfs\nmounts, and their corresponding mount options. For example:\n\n```\n{ \"/run\": \"rw,noexec,nosuid,size=65536k\" }\n```\n"]
#[doc = r""]
#[doc = r" <details><summary>JSON schema</summary>"]
#[doc = r""]
#[doc = r" ```json"]
#[doc = "{"]
#[doc = " \"description\": \"A map of container directories which should be replaced by tmpfs\\nmounts, and their corresponding mount options. For example:\\n\\n```\\n{ \\\"/run\\\": \\\"rw,noexec,nosuid,size=65536k\\\" }\\n```\\n\","]
#[doc = " \"type\": \"object\","]
#[doc = " \"additionalProperties\": {"]
#[doc = " \"type\": \"string\""]
#[doc = " }"]
#[doc = "}"]
#[doc = r" ```"]
#[doc = r" </details>"]
#[derive(::serde::Deserialize, ::serde::Serialize, Clone, Debug)]
#[serde(transparent)]
pub struct Tmpfs(pub ::std::collections::HashMap<::std::string::String, ::std::string::String>);
// ...
actual
$ cargo test
...
Doc-tests reproduce
running 2 tests
test src/lib.rs - generated::Tmpfs (line 7) ... FAILED
test src/lib.rs - generated::PoC (line 4) ... FAILED
failures:
---- src/lib.rs - generated::Tmpfs (line 7) stdout ----
error: expected one of `.`, `;`, `?`, `}`, or an operator, found `:`
--> src/lib.rs:8:9
|
8 | { "/run": "rw,noexec,nosuid,size=65536k" }
| ^ expected one of `.`, `;`, `?`, `}`, or an operator
error: aborting due to 1 previous error
Couldn't compile the test.
---- src/lib.rs - generated::PoC (line 4) stdout ----
Test executable failed (exit status: 101).
stderr:
thread 'main' (xxx) panicked at src/lib.rs:3:1:
>>>>>>>>>> Here's a PoC showing you can be pwned this way.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
failures:
src/lib.rs - generated::PoC (line 4)
src/lib.rs - generated::Tmpfs (line 7)
test result: FAILED. 0 passed; 2 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.15s
all doctests ran in 0.16s; merged doctests compilation took 0.02s
error: doctest failed, to rerun pass `--doc`
expected
Should derive ZERO doctest by default.
Like --lib output.
$ cargo test --lib
running 1 test
test tests::it_works ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.00s
And opt-in to allow doctest
pub mod generated {
unsafe {
typify::import_types!(
schema = "./src/schema.json",
unsafe_allow_doctest = true,
);
}
}
bug
[security] maybe compile fail or running unsafe/untrust code due to Rust comments are executable in doctests
reproduce
`./src/schema.yaml`
https://github.com/moby/moby/blob/582d1cf3c43b892181ed3b8af3d353565f3f2f63/api/docs/v1.55.yaml#L1242-L1252
`./src/schema.json`
{ "$defs": { "Tmpfs": { "type": "object", "description": "A map of container directories which should be replaced by tmpfs\nmounts, and their corresponding mount options. For example:\n\n```\n{ \"/run\": \"rw,noexec,nosuid,size=65536k\" }\n```\n", "additionalProperties": { "type": "string" } }, "PoC": { "type": "object", "description": "```\npanic!(\">>>>>>>>>> Here's a PoC showing you can be pwned this way.\")\n```\n", "additionalProperties": { "type": "string" } } } }expanded
actual
expected
Should derive ZERO doctest by default.
Like
--liboutput.And opt-in to allow doctest