Page MenuHomeFreeBSD

hastd: Fix crash on empty message
ClosedPublic

Authored by des on Tue, Sep 1, 1:57 PM.
Tags
None
Referenced Files
F170816184: D59306.id185686.diff
Sun, Sep 6, 7:46 PM
F170773160: D59306.id185570.diff
Sun, Sep 6, 1:33 PM
F170744068: D59306.id185570.diff
Sun, Sep 6, 9:10 AM
F170737189: D59306.diff
Sun, Sep 6, 8:01 AM
F170696306: D59306.id185561.diff
Sun, Sep 6, 2:01 AM
Unknown Object (File)
Sat, Sep 5, 11:42 PM
Unknown Object (File)
Sat, Sep 5, 6:59 PM
Unknown Object (File)
Sat, Sep 5, 4:02 PM
Subscribers

Details

Summary

A HAST message can be empty, in which case ebuf_data() will return NULL,
but in the receive path, we assert that the return value is not NULL.
Thus sending a message to hastd with an empty payload results in an
immediate crash. This is trivially reproducable by running `hastctl
status` or hastctl role init (which the rc script happens to do prior
to stopping hastd).

PR: 298085
MFC after: 3 days

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Skipped
Unit
Tests Skipped
Build Status
Buildable 76377
Build 73260: arc lint + arc unit

Event Timeline

des requested review of this revision.Tue, Sep 1, 1:57 PM

I'm not convinced this patch is correct. I think we should call proto_recv() in all cases.

In D59306#1360617, @des wrote:

I'm not convinced this patch is correct. I think we should call proto_recv() in all cases.

OK, I misunderstood the code; I thought proto_recv() called the handler for the message, but what it actually does is read the payload from the socket, so we only need to call it if there is a payload to be read, and the patch is fine.

don't call ebuf_add_tail() needlessly

sbin/hastd/hast_proto.c
156

actually this is completely redundant because we already gave hdr.size to ebuf_alloc() so it already allocated enough memory for it (and a whole additional page, for some reason).

sbin/hastd/hast_proto.c
156

hmm that turned out not to be correct in practice, probably a bug in the ebuf code

sbin/hastd/hast_proto.c
156

It's actually not a bug; ebuf_alloc(hdr.size) creates an ebuf with no data but with the expectation that at least hdr.size bytes will be written to it in the future, while ebuf_add_tail(eb, NULL, hdr.size) adds hdr.size bytes of uninitialized data to the ebuf (without allocating any additional memory); ebuf_data() will return NULL until the first call to either ebuf_add_head() or ebuf_add_tail().

This revision resolves the issue for me.

This revision is now accepted and ready to land.Tue, Sep 1, 5:13 PM
This revision was automatically updated to reflect the committed changes.