summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2023-12-04 11:22:38 +0100
committerThomas Haller <thaller@redhat.com>2023-12-04 11:28:09 +0100
commit4fcb075720ed3beea4ceee3f679305caacd0f51b (patch)
tree693f6779e1d201901b62e135292a93950041ad63
parentf743c62fa69edf3acc26ee30ffbee8a3c6841ed3 (diff)
downloadlibnl-4fcb075720ed3beea4ceee3f679305caacd0f51b.tar.gz
socket: workaround coverity warning about time_t handling
Coverity really wants to warn if a time_t is cast to 32 bits. We use time() here to get (some very bad) randomness. The loss of the upper bits is the least of the problems. Work around the coverity warning by also the higher bits. Error: Y2K38_SAFETY (CWE-197): [#def12] libnl-3.8.0/lib/socket.c:76: store_truncates_time_t: A "time_t" value is stored in an integer with too few bits to accommodate it. The expression "time(NULL)" is cast to "uint32_t". # 74| # 75| if (idx_state == 0) { # 76|-> uint32_t t = (uint32_t) time(NULL); # 77| # 78| /* from time to time (on average each 2^15 calls), the idx_state will Error: Y2K38_SAFETY (CWE-197): [#def13] libnl-3.8.0/lib/socket.c:193: store_truncates_time_t: A "time_t" value is stored in an integer with too few bits to accommodate it. The expression "time(NULL)" is cast to "unsigned int". # 191| sk->s_local.nl_family = AF_NETLINK; # 192| sk->s_peer.nl_family = AF_NETLINK; # 193|-> sk->s_seq_next = (unsigned int) time(NULL); # 194| sk->s_seq_expect = sk->s_seq_next; # 195|
-rw-r--r--lib/socket.c22
1 files changed, 20 insertions, 2 deletions
diff --git a/lib/socket.c b/lib/socket.c
index 5f28ea83..9b42f679 100644
--- a/lib/socket.c
+++ b/lib/socket.c
@@ -60,6 +60,24 @@ static void _nl_init init_default_cb(void)
}
}
+static uint32_t _badrandom_from_time(void)
+{
+ uint32_t result;
+ uint64_t v64;
+ time_t t;
+
+ t = time(NULL);
+ v64 = (uint64_t)t;
+ result = (uint32_t)v64;
+
+ /* XOR with the upper bits. Otherwise, coverity warns about only
+ * considering 32 bit from time_t. Use the inverse, so that for the
+ * most part the bits don't change. */
+ result ^= (~(v64 >> 32));
+
+ return result;
+}
+
static uint32_t used_ports_map[32];
static NL_RW_LOCK(port_map_lock);
@@ -73,7 +91,7 @@ static uint32_t generate_local_port(void)
nl_write_lock(&port_map_lock);
if (idx_state == 0) {
- uint32_t t = (uint32_t) time(NULL);
+ uint32_t t = _badrandom_from_time();
/* from time to time (on average each 2^15 calls), the idx_state will
* be zero again. No problem, just "seed" anew with time(). */
@@ -190,7 +208,7 @@ static struct nl_sock *__alloc_socket(struct nl_cb *cb)
sk->s_cb = nl_cb_get(cb);
sk->s_local.nl_family = AF_NETLINK;
sk->s_peer.nl_family = AF_NETLINK;
- sk->s_seq_next = (unsigned int) time(NULL);
+ sk->s_seq_next = _badrandom_from_time();
sk->s_seq_expect = sk->s_seq_next;
/* the port is 0 (unspecified), meaning NL_OWN_PORT */