Page MenuHomeFreeBSD

hastd: Fix crash on empty message
AcceptedPublic

Authored by des on Tue, Sep 1, 1:57 PM.
Tags
None
Referenced Files
F169616095: D59306.id185561.diff
Wed, Sep 2, 2:04 AM
F169538725: D59306.id185570.diff
Tue, Sep 1, 8:54 PM
F169537271: D59306.id185571.diff
Tue, Sep 1, 8:47 PM
F169506533: D59306.id185564.diff
Tue, Sep 1, 6:13 PM
F169500160: D59306.id185571.diff
Tue, Sep 1, 5:36 PM
F169492576: D59306.diff
Tue, Sep 1, 5:02 PM
F169491486: D59306.id185571.diff
Tue, Sep 1, 4:56 PM
F169484211: D59306.id.diff
Tue, Sep 1, 4:14 PM
Subscribers

Details

Reviewers
gjb
pjd
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 76384
Build 73267: 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
154

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
154

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

sbin/hastd/hast_proto.c
154

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