Skip to content

Conversation

@jamtho
Copy link
Contributor

@jamtho jamtho commented Dec 9, 2017

This is an attempt to improve memory safety in message parsing, by checking whether callers to AisBitset::ToUnsignedInt() etc are reading too far, and returning an error that's easily attached to the Ais object for callers to see. If asserts are enabled, however, it dies on one in the usual way.

This suggestion is particularly prompted by the recent issues raised by fuzzing, so I've converted Ais20 and Ais26 to use the new system, addressing #174 and #171. If asserts are enabled it continues to die essentially as documented in the issue, or if not then the relevant Ais objects are successfully constructed with status set to AIS_ERR_BAD_BIT_COUNT.

I haven't tested to see whether this affects performance yet - I'm happy to have a look if there's a standard project method based on public data. If there's significant degradation then I think it's possible to do something very similar statically, using the same number of branches as currently exist. That would be an ugly mess of templates, however.

Provides safe a batch-fetch interface for AisBitset bit sub-sequences,
erroring on out-of-bounds requests at runtime or dying on an assert if
they're enabled.

The interface is supposed to match libais's current control flow
approach, avoiding requiring major code surgery to integrate. It's
currently a bit too wordy, though, and could be improved.

This is designed to tackle a semi-regular class of bugs in libais,
where a decoder-set message length precondition is narrower than the
AisBitset calls made further down the function. Since asserts are the
only error handling in this situation we currently get UB in release
builds.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant