When a fuzz-crafted RRD file contains an RRA with pdp_cnt == 0 or
pdp_step == 0, rrd_dump_cb_r performed a modulo operation whose
divisor could be zero, triggering a SIGFPE. Add a guard at the top
of the per-RRA loop that rejects such files with rrd_set_error()
and a clean return rather than crashing.
Reported by @rwhitworth.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
text documentation works on systems with BSD-derived nroff (e.g.
macOS /usr/bin/nroff). Issue #1323 reported by @gigaimage, fixed by
@oetiker
+* Fix SIGFPE divide-by-zero crash in `rrdtool dump` when processing
+ fuzz-crafted RRD files that contain an RRA with `pdp_cnt` or
+ `pdp_step` equal to zero. The modulo operation at the heart of the
+ timestamp calculation is now guarded: such files are rejected with
+ a descriptive error message instead of crashing.
+ Issue #783 reported by @rwhitworth, fix by @oetiker.
Features
--------
rra_next += (rrd.stat_head->ds_cnt
* rrd.rra_def[i].row_cnt * sizeof(rrd_value_t));
+ if (rrd.rra_def[i].pdp_cnt == 0 || rrd.stat_head->pdp_step == 0) {
+ rrd_set_error("invalid RRA %u: pdp_cnt or pdp_step is zero", i);
+ rrd_free(&rrd);
+ rrd_close(rrd_file);
+ return (-1);
+ }
+
CB_PUTS("\t<rra>\n");
CB_FMTS("\t\t<cf>%s</cf>\n", rrd.rra_def[i].cf_nam);
CB_FMTS("\t\t<pdp_per_row>%lu</pdp_per_row> <!-- %lu seconds -->\n\n",
- rrd.rra_def[i].pdp_cnt,
+ rrd.rra_def[i].pdp_cnt,
rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step);
/* support for RRA parameters */