CTF writer: stream: handle automatic fields more securely
authorPhilippe Proulx <eeppeliteloop@gmail.com>
Fri, 19 May 2017 23:56:09 +0000 (19:56 -0400)
committerJérémie Galarneau <jeremie.galarneau@efficios.com>
Sun, 28 May 2017 16:57:44 +0000 (12:57 -0400)
commitb3376dd98f1daa25bf03af261f4560a3789fb367
tree275604649bd1eece9a3db8161b8ee72d7cd0fdd2
parente011d2c1930972adc9b85f2c4067c62c207fc4ff
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>
include/babeltrace/ctf-ir/stream-internal.h
include/babeltrace/ctf-writer/serialize-internal.h
include/babeltrace/ctf-writer/stream.h
lib/ctf-ir/fields.c
lib/ctf-ir/stream.c
lib/ctf-writer/serialize.c
This page took 0.035003 seconds and 4 git commands to generate.