Since I don't think your name is Steve, you're going to touch that, please get rid of the PORT_MAX_LEN/calloc/snprintf dance and just use asprintf() instead so I don't need more therapy reading it.. (look at my eye twitching...)
On Sun, Dec 6, 2015 at 2:01 PM, Theo Buehler <t...@math.ethz.ch> wrote: > On Sun, Dec 06, 2015 at 07:37:27PM +0100, Theo Buehler wrote: >> The current implementation of the selection of a random sequence of >> ports in nc -r suffers from modulo bias and a biased shuffling >> procedure. Use arc4random_uniform() and the Fisher-Yates shuffle >> instead. > > daniel@ pointed out that it might be nicer to combine initialization > and shuffling, as in ip_id.c, so here's a second version of the patch. > The patch is bigger, but the resulting code looks tighter. > > Index: usr.bin/nc/netcat.c > =================================================================== > RCS file: /cvs/src/usr.bin/nc/netcat.c,v > retrieving revision 1.144 > diff -u -p -r1.144 netcat.c > --- usr.bin/nc/netcat.c 23 Nov 2015 01:23:56 -0000 1.144 > +++ usr.bin/nc/netcat.c 6 Dec 2015 20:53:20 -0000 > @@ -1289,6 +1289,23 @@ build_ports(char *p) > lo = cp; > } > > + if (rflag) { > + /* > + * Initialize portlist[] with a random permutation. > + * Based on Knuth, as in ip_randomid() in ip_id.c. > + */ > + for (x = 0; x <= hi - lo; x++) { > + cp = arc4random_uniform(x + 1); > + portlist[x] = portlist[cp]; > + portlist[cp] = calloc(1, PORT_MAX_LEN); > + if (portlist[cp] == NULL) > + err(1, NULL); > + snprintf(portlist[cp], PORT_MAX_LEN, "%d", > + x + lo); > + } > + return; > + } > + > /* Load ports sequentially. */ > for (cp = lo; cp <= hi; cp++) { > portlist[x] = calloc(1, PORT_MAX_LEN); > @@ -1296,19 +1313,6 @@ build_ports(char *p) > err(1, NULL); > snprintf(portlist[x], PORT_MAX_LEN, "%d", cp); > x++; > - } > - > - /* Randomly swap ports. */ > - 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; > - } > } > } else { > hi = strtonum(p, 1, PORT_MAX, &errstr); >