Bug #707
closedInner structures in lttcomm_session_msg's union should be packed
100%
Description
The lttcomm_session_msg is sent over a unix socket to send messages to the session daemon using the lttng-ctl API.
The LTTNG_PACKED macro is used to ensure the structures in "u" are packed. However this attribute does not apply to inner structures, which must be annotated explicitly; LTTNG_PACKED is not recursive.
#define LTTNG_PACKED __attribute__((__packed__))
For reference, the lttcomm_session_msg structure follows. Note how the snapshot_output member in the "u" union contains a struct lttng_snapshot_output which is not packed. There are multiple instances of this in the structure and the same problem may affect the other IPC structures.
struct lttcomm_session_msg { uint32_t cmd_type; /* enum lttcomm_sessiond_command */ struct lttng_session session; struct lttng_domain domain; union { struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; char name[NAME_MAX]; } LTTNG_PACKED disable; /* Event data */ struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; struct lttng_event event; /* Length of following bytecode for filter. */ uint32_t bytecode_len; /* exclusion data */ uint32_t exclusion_count; /* * After this structure, the following variable-length * items are transmitted: * - char exclusion_names[LTTNG_SYMBOL_NAME_LEN][exclusion_count] * - unsigned char filter_bytecode[bytecode_len] */ } LTTNG_PACKED enable; /* Create channel */ struct { struct lttng_channel chan; } LTTNG_PACKED channel; /* Context */ struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; struct lttng_event_context ctx; } LTTNG_PACKED context; /* Use by register_consumer */ struct { char path[PATH_MAX]; } LTTNG_PACKED reg; /* List */ struct { char channel_name[LTTNG_SYMBOL_NAME_LEN]; } LTTNG_PACKED list; struct lttng_calibrate calibrate; /* Used by the set_consumer_url and used by create_session also call */ struct { /* Number of lttng_uri following */ uint32_t size; } LTTNG_PACKED uri; struct { struct lttng_snapshot_output output; } LTTNG_PACKED snapshot_output; struct { uint32_t wait; struct lttng_snapshot_output output; } LTTNG_PACKED snapshot_record; struct { uint32_t nb_uri; unsigned int timer_interval; /* usec */ } LTTNG_PACKED session_live; struct { struct lttng_save_session_attr; } LTTNG_PACKED save_session; } u; } LTTNG_PACKED;
Nice write-up that explains the problem in more details:
http://axelio.wordpress.com/2007/07/24/be-careful-with-packed-structures/
Hopefully I missed something and this is a false alarm...