Date: Sat, 9 Jul 2016 17:11:54 +0000 (UTC) From: "Conrad E. Meyer" <cem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r302500 - head/bin/dd Message-ID: <201607091711.u69HBs2K017668@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: cem Date: Sat Jul 9 17:11:54 2016 New Revision: 302500 URL: https://svnweb.freebsd.org/changeset/base/302500 Log: dd(1): Enable access to SIZE_T_MAX character devices On machines where SIZE_T_MAX exceeds OFF_MAX (signed 64-bit), permit seeking character devices to negative off_t values. This enables dd(1) to interact with kernel KVA in /dev/kmem on amd64, for example. Sponsored by: EMC / Isilon Storage Division Modified: head/bin/dd/args.c head/bin/dd/position.c Modified: head/bin/dd/args.c ============================================================================== --- head/bin/dd/args.c Sat Jul 9 14:59:16 2016 (r302499) +++ head/bin/dd/args.c Sat Jul 9 17:11:54 2016 (r302500) @@ -167,14 +167,6 @@ jcl(char **argv) errx(1, "cbs meaningless if not doing record operations"); } else cfunc = def; - - /* - * Bail out if the calculation of a file offset would overflow. - */ - if (in.offset > OFF_MAX / (ssize_t)in.dbsz || - out.offset > OFF_MAX / (ssize_t)out.dbsz) - errx(1, "seek offsets cannot be larger than %jd", - (intmax_t)OFF_MAX); } static int Modified: head/bin/dd/position.c ============================================================================== --- head/bin/dd/position.c Sat Jul 9 14:59:16 2016 (r302499) +++ head/bin/dd/position.c Sat Jul 9 17:11:54 2016 (r302500) @@ -45,12 +45,41 @@ __FBSDID("$FreeBSD$"); #include <err.h> #include <errno.h> #include <inttypes.h> +#include <limits.h> #include <signal.h> #include <unistd.h> #include "dd.h" #include "extern.h" +static off_t +seek_offset(IO *io) +{ + off_t n; + size_t sz; + + n = io->offset; + sz = io->dbsz; + + _Static_assert(sizeof(io->offset) == sizeof(int64_t), "64-bit off_t"); + + /* + * If the lseek offset will be negative, verify that this is a special + * device file. Some such files (e.g. /dev/kmem) permit "negative" + * offsets. + * + * Bail out if the calculation of a file offset would overflow. + */ + if ((io->flags & ISCHR) == 0 && n > OFF_MAX / (ssize_t)sz) + errx(1, "seek offsets cannot be larger than %jd", + (intmax_t)OFF_MAX); + else if ((io->flags & ISCHR) != 0 && (uint64_t)n > UINT64_MAX / sz) + errx(1, "seek offsets cannot be larger than %ju", + (uintmax_t)UINT64_MAX); + + return ((off_t)( (uint64_t)n * sz )); +} + /* * Position input/output data streams before starting the copy. Device type * dependent. Seekable devices use lseek, and the rest position by reading. @@ -68,7 +97,7 @@ pos_in(void) /* If known to be seekable, try to seek on it. */ if (in.flags & ISSEEK) { errno = 0; - if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 && + if (lseek(in.fd, seek_offset(&in), SEEK_CUR) == -1 && errno != 0) err(1, "%s", in.name); return; @@ -136,7 +165,7 @@ pos_out(void) */ if (out.flags & (ISSEEK | ISPIPE)) { errno = 0; - if (lseek(out.fd, out.offset * out.dbsz, SEEK_CUR) == -1 && + if (lseek(out.fd, seek_offset(&out), SEEK_CUR) == -1 && errno != 0) err(1, "%s", out.name); return;
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201607091711.u69HBs2K017668>