Hi, tobias@ spotted this one a few months ago when reviewing a different diff of mine.
Casting the size given to malloc(3) here causes it to wrap if our block sizes are large enough, and then dd(1) misbehaves, at least on 64-bit platforms: # dd bs=$(((1 << 31) + 1)) cbs=$((1 << 31)) conv=ascii if=/dev/zero of=/dev/null count=1 dd: /dev/random: Bad address The block sizes sum to 1 when cast and malloc(3) breaks us off a byte. read(2) then sees that it would be writing outside the valid address space and fails. Fix attached. Maybe pedantic, but should we also be checking for addition overflow? OpenBSD is fine -- those additions will not overflow, as we check prior to this point that all block sizes are <= SSIZE_MAX. But the standard doesn't guarantee that SSIZE_MAX * 2 < SIZE_MAX. Are such considerations left to the porter? ... ok as-is? -Scott Index: bin/dd/dd.c =================================================================== RCS file: /cvs/src/bin/dd/dd.c,v retrieving revision 1.24 diff -u -p -r1.24 dd.c --- bin/dd/dd.c 13 Aug 2017 02:06:42 -0000 1.24 +++ bin/dd/dd.c 20 Jul 2018 23:44:12 -0000 @@ -136,10 +136,14 @@ setup(void) if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) err(1, "input buffer"); out.db = in.db; - } else if ((in.db = - malloc((u_int)(MAXIMUM(in.dbsz, cbsz) + cbsz))) == NULL || - (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) - err(1, "output buffer"); + } else { + in.db = malloc(MAXIMUM(in.dbsz, cbsz) + cbsz); + if (in.db == NULL) + err(1, "input buffer"); + out.db = malloc(out.dbsz + cbsz); + if (out.db == NULL) + err(1, "output buffer"); + } in.dbp = in.db; out.dbp = out.db;