summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <tb@cvs.openbsd.org>2015-12-07 02:38:55 +0000
committertb <tb@cvs.openbsd.org>2015-12-07 02:38:55 +0000
commita89dfcc63c1861093d1deb834aabd4dc4cb5df3a (patch)
tree9faa04913ae380bc91659a90314fbcf07b16b328
parent10621099f65cef40eada031871a9fb8877af1332 (diff)
Get rid of modulo bias and replace the naive shuffle by the
Knuth-Fisher-Yates shuffle to make the random sequence of ports less biased. Based on the implementation in sys/netinet/ip_id.c. With helpful input from daniel@ and beck@ ok beck@ despite eye twitching
-rw-r--r--usr.bin/nc/netcat.c36
1 files changed, 16 insertions, 20 deletions
diff --git a/usr.bin/nc/netcat.c b/usr.bin/nc/netcat.c
index 4c3ed4e97f0..cfc5a2363b8 100644
--- a/usr.bin/nc/netcat.c
+++ b/usr.bin/nc/netcat.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: netcat.c,v 1.144 2015/11/23 01:23:56 bcook Exp $ */
+/* $OpenBSD: netcat.c,v 1.145 2015/12/07 02:38:54 tb Exp $ */
/*
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
* Copyright (c) 2015 Bob Beck. All rights reserved.
@@ -58,7 +58,6 @@
#include "atomicio.h"
#define PORT_MAX 65535
-#define PORT_MAX_LEN 6
#define UNIX_DG_TMP_SOCKET_SIZE 19
#define POLL_STDIN 0
@@ -1289,25 +1288,22 @@ build_ports(char *p)
lo = cp;
}
- /* Load ports sequentially. */
- for (cp = lo; cp <= hi; cp++) {
- portlist[x] = calloc(1, PORT_MAX_LEN);
- if (portlist[x] == NULL)
- err(1, NULL);
- snprintf(portlist[x], PORT_MAX_LEN, "%d", cp);
- x++;
- }
-
- /* Randomly swap ports. */
+ /*
+ * Initialize portlist with a random permutation. Based on
+ * Knuth, as in ip_randomid() in sys/netinet/ip_id.c.
+ */
if (rflag) {
- int y;
- char *c;
-
- for (x = 0; x <= (hi - lo); x++) {
- y = (arc4random() & 0xFFFF) % (hi - lo);
- c = portlist[x];
- portlist[x] = portlist[y];
- portlist[y] = c;
+ for (x = 0; x <= hi - lo; x++) {
+ cp = arc4random_uniform(x + 1);
+ portlist[x] = portlist[cp];
+ if (asprintf(&portlist[cp], "%d", x + lo) < 0)
+ err(1, "asprintf");
+ }
+ } else { /* Load ports sequentially. */
+ for (cp = lo; cp <= hi; cp++) {
+ if (asprintf(&portlist[x], "%d", cp) < 0)
+ err(1, "asprintf");
+ x++;
}
}
} else {