svn commit: r321139 - in stable/11/bin/dd: . tests
Ngie Cooper
ngie at FreeBSD.org
Tue Jul 18 17:35:30 UTC 2017
Author: ngie
Date: Tue Jul 18 17:35:29 2017
New Revision: 321139
URL: https://svnweb.freebsd.org/changeset/base/321139
Log:
MFC r302500,r319339,r319543,r319544,r319551,r321138:
r302500 (by cem):
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.
r319339 (by asomers):
Fix integer overflow detection in dd
dd(1) tried to detect whether the seek offset would overflow, but it failed
to account for the case where the provided argument was negative and the
file was a regular file (negative seeks are allowed for character devices).
I fixed it, and added a regression test.
CID: 1368659
r319543:
Stylistic tweaks
Move opening braces of functions from the last column to column 0.
MFC with: r319339
r319544:
Mark :seek_overflow as an expected failure
MFC with: r319339
PR: 219757
r319551 (by asomers):
Fix bin/dd/dd2_tests:seek_overflow on UFS and TMPFS
Split the postive and negative parts into separate test cases. The positive
test case can only run on ZFS, because only ZFS supports files that large.
PR: 219757
r321138:
Remove unnecessary make logic added in r319339
This makes the change cleaner and easier to backport to ^/stable/10.
Added:
stable/11/bin/dd/tests/dd2_test.sh
- copied, changed from r319339, head/bin/dd/tests/dd2_test.sh
Modified:
stable/11/bin/dd/args.c
stable/11/bin/dd/position.c
stable/11/bin/dd/tests/Makefile
Directory Properties:
stable/11/ (props changed)
Modified: stable/11/bin/dd/args.c
==============================================================================
--- stable/11/bin/dd/args.c Tue Jul 18 17:29:12 2017 (r321138)
+++ stable/11/bin/dd/args.c Tue Jul 18 17:35:29 2017 (r321139)
@@ -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: stable/11/bin/dd/position.c
==============================================================================
--- stable/11/bin/dd/position.c Tue Jul 18 17:29:12 2017 (r321138)
+++ stable/11/bin/dd/position.c Tue Jul 18 17:35:29 2017 (r321139)
@@ -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 < 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;
Modified: stable/11/bin/dd/tests/Makefile
==============================================================================
--- stable/11/bin/dd/tests/Makefile Tue Jul 18 17:29:12 2017 (r321138)
+++ stable/11/bin/dd/tests/Makefile Tue Jul 18 17:35:29 2017 (r321139)
@@ -1,5 +1,6 @@
# $FreeBSD$
+ATF_TESTS_SH= dd2_test
NETBSD_ATF_TESTS_SH= dd_test
.include <netbsd-tests.test.mk>
Copied and modified: stable/11/bin/dd/tests/dd2_test.sh (from r319339, head/bin/dd/tests/dd2_test.sh)
==============================================================================
--- head/bin/dd/tests/dd2_test.sh Wed May 31 16:07:32 2017 (r319339, copy source)
+++ stable/11/bin/dd/tests/dd2_test.sh Tue Jul 18 17:35:29 2017 (r321139)
@@ -26,17 +26,35 @@
# $FreeBSD$
-atf_test_case seek_overflow
-seek_overflow_head() {
- atf_set "descr" "dd(1) should reject too-large seek values"
+atf_test_case max_seek
+max_seek_head()
+{
+ atf_set "descr" "dd(1) can seek by the maximum amount"
}
-seek_overflow_body() {
+max_seek_body()
+{
+ case `df -T . | tail -n 1 | cut -wf 2` in
+ "ufs")
+ atf_skip "UFS's maximum file size is too small";;
+ "zfs") ;; # ZFS is fine
+ "tmpfs")
+ atf_skip "tmpfs can't create arbitrarily large spare files";;
+ *) atf_skip "Unknown file system";;
+ esac
+
touch f.in
- # Positive tests
seek=`echo "2^63 / 4096 - 1" | bc`
atf_check -s exit:0 -e ignore dd if=f.in of=f.out bs=4096 seek=$seek
+}
- # Negative tests
+atf_test_case seek_overflow
+seek_overflow_head()
+{
+ atf_set "descr" "dd(1) should reject too-large seek values"
+}
+seek_overflow_body()
+{
+ touch f.in
seek=`echo "2^63 / 4096" | bc`
atf_check -s not-exit:0 -e match:"seek offsets cannot be larger than" \
dd if=f.in of=f.out bs=4096 seek=$seek
@@ -46,5 +64,6 @@ seek_overflow_body() {
atf_init_test_cases()
{
- atf_add_test_case seek_overflow
+ atf_add_test_case max_seek
+ atf_add_test_case seek_overflow
}
More information about the svn-src-all
mailing list