Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful

2013-01-10 Thread Michael Vogt
On Thu, Jan 10, 2013 at 02:44:42AM -0500, sacrificial-spam-addr...@horizon.com 
wrote:
  Thanks, I fixed this now in my bzr tree and it will be part of the
  next upload.
 
 Er, assuming that's revision 2269:
 http://anonscm.debian.org/loggerhead/apt/debian-sid/revision/2269/debian/apt.cron.daily

Great, thanks for double checking.
 
 You don't need the final cut -c1-5.  It is true that cksum returns an
 unsigned 32-bit number, and some shells only do 32-bit signed math, but
 they simply convert the number to negative.
 
 You either mask off the sign bit with
 RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2 /dev/null | cksum | cut -d' ' 
 -f1) % 0x7fff))
 
 Or, of you want to emulate the range of Bash $RANDOM exactly:
 RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2 /dev/null | cksum | cut -d' ' 
 -f1) % 0x7fff))

Thanks, indeed, simulating this more closely is probably a good idea,
I added that in my bzr branch now.

 The od -d -N2 -An solution works with a recent enough od.
 I was looking to see how old that can be.  The uppercase option flags
 are not in 7th edition, but are in POSIX.1 as of 2001:
[..]

Thanks for checking this. I like this, its more compact than the
current code. However the reason why I did not use this, was that the
following fragment:

$ while true; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2); echo
$res; if [ -z $res ]; then break;  fi ; done
61581
42056
38021

$ 

give me a empty string in $res sometimes. I haven't really put any
though into why this is, maybe just a side effect of running it in th
while loop?

Cheers,
 Michael


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful

2013-01-10 Thread sacrificial-spam-address
 Thanks for checking this. I like this, its more compact than the
 current code. However the reason why I did not use this, was that the
 following fragment:
 
 $ while true; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2); echo
 $res; if [ -z $res ]; then break;  fi ; done
 61581
 42056
 38021
 
 $ 
 
 give me a empty string in $res sometimes. I haven't really put any
 though into why this is, maybe just a side effect of running it in th
 while loop?

No, it's a side effect of od printing a decimal number which is sometimes less 
than 1 and so
is space-padded on the left.

Try:
while : ; do x=$(od -N2 -d /dev/urandom); y=$(echo $x | cut -s -d' ' -f2); 
echo $y; if test -z $y; then echo $x; break; fi; done

When it errors out, $x contains:
000  9611
002

Now is it clear?

Include *all* the fields other than 1 and it will never fail:

while :; do res=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2-); echo $res; if [ 
-z $res ]; then break;  fi ; done

The other way is to use a number format that is zero-padded:
while :; do res=0x$(od -N2 -x /dev/urandom | cut -s -d' ' -f2-); echo $res; if 
[ -z $res ]; then break;  fi ; done


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful

2013-01-09 Thread sacrificial-spam-address
 Thanks, I fixed this now in my bzr tree and it will be part of the
 next upload.

Er, assuming that's revision 2269:
http://anonscm.debian.org/loggerhead/apt/debian-sid/revision/2269/debian/apt.cron.daily

You don't need the final cut -c1-5.  It is true that cksum returns an
unsigned 32-bit number, and some shells only do 32-bit signed math, but
they simply convert the number to negative.

You either mask off the sign bit with
RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2 /dev/null | cksum | cut -d' ' 
-f1) % 0x7fff))

Or, of you want to emulate the range of Bash $RANDOM exactly:
RANDOM=$(($(dd if=/dev/urandom bs=2 count=1 2 /dev/null | cksum | cut -d' ' 
-f1) % 0x7fff))

The od -d -N2 -An solution works with a recent enough od.
I was looking to see how old that can be.  The uppercase option flags
are not in 7th edition, but are in POSIX.1 as of 2001:
http://www.unix.com/man-page/posix/0/od/
It also appears to be in xpg4:
http://docs.oracle.com/cd/E19963-01/html/821-1461/od-1.html
And in SunOD 5.8 (2000):
http://www.manpages.info/sunos/od.1.html
GNU textutils 2.0 (1999):
http://sunsite.ualberta.ca/Documentation/Gnu/textutils-2.0/man/od.1.html

Apparently the spec was in POSIX.1 as of 1992, alyhough not NetBSD
as of 2000:
http://gnats.netbsd.org/11204
It was added to NetBSD in 2008:
http://cvsweb.netbsd.org/bsdweb.cgi/src/usr.bin/hexdump/od.1?rev=1.23content-type=text/x-cvsweb-markupf=Honly_with_tag=MAIN


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful

2013-01-08 Thread Michael Vogt
On Thu, Dec 06, 2012 at 11:45:40AM -0500, sacrificial-spam-addr...@horizon.com 
wrote:
 Package: apt
 Version: 0.9.7.6
 Severity: minor
 
Thanks for your bugreport.

[..]
 This backup for a missing $RANDOM reads 512 bytes out of /dev/urandom, only
 to reduce it (incorrectly) to a 5-digit number (16.6 bits max, although
 the distribution is skewed), then to 10.8 bits (modulo 1800).
 
 It's incorrect because cksum produces a 32-bit checksum, formatted as
 %u, so some small fraction of the time (1 in 4.3 million times), it'll
 be less than 1000 and the cut will produce a result of the form 123 4, 
 causing the evaluation
 of TIME to fail.

Thanks, I fixed this now in my bzr tree and it will be part of the
next upload.


Cheers,
 Michael


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org



Bug#695285: /etc/cron.daily/apt backup RNG is very wasteful

2012-12-06 Thread sacrificial-spam-address
Package: apt
Version: 0.9.7.6
Severity: minor

/etc/cron.daily/apt does:
random_sleep()
{
RandomSleep=1800
eval $(apt-config shell RandomSleep APT::Periodic::RandomSleep)
if [ $RandomSleep -eq 0 ]; then
return
fi
if [ -z $RANDOM ] ; then
# A fix for shells that do not have this bash feature.
RANDOM=$(dd if=/dev/urandom count=1 2 /dev/null | cksum | cut -c1-5)
fi
TIME=$(($RANDOM % $RandomSleep))
debug_echo sleeping for $TIME seconds
sleep $TIME
}

This backup for a missing $RANDOM reads 512 bytes out of /dev/urandom, only
to reduce it (incorrectly) to a 5-digit number (16.6 bits max, although
the distribution is skewed), then to 10.8 bits (modulo 1800).

It's incorrect because cksum produces a 32-bit checksum, formatted as
%u, so some small fraction of the time (1 in 4.3 million times), it'll
be less than 1000 and the cut will produce a result of the form 123 4, 
causing the evaluation
of TIME to fail.

Two other options, which both use a lot less entropy and don't have the
bug, are:
RANDOM=$(dd if=/dev/urandom bs=2 count=1 2/dev/null | cksum | cut -d' 
' -f1)
RANDOM=$(od -N2 -d /dev/urandom | cut -s -d' ' -f2)

or, using more shell builtins:

read x RANDOM EOF
$(od -N2 -d /dev/urandom)
EOF

(The fact that you can't just pipe into read is a well-known sh problem.)


Also, you don't need to prefix variables with $ inside $(()); you can
use TIME=$((RANDOM % RandomSleep))


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of unsubscribe. Trouble? Contact listmas...@lists.debian.org