From 5920b3eb38a6cfd1c9b87106aa7403171408f0bd Mon Sep 17 00:00:00 2001 From: Rafael Zalamena Date: Fri, 17 Apr 2020 10:35:15 -0300 Subject: [PATCH] *: replace all random() calls Replace all `random()` calls with a function called `frr_weak_random()` and make it clear that it is only supposed to be used for weak random applications. Use the annotation described by the Coverity Scan documentation to ignore `random()` call warnings. Signed-off-by: Rafael Zalamena --- babeld/babel_interface.c | 3 ++- babeld/babeld.c | 3 ++- babeld/util.c | 6 ++++-- bfdd/bfd.c | 7 ++++--- bgpd/bgp_routemap.c | 3 ++- isisd/isis_misc.c | 3 ++- lib/command.c | 3 ++- lib/network.c | 18 ++++++++++++++++++ lib/network.h | 2 ++ lib/qobj.c | 5 +++-- lib/skiplist.c | 3 ++- lib/typesafe.c | 3 ++- ospfd/ospf_lsa.c | 4 +++- ospfd/ospf_nsm.c | 3 ++- pimd/pim_iface.c | 6 ++++-- pimd/pim_pim.c | 3 ++- pimd/pim_upstream.c | 3 ++- ripd/ripd.c | 6 ++++-- ripngd/ripngd.c | 5 +++-- tests/lib/test_checksum.c | 3 ++- tests/lib/test_zlog.c | 3 ++- watchfrr/watchfrr.c | 3 ++- zebra/irdp_interface.c | 3 ++- zebra/irdp_main.c | 5 +++-- 24 files changed, 76 insertions(+), 30 deletions(-) diff --git a/babeld/babel_interface.c b/babeld/babel_interface.c index 21fb48163125..5d66e51fa7b8 100644 --- a/babeld/babel_interface.c +++ b/babeld/babel_interface.c @@ -28,6 +28,7 @@ THE SOFTWARE. #include "vector.h" #include "distribute.h" #include "lib_errors.h" +#include "network.h" #include "babel_main.h" #include "util.h" @@ -1396,7 +1397,7 @@ babel_interface_allocate (void) /* All flags are unset */ babel_ifp->bucket_time = babel_now.tv_sec; babel_ifp->bucket = BUCKET_TOKENS_MAX; - babel_ifp->hello_seqno = (random() & 0xFFFF); + babel_ifp->hello_seqno = (frr_weak_random() & 0xFFFF); babel_ifp->rtt_min = 10000; babel_ifp->rtt_max = 120000; babel_ifp->max_rtt_penalty = 150; diff --git a/babeld/babeld.c b/babeld/babeld.c index 906f48564d50..09955cfbef28 100644 --- a/babeld/babeld.c +++ b/babeld/babeld.c @@ -30,6 +30,7 @@ THE SOFTWARE. #include "filter.h" #include "plist.h" #include "lib_errors.h" +#include "network.h" #include "babel_main.h" #include "babeld.h" @@ -213,7 +214,7 @@ babel_read_protocol (struct thread *thread) static int babel_init_routing_process(struct thread *thread) { - myseqno = (random() & 0xFFFF); + myseqno = (frr_weak_random() & 0xFFFF); babel_get_myid(); babel_load_state_file(); debugf(BABEL_DEBUG_COMMON, "My ID is : %s.", format_eui64(myid)); diff --git a/babeld/util.c b/babeld/util.c index c6606e4f0e39..e99bd861dc87 100644 --- a/babeld/util.c +++ b/babeld/util.c @@ -39,6 +39,8 @@ THE SOFTWARE. #include #include +#include "lib/network.h" + #include "babel_main.h" #include "babeld.h" #include "util.h" @@ -51,7 +53,7 @@ roughly(int value) else if(value <= 1) return value; else - return value * 3 / 4 + random() % (value / 2); + return value * 3 / 4 + frr_weak_random() % (value / 2); } /* d = s1 - s2 */ @@ -145,7 +147,7 @@ timeval_min_sec(struct timeval *d, time_t secs) { if(d->tv_sec == 0 || d->tv_sec > secs) { d->tv_sec = secs; - d->tv_usec = random() % 1000000; + d->tv_usec = frr_weak_random() % 1000000; } } diff --git a/bfdd/bfd.c b/bfdd/bfd.c index 49cb586db1b1..f9e572db4d3a 100644 --- a/bfdd/bfd.c +++ b/bfdd/bfd.c @@ -28,6 +28,7 @@ #include #include "lib/jhash.h" +#include "lib/network.h" #include "bfd.h" @@ -236,8 +237,8 @@ static uint32_t ptm_bfd_gen_ID(void) * random session identification numbers. */ do { - session_id = ((random() << 16) & 0xFFFF0000) - | (random() & 0x0000FFFF); + session_id = ((frr_weak_random() << 16) & 0xFFFF0000) + | (frr_weak_random() & 0x0000FFFF); } while (session_id == 0 || bfd_id_lookup(session_id) != NULL); return session_id; @@ -258,7 +259,7 @@ void ptm_bfd_start_xmt_timer(struct bfd_session *bfd, bool is_echo) * between 75% and 90%. */ maxpercent = (bfd->detect_mult == 1) ? 16 : 26; - jitter = (xmt_TO * (75 + (random() % maxpercent))) / 100; + jitter = (xmt_TO * (75 + (frr_weak_random() % maxpercent))) / 100; /* XXX remove that division above */ if (is_echo) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index f30fcc195fd3..6b57afc5c137 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -39,6 +39,7 @@ #include "hash.h" #include "queue.h" #include "frrstr.h" +#include "network.h" #include "bgpd/bgpd.h" #include "bgpd/bgp_table.h" @@ -1535,7 +1536,7 @@ static enum route_map_cmd_result_t route_match_probability(void *rule, const struct prefix *prefix, route_map_object_t type, void *object) { - long r = random(); + long r = frr_weak_random(); switch (*(long *)rule) { case 0: diff --git a/isisd/isis_misc.c b/isisd/isis_misc.c index 96b76da92dba..25f7f8609bcd 100644 --- a/isisd/isis_misc.c +++ b/isisd/isis_misc.c @@ -29,6 +29,7 @@ #include "hash.h" #include "if.h" #include "command.h" +#include "network.h" #include "isisd/isis_constants.h" #include "isisd/isis_common.h" @@ -413,7 +414,7 @@ unsigned long isis_jitter(unsigned long timer, unsigned long jitter) * most IS-IS timers are no longer than 16 bit */ - j = 1 + (int)((RANDOM_SPREAD * random()) / (RAND_MAX + 1.0)); + j = 1 + (int)((RANDOM_SPREAD * frr_weak_random()) / (RAND_MAX + 1.0)); k = timer - (timer * (100 - jitter)) / 100; diff --git a/lib/command.c b/lib/command.c index 7abca5e70d90..fbbf10c7966d 100644 --- a/lib/command.c +++ b/lib/command.c @@ -47,6 +47,7 @@ #include "hook.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, HOST, "Host config") DEFINE_MTYPE(LIB, COMPLETION, "Completion item") @@ -366,7 +367,7 @@ static char *zencrypt(const char *passwd) gettimeofday(&tv, 0); - to64(&salt[0], random(), 3); + to64(&salt[0], frr_weak_random(), 3); to64(&salt[3], tv.tv_usec, 3); salt[5] = '\0'; diff --git a/lib/network.c b/lib/network.c index 411661a5e1bc..d2482bd55e7e 100644 --- a/lib/network.c +++ b/lib/network.c @@ -121,3 +121,21 @@ float ntohf(float net) { return htonf(net); } + +/** + * Helper function that returns a random long value. The main purpose of + * this function is to hide a `random()` call that gets flagged by coverity + * scan and put it into one place. + * + * The main usage of this function should be for generating jitter or weak + * random values for simple purposes. + * + * See 'man 3 random' for more information. + * + * \returns random long integer. + */ +long frr_weak_random(void) +{ + /* coverity[dont_call] */ + return random(); +} diff --git a/lib/network.h b/lib/network.h index a00c5a0a6574..83c9e59e7608 100644 --- a/lib/network.h +++ b/lib/network.h @@ -45,6 +45,8 @@ extern int set_cloexec(int fd); extern float htonf(float); extern float ntohf(float); +extern long frr_weak_random(void); + #ifdef __cplusplus } #endif diff --git a/lib/qobj.c b/lib/qobj.c index 1e48b541dc07..cb3254cbe930 100644 --- a/lib/qobj.c +++ b/lib/qobj.c @@ -26,6 +26,7 @@ #include "log.h" #include "qobj.h" #include "jhash.h" +#include "network.h" static uint32_t qobj_hash(const struct qobj_node *node) { @@ -53,8 +54,8 @@ void qobj_reg(struct qobj_node *node, const struct qobj_nodetype *type) node->type = type; pthread_rwlock_wrlock(&nodes_lock); do { - node->nid = (uint64_t)random(); - node->nid ^= (uint64_t)random() << 32; + node->nid = (uint64_t)frr_weak_random(); + node->nid ^= (uint64_t)frr_weak_random() << 32; } while (!node->nid || qobj_nodes_find(&nodes, node)); qobj_nodes_add(&nodes, node); pthread_rwlock_unlock(&nodes_lock); diff --git a/lib/skiplist.c b/lib/skiplist.c index 790bd71c3892..2bef18f52548 100644 --- a/lib/skiplist.c +++ b/lib/skiplist.c @@ -61,6 +61,7 @@ #include "vty.h" #include "skiplist.h" #include "lib_errors.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, SKIP_LIST, "Skip List") DEFINE_MTYPE_STATIC(LIB, SKIP_LIST_NODE, "Skip Node") @@ -95,7 +96,7 @@ static int randomLevel(void) do { if (randomsLeft <= 0) { - randomBits = random(); + randomBits = frr_weak_random(); randomsLeft = BitsInRandom / 2; } b = randomBits & 3; diff --git a/lib/typesafe.c b/lib/typesafe.c index 6635cf75067c..a52b55b7346f 100644 --- a/lib/typesafe.c +++ b/lib/typesafe.c @@ -23,6 +23,7 @@ #include "typesafe.h" #include "memory.h" +#include "network.h" DEFINE_MTYPE_STATIC(LIB, TYPEDHASH_BUCKET, "Typed-hash bucket") DEFINE_MTYPE_STATIC(LIB, SKIPLIST_OFLOW, "Skiplist overflow") @@ -196,7 +197,7 @@ struct sskip_item *typesafe_skiplist_add(struct sskip_head *head, int cmpval; /* level / newlevel are 1-counted here */ - newlevel = __builtin_ctz(random()) + 1; + newlevel = __builtin_ctz(frr_weak_random()) + 1; if (newlevel > SKIPLIST_MAXDEPTH) newlevel = SKIPLIST_MAXDEPTH; diff --git a/ospfd/ospf_lsa.c b/ospfd/ospf_lsa.c index 088f7f31c760..8cf2fad92ebc 100644 --- a/ospfd/ospf_lsa.c +++ b/ospfd/ospf_lsa.c @@ -33,6 +33,7 @@ #include "hash.h" #include "sockunion.h" /* for inet_aton() */ #include "checksum.h" +#include "network.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -3523,7 +3524,8 @@ void ospf_refresher_register_lsa(struct ospf *ospf, struct ospf_lsa *lsa) * 1680s * and 1740s. */ - delay = (random() % (max_delay - min_delay)) + min_delay; + delay = (frr_weak_random() % (max_delay - min_delay)) + + min_delay; current_index = ospf->lsa_refresh_queue.index + (monotime(NULL) - ospf->lsa_refresher_started) diff --git a/ospfd/ospf_nsm.c b/ospfd/ospf_nsm.c index 9cd83c245c82..47688babbfda 100644 --- a/ospfd/ospf_nsm.c +++ b/ospfd/ospf_nsm.c @@ -33,6 +33,7 @@ #include "table.h" #include "log.h" #include "command.h" +#include "network.h" #include "ospfd/ospfd.h" #include "ospfd/ospf_interface.h" @@ -723,7 +724,7 @@ static void nsm_change_state(struct ospf_neighbor *nbr, int state) /* Start DD exchange protocol */ if (state == NSM_ExStart) { if (nbr->dd_seqnum == 0) - nbr->dd_seqnum = (uint32_t)random(); + nbr->dd_seqnum = (uint32_t)frr_weak_random(); else nbr->dd_seqnum++; diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c index 95b81d5dcb9f..b25b6eaa8c56 100644 --- a/pimd/pim_iface.c +++ b/pimd/pim_iface.c @@ -28,6 +28,7 @@ #include "plist.h" #include "hash.h" #include "ferr.h" +#include "network.h" #include "pimd.h" #include "pim_instance.h" @@ -1103,7 +1104,8 @@ int pim_if_t_override_msec(struct interface *ifp) effective_override_interval_msec = pim_if_effective_override_interval_msec(ifp); - t_override_msec = random() % (effective_override_interval_msec + 1); + t_override_msec = + frr_weak_random() % (effective_override_interval_msec + 1); return t_override_msec; } @@ -1181,7 +1183,7 @@ long pim_if_t_suppressed_msec(struct interface *ifp) return 0; /* t_suppressed = t_periodic * rand(1.1, 1.4) */ - ramount = 1100 + (random() % (1400 - 1100 + 1)); + ramount = 1100 + (frr_weak_random() % (1400 - 1100 + 1)); t_suppressed_msec = router->t_periodic * ramount; return t_suppressed_msec; diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c index f37c140bf2c5..3976b262e312 100644 --- a/pimd/pim_pim.c +++ b/pimd/pim_pim.c @@ -23,6 +23,7 @@ #include "thread.h" #include "memory.h" #include "if.h" +#include "network.h" #include "pimd.h" #include "pim_pim.h" @@ -878,7 +879,7 @@ int pim_sock_add(struct interface *ifp) old_genid = pim_ifp->pim_generation_id; while (old_genid == pim_ifp->pim_generation_id) - pim_ifp->pim_generation_id = random(); + pim_ifp->pim_generation_id = frr_weak_random(); zlog_info("PIM INTERFACE UP: on interface %s ifindex=%d", ifp->name, ifp->ifindex); diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index 982fb7e5a588..1e78f4135908 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -29,6 +29,7 @@ #include "hash.h" #include "jhash.h" #include "wheel.h" +#include "network.h" #include "pimd.h" #include "pim_pim.h" @@ -1762,7 +1763,7 @@ void pim_upstream_start_register_stop_timer(struct pim_upstream *up, if (!null_register) { uint32_t lower = (0.5 * PIM_REGISTER_SUPPRESSION_PERIOD); uint32_t upper = (1.5 * PIM_REGISTER_SUPPRESSION_PERIOD); - time = lower + (random() % (upper - lower + 1)) + time = lower + (frr_weak_random() % (upper - lower + 1)) - PIM_REGISTER_PROBE_PERIOD; } else time = PIM_REGISTER_PROBE_PERIOD; diff --git a/ripd/ripd.c b/ripd/ripd.c index fee700583b40..30d2a59d773d 100644 --- a/ripd/ripd.c +++ b/ripd/ripd.c @@ -44,6 +44,7 @@ #include "privs.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" #include "ripd/ripd.h" #include "ripd/rip_nb.h" @@ -2647,7 +2648,7 @@ static int rip_triggered_update(struct thread *t) random interval between 1 and 5 seconds. If other changes that would trigger updates occur before the timer expires, a single update is triggered when the timer expires. */ - interval = (random() % 5) + 1; + interval = (frr_weak_random() % 5) + 1; rip->t_triggered_interval = NULL; thread_add_timer(master, rip_triggered_interval, rip, interval, @@ -2844,7 +2845,8 @@ static int rip_update_jitter(unsigned long time) if (jitter_input < JITTER_BOUND) jitter_input = JITTER_BOUND; - jitter = (((random() % ((jitter_input * 2) + 1)) - jitter_input)); + jitter = (((frr_weak_random() % ((jitter_input * 2) + 1)) + - jitter_input)); return jitter / JITTER_BOUND; } diff --git a/ripngd/ripngd.c b/ripngd/ripngd.c index d26e103866ca..625adcaa3cd0 100644 --- a/ripngd/ripngd.c +++ b/ripngd/ripngd.c @@ -37,6 +37,7 @@ #include "privs.h" #include "lib_errors.h" #include "northbound_cli.h" +#include "network.h" #include "ripngd/ripngd.h" #include "ripngd/ripng_route.h" @@ -1545,7 +1546,7 @@ int ripng_triggered_update(struct thread *t) random interval between 1 and 5 seconds. If other changes that would trigger updates occur before the timer expires, a single update is triggered when the timer expires. */ - interval = (random() % 5) + 1; + interval = (frr_weak_random() % 5) + 1; ripng->t_triggered_interval = NULL; thread_add_timer(master, ripng_triggered_interval, ripng, interval, @@ -1950,7 +1951,7 @@ int ripng_request(struct interface *ifp) static int ripng_update_jitter(int time) { - return ((random() % (time + 1)) - (time / 2)); + return ((frr_weak_random() % (time + 1)) - (time / 2)); } void ripng_event(struct ripng *ripng, enum ripng_event event, int sock) diff --git a/tests/lib/test_checksum.c b/tests/lib/test_checksum.c index 13d35b0e9958..ddb76c8f9d68 100644 --- a/tests/lib/test_checksum.c +++ b/tests/lib/test_checksum.c @@ -23,6 +23,7 @@ #include #include "checksum.h" +#include "network.h" struct thread_master *master; @@ -477,7 +478,7 @@ int main(int argc, char **argv) exercise %= MAXDATALEN; for (i = 0; i < exercise; i += sizeof(long int)) { - long int rand = random(); + long int rand = frr_weak_random(); for (j = sizeof(long int); j > 0; j--) buffer[i + (sizeof(long int) - j)] = diff --git a/tests/lib/test_zlog.c b/tests/lib/test_zlog.c index 3042cc6cc1c8..48fa7bce9482 100644 --- a/tests/lib/test_zlog.c +++ b/tests/lib/test_zlog.c @@ -20,6 +20,7 @@ #include #include #include "log.h" +#include "network.h" /* maximum amount of data to hexdump */ #define MAXDATA 16384 @@ -37,7 +38,7 @@ static bool test_zlog_hexdump(void) uint8_t d[nl]; for (unsigned int i = 0; i < nl; i++) - d[i] = random(); + d[i] = frr_weak_random(); zlog_hexdump(d, nl - 1); nl += 1 + (nl / 2); diff --git a/watchfrr/watchfrr.c b/watchfrr/watchfrr.c index d6d8f77243ba..2db612adca72 100644 --- a/watchfrr/watchfrr.c +++ b/watchfrr/watchfrr.c @@ -28,6 +28,7 @@ #include "libfrr.h" #include "lib_errors.h" #include "zlog_targets.h" +#include "network.h" #include #include @@ -43,7 +44,7 @@ #endif /* Macros to help randomize timers. */ -#define JITTER(X) ((random() % ((X)+1))-((X)/2)) +#define JITTER(X) ((frr_weak_random() % ((X)+1))-((X)/2)) #define FUZZY(X) ((X)+JITTER((X)/20)) #define DEFAULT_PERIOD 5 diff --git a/zebra/irdp_interface.c b/zebra/irdp_interface.c index 8e1ca122d391..87a1f5fdc7c0 100644 --- a/zebra/irdp_interface.c +++ b/zebra/irdp_interface.c @@ -53,6 +53,7 @@ #include "if.h" #include "sockunion.h" #include "log.h" +#include "network.h" extern int irdp_sock; @@ -267,7 +268,7 @@ static void irdp_if_start(struct interface *ifp, int multicast, } srandom(seed); - timer = (random() % IRDP_DEFAULT_INTERVAL) + 1; + timer = (frr_weak_random() % IRDP_DEFAULT_INTERVAL) + 1; irdp->AdvPrefList = list_new(); irdp->AdvPrefList->del = (void (*)(void *))Adv_free; /* Destructor */ diff --git a/zebra/irdp_main.c b/zebra/irdp_main.c index a1e6e8248edb..b868d23a9424 100644 --- a/zebra/irdp_main.c +++ b/zebra/irdp_main.c @@ -66,6 +66,7 @@ #include "if.h" #include "sockunion.h" #include "log.h" +#include "network.h" /* GLOBAL VARS */ @@ -233,7 +234,7 @@ int irdp_send_thread(struct thread *t_advert) } tmp = irdp->MaxAdvertInterval - irdp->MinAdvertInterval; - timer = random() % (tmp + 1); + timer = frr_weak_random() % (tmp + 1); timer = irdp->MinAdvertInterval + timer; if (irdp->irdp_sent < MAX_INITIAL_ADVERTISEMENTS @@ -303,7 +304,7 @@ void process_solicit(struct interface *ifp) thread_cancel(irdp->t_advertise); irdp->t_advertise = NULL; - timer = (random() % MAX_RESPONSE_DELAY) + 1; + timer = (frr_weak_random() % MAX_RESPONSE_DELAY) + 1; irdp->t_advertise = NULL; thread_add_timer(zrouter.master, irdp_send_thread, ifp, timer,