CTF writer: stream: handle automatic fields more securely
The stream.c code for automatically writing the values of selected
fields in the packet context, packet header, and event header fields is
not super secure, in that the user could make the stream object write an
invalid CTF data stream file.
The code is updated to follow those rules:
* Packet header field:
* `magic` field: always force to 0xc1fc1fc1. Override any current
value.
* `uuid` field: always force to trace's UUID. Override any current
value.
* `stream_id`: always force to stream's class's ID. Override any
current value.
* Packet context field:
* `packet_size`: always force to the size of the packet being flushed.
Override any current value.
* `packet_size`: always force to the current packet's offset. Override
any current value.
* `timestamp_begin`: if the field's type is mapped to the stream's
class's clock class, force to the timestamp of the stream's first
recorded event (if any, and if this timestamp is itself mapped to
the same clock class), overriding the user's value.
* `timestamp_end`: if the field's type is mapped to the stream's
class's clock class, force to the timestamp of the stream's last
recorded event (if any, and if this timestamp is itself mapped to
the same clock class), overriding the user's value.
* `events_discarded`: always force to the stream's current discarded
events count (now a dedicated member of the stream object to keep
this value safe). Override any current value.
* Event header field:
* `timestamp`: if the field's type is an integer field type which is
mapped to the stream's class's clock class, force to the current
value of the stream's class's clock, overriding the user's value.
* `id`: if the field's type is an integer field type, force to the
event's class's ID, overriding the user's value.
* If the stream's packet context does not exist or does not contain
a `packet_size` field, the user can only flush the stream one time.
* If the stream's packet context does not exist or does not contain a
`content_size` field, the content size (current offset) of the packet
to flush must be equal to its packet size.
Those rules are more strict than before, but they ensure that the
written stream is valid. Writing an invalid CTF stream, or CTF trace at
all, is not a CTF writer use case. This is in line with the project's
first precept: don't trust the user.
I added assertions which check that the packet size is always a multiple
of 8: this is suggested by CTF 1, and required by (eventual) CTF 2. This
is always the case here because the packet's initial size is 8 pages and
then it's incremented by this value each time. If it is a requirement
that the user should be able to control the packet size, then we should
add a function to set the expected packet size before flushing the
stream, not rely on the `packet_size` field's value.
There are still a few cases which remain to be checked. For example, if
the stream class's event header field type's `id` field does not exist,
and there's more than one event class in the stream's class, we write
the event anyway without any warning: this is because LTTng is known to
have a complex system of `id` and `timestamp` fields with extended
structures depending on the ID value, and the ctf.fs sink component
class uses CTF writer as is. That said, in the most common scenarios,
`id` is an integer field type.
Signed-off-by: Philippe Proulx <eeppeliteloop@gmail.com>
Signed-off-by: Jérémie Galarneau <jeremie.galarneau@efficios.com>
This page took 0.037502 seconds and 4 git commands to generate.