Repository navigation
lib/gis: set buffer to G_format_[northing|easting|resolution] to >=320 bytes - #7943
Conversation
|
Please remove the comments, the info belongs to the commit message. |
|
How were you able to do the asan verifications before and after (if you actually did), without doing a grass build? Seems a little contradictory, unless not explained well |
|
Yes -- no full build, deliberately. Happy to do a full build and rerun if that's wanted for confidence here -- just flagging it wasn't done yet. |
|
This looks good to me, but, again please remove the comments in code. You might add a very short notice (on min buffer size) in the functions |
bb61c21 to
6b39ba5
Compare
|
Added a short note on the minimum buffer size to the |
format_double() (lib/gis/wind_format.c) formats a coordinate with sprintf(buf, "%.8f", value) for any non-lat/lon projection. %.8f on a double has no fixed maximum width -- DBL_MAX needs 318 characters -- but several callers pass a fixed local buffer sized for an ordinary coordinate: 30 bytes in r.coin, 50 in r.report, ps.map, and d.where. g.region's coordinate parser (scan_double() in wind_scan.c) is a bare sscanf with no magnitude check, so an extreme n=/s=/e=/w= value in a non-lat/lon projection is accepted, and the region's stored coordinate can be large enough to overflow these buffers when one of the four affected programs formats it. Reproduced with format_double() extracted verbatim into a standalone harness under AddressSanitizer: 9e19 (29-char result) is clean, 1e20 (30 characters, one more than a 30-byte buffer can hold with the terminator) overflows. DBL_MAX needs exactly 318 characters, measured directly. Bumped each of the four buffers to 320 bytes -- sign + DBL_MAX's 318 digits + the terminator -- rather than changing format_double()'s signature, which is called from many places across the tree with no size parameter today and felt like a separate, bigger decision. Fixes OSGeo#7942. Could not build the full tree to test end to end -- this machine is already tight on disk space, and the change is a pure buffer-size literal with no logic difference, so I didn't think it was worth the risk for the confidence gained. clang-format is clean on all four files. Signed-off-by: sai pranav <rajasaipranav0@gmail.com>
6b39ba5 to
a078add
Compare
|
Taken exactly as suggested, applied to all three functions (G_format_northing/easting/resolution). |
Fixes #7942.
format_double()(lib/gis/wind_format.c) usessprintf(buf, "%.8f", value)for any non-lat/lon projection.%.8fon adoublehas no fixed maximum width --DBL_MAXneeds 318 characters -- but the callers changed here pass a fixed local buffer sized for an ordinary coordinate: 30 bytes inr.coin, 50 inr.report,ps.map, andd.where.The value comes from the current region, settable via
g.region.scan_double()(lib/gis/wind_scan.c), which parsesg.region'sn=/s=/e=/w=for any non-lat/lon projection, is a baresscanfwith no magnitude check, so an extreme value is accepted and can reach these buffers when one of the four programs formats it.Reproduced with
format_double()extracted verbatim (matched by function name, not retyped) into a standalone harness under AddressSanitizer:9e19(29-char result) is clean,1e20(30 characters, one more than a 30-byte buffer can hold with the terminator) overflows.DBL_MAXneeds exactly 318 characters, measured directly withsprintfinto a 512-byte scratch buffer.Fix: bump each buffer to 320 bytes (sign +
DBL_MAX's 318 digits + terminator) rather than changingformat_double()'s signature -- it's called from many places across the tree with no size parameter today, and widening a public API felt like a separate decision from fixing four buffers that are simply too small for what it already does. Happy to go the other way (a boundedsnprintfinsideformat_double()itself) if you'd rather standardize there.Testing:
clang-formatis clean on all four files. I did not attempt a full build -- this machine is low on disk space, and the change is a pure buffer-size literal with no logic difference (same four lines, larger numbers), so a full multi-GB build felt like more risk to my disk than confidence gained. The actual defect (the unbounded write) is what's ASAN-verified above; each affected call site was individually located and its buffer size checked, not assumed from the one function.