3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-06-21 13:23:40 +00:00

Merge pull request #5165 from georgerennie/george/opt_dff_uaf

opt_dff: don't remove cells until all have been visited to prevent UAF
This commit is contained in:
George Rennie 2025-06-20 23:33:26 +01:00 committed by GitHub
commit 170933ecb0
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 71 additions and 3 deletions

View file

@ -738,7 +738,11 @@ struct OptDffWorker
ModWalker modwalker(module->design, module); ModWalker modwalker(module->design, module);
QuickConeSat qcsat(modwalker); QuickConeSat qcsat(modwalker);
// Run as a separate sub-pass, so that we don't mutate (non-FF) cells under ModWalker. // Defer mutating cells by removing them/emiting new flip flops so that
// cell references in modwalker are not invalidated
std::vector<RTLIL::Cell*> cells_to_remove;
std::vector<FfData> ffs_to_emit;
bool did_something = false; bool did_something = false;
for (auto cell : module->selected_cells()) { for (auto cell : module->selected_cells()) {
if (!RTLIL::builtin_ff_cell_types().count(cell->type)) if (!RTLIL::builtin_ff_cell_types().count(cell->type))
@ -830,16 +834,20 @@ struct OptDffWorker
if (!removed_sigbits.count(i)) if (!removed_sigbits.count(i))
keep_bits.push_back(i); keep_bits.push_back(i);
if (keep_bits.empty()) { if (keep_bits.empty()) {
module->remove(cell); cells_to_remove.emplace_back(cell);
did_something = true; did_something = true;
continue; continue;
} }
ff = ff.slice(keep_bits); ff = ff.slice(keep_bits);
ff.cell = cell; ff.cell = cell;
ff.emit(); ffs_to_emit.emplace_back(ff);
did_something = true; did_something = true;
} }
} }
for (auto* cell : cells_to_remove)
module->remove(cell);
for (auto& ff : ffs_to_emit)
ff.emit();
return did_something; return did_something;
} }
}; };

60
tests/opt/bug5164.ys Normal file
View file

@ -0,0 +1,60 @@
read_rtlil <<EOT
module \module137
wire input 1 \clk
wire width 1 output 1 \qa
wire width 1 \qb
cell $dff \dffa
parameter \CLK_POLARITY 1
parameter \WIDTH 1
connect \CLK \clk
connect \D \qb
connect \Q \qa
end
cell $dff \dffb
parameter \CLK_POLARITY 1
parameter \WIDTH 1
connect \CLK \clk
connect \D 1'x
connect \Q \qb
end
end
EOT
equiv_opt -assert opt_dff -sat
design -reset
read_rtlil <<EOT
module \module137
wire output 1 width 9 $2\reg204[8:0]
wire input 1 \clk
wire width 9 $auto$wreduce.cc:514:run$19340
wire width 9 $auto$wreduce.cc:514:run$19341
wire width 15 \dffout
attribute \init 9'000000000
wire width 9 \reg204
cell $dff $auto$ff.cc:266:slice$26225
parameter \CLK_POLARITY 1
parameter \WIDTH 15
connect \CLK \clk
connect \D { 9'x \reg204 [8:3] }
connect \Q \dffout
end
cell $dff $auto$ff.cc:266:slice$26292
parameter \CLK_POLARITY 1
parameter \WIDTH 9
connect \CLK \clk
connect \D $2\reg204[8:0]
connect \Q \reg204
end
cell $mux $procmux$4510
parameter \WIDTH 9
connect \A 9'x
connect \B 9'x
connect \S 1'x
connect \Y $auto$wreduce.cc:514:run$19340
end
connect $2\reg204[8:0] $auto$wreduce.cc:514:run$19340
connect $auto$wreduce.cc:514:run$19341 [8:3] 6'000000
end
EOT
equiv_opt -assert opt_dff -sat