diff options
author | John Thacker <johnthacker@gmail.com> | 2022-07-30 08:49:08 -0400 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2022-07-30 08:49:08 -0400 |
commit | 5aba5772e9cb535e770f1774ab5819926dcd4d2b (patch) | |
tree | e947ee5212d02be381a04106e817e6e97e6058f7 | |
parent | 735ae0041745bc069239ecfc9ea1e3c59d1a4cf2 (diff) |
gboolean bitfields considered harmful
ISO C Std § 6.7.2, 5: "for bit-fields, it is implementation-defined
whether the specifier int designates the same type as signed int or the
same type as unsigned int." (See also the note in § 6.7.2.1 and ISO C
Std Appendix J.3.9.)
A gboolean is a typedef'd gint. Therefore, many implementations,
including gcc and clang, treat a gboolean bitfield of width 1 as
signed, meaning that it has two possible values: 0 and -1, any time
the integer promotions occur (which is all the time.) Constructs like this:
dgram_info->from_server = TRUE;
if (dgram_info->from_server == TRUE) ws_warning("True");
will not work as expected, though gcc (but not clang) will give an
error:
/home/johnthacker/wireshark/epan/dissectors/packet-quic.c:3457:37: error: comparison is always false due to limited range of data type [-Werror=type-limits]
3457 | if (dgram_info->from_server == TRUE)
|
proto_tree_add_debug_text(quic_tree, "Connection: %d %p from_server:%d", pinfo->num, dgram_info->conn, dgram_info->from_server);
Connection: 1 0x7fc4b47f2be0 from_server:0
Connection: 2 0x7fc4b47f2be0 from_server:-1
Connection: 3 0x7fc4b47f2be0 from_server:0
Connection: 4 0x7fc4b47f2be0 from_server:-1
At worst this can cause buffer overruns.
If a bitfield is desired, to guarantee expected behavior the standard
_Bool/bool should be used instead.
-rw-r--r-- | epan/dissectors/packet-quic.c | 22 | ||||
-rw-r--r-- | epan/dissectors/packet-wireguard.c | 5 | ||||
-rw-r--r-- | ui/tap-sctp-analysis.h | 13 |
3 files changed, 22 insertions, 18 deletions
diff --git a/epan/dissectors/packet-quic.c b/epan/dissectors/packet-quic.c index 526a91240e..96e00cb2cd 100644 --- a/epan/dissectors/packet-quic.c +++ b/epan/dissectors/packet-quic.c @@ -48,6 +48,8 @@ #include <config.h> +#include <stdbool.h> + #include <epan/packet.h> #include <epan/expert.h> #include <epan/proto_data.h> @@ -346,7 +348,7 @@ typedef struct quic_pp_state { quic_pp_cipher pp_ciphers[2]; /**< PP cipher for Key Phase 0/1 */ quic_hp_cipher hp_cipher; /**< HP cipher for both Key Phases; it does not change after KeyUpdate */ guint64 changed_in_pkn; /**< Packet number where key change occurred. */ - gboolean key_phase : 1; /**< Current key phase. */ + bool key_phase : 1; /**< Current key phase. */ } quic_pp_state_t; /** Singly-linked list of Connection IDs. */ @@ -402,12 +404,12 @@ typedef struct quic_info_data { guint32 version; address server_address; guint16 server_port; - gboolean skip_decryption : 1; /**< Set to 1 if no keys are available. */ - gboolean client_dcid_set : 1; /**< Set to 1 if client_dcid_initial is set. */ - gboolean client_loss_bits_recv : 1; /**< The client is able to read loss bits info */ - gboolean client_loss_bits_send : 1; /**< The client wants to send loss bits info */ - gboolean server_loss_bits_recv : 1; /**< The server is able to read loss bits info */ - gboolean server_loss_bits_send : 1; /**< The server wants to send loss bits info */ + bool skip_decryption : 1; /**< Set to 1 if no keys are available. */ + bool client_dcid_set : 1; /**< Set to 1 if client_dcid_initial is set. */ + bool client_loss_bits_recv : 1; /**< The client is able to read loss bits info */ + bool client_loss_bits_send : 1; /**< The client wants to send loss bits info */ + bool server_loss_bits_recv : 1; /**< The server is able to read loss bits info */ + bool server_loss_bits_send : 1; /**< The server wants to send loss bits info */ int hash_algo; /**< Libgcrypt hash algorithm for key derivation. */ int cipher_algo; /**< Cipher algorithm for packet number and packet encryption. */ int cipher_mode; /**< Cipher mode for packet encryption. */ @@ -448,8 +450,8 @@ struct quic_packet_info { guint8 pkn_len; /**< Length of PKN (1/2/3/4) or unknown (0). */ guint8 first_byte; /**< Decrypted flag byte, valid only if pkn_len is non-zero. */ guint8 packet_type; - gboolean retry_integrity_failure : 1; - gboolean retry_integrity_success : 1; + bool retry_integrity_failure : 1; + bool retry_integrity_success : 1; }; typedef struct quic_packet_info quic_packet_info_t; @@ -457,7 +459,7 @@ typedef struct quic_packet_info quic_packet_info_t; typedef struct quic_datagram { quic_info_data_t *conn; quic_packet_info_t first_packet; - gboolean from_server : 1; + bool from_server : 1; } quic_datagram; /** diff --git a/epan/dissectors/packet-wireguard.c b/epan/dissectors/packet-wireguard.c index 32188ae2e9..5b8499130b 100644 --- a/epan/dissectors/packet-wireguard.c +++ b/epan/dissectors/packet-wireguard.c @@ -16,6 +16,7 @@ #include <config.h> #include <errno.h> +#include <stdbool.h> #define WS_LOG_DOMAIN "packet-wireguard" @@ -210,8 +211,8 @@ typedef struct { const wg_skey_t *initiator_skey; /* Spub_i based on Initiation.static (decrypted, null if decryption failed) */ const wg_skey_t *responder_skey; /* Spub_r based on Initiation.MAC1 (+Spriv_r if available) */ guint8 timestamp[12]; /* Initiation.timestamp (decrypted) */ - gboolean timestamp_ok : 1; /* Whether the timestamp was successfully decrypted */ - gboolean empty_ok : 1; /* Whether the empty field was successfully decrypted */ + bool timestamp_ok : 1; /* Whether the timestamp was successfully decrypted */ + bool empty_ok : 1; /* Whether the empty field was successfully decrypted */ /* The following fields are only valid on the initial pass. */ const wg_ekey_t *initiator_ekey; /* Epub_i matching Initiation.Ephemeral (+Epriv_i if available) */ diff --git a/ui/tap-sctp-analysis.h b/ui/tap-sctp-analysis.h index eb5ecf101e..0f7f1ebc4e 100644 --- a/ui/tap-sctp-analysis.h +++ b/ui/tap-sctp-analysis.h @@ -12,6 +12,7 @@ #ifndef __TAP_SCTP_ANALYSIS_H__ #define __TAP_SCTP_ANALYSIS_H__ +#include <stdbool.h> #include <epan/dissectors/packet-sctp.h> #include <epan/address.h> #ifdef _WIN32 @@ -165,8 +166,8 @@ typedef struct _sctp_init_collision { guint32 initack_vtag; /* initiate tag of the INIT-ACK chunk */ guint32 init_min_tsn; /* initial tsn of the INIT chunk */ guint32 initack_min_tsn; /* initial tsn of the INIT-ACK chunk */ - gboolean init:1; - gboolean initack:1; + bool init:1; + bool initack:1; } sctp_init_collision_t; struct tsn_sort{ @@ -232,10 +233,10 @@ typedef struct _sctp_assoc_info { guint32 max_window2; guint32 arwnd1; guint32 arwnd2; - gboolean init:1; - gboolean initack:1; - gboolean firstdata:1; - gboolean init_collision:1; + bool init:1; + bool initack:1; + bool firstdata:1; + bool init_collision:1; guint16 initack_dir; guint16 direction; guint32 min_secs; |