Module Name: src Committed By: christos Date: Mon Jan 3 02:53:15 UTC 2011
Modified Files: src/tests/net/bpf: Makefile t_bpf.c Log Message: PR/44310: Alexander Nasonov: write to /dev/bpf truncates size_t to int To generate a diff of this commit: cvs rdiff -u -r1.2 -r1.3 src/tests/net/bpf/Makefile cvs rdiff -u -r1.1 -r1.2 src/tests/net/bpf/t_bpf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/net/bpf/Makefile diff -u src/tests/net/bpf/Makefile:1.2 src/tests/net/bpf/Makefile:1.3 --- src/tests/net/bpf/Makefile:1.2 Mon Dec 6 06:32:01 2010 +++ src/tests/net/bpf/Makefile Sun Jan 2 21:53:15 2011 @@ -1,4 +1,4 @@ -# $NetBSD: Makefile,v 1.2 2010/12/06 11:32:01 pooka Exp $ +# $NetBSD: Makefile,v 1.3 2011/01/03 02:53:15 christos Exp $ # .include <bsd.own.mk> @@ -9,7 +9,7 @@ TESTS_C+= t_div-by-zero LDADD+= -lrumpnet_shmif -LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_net -lrumpnet -lrumpvfs -LDADD+= -lrump -lrumpuser -lpthread +LDADD+= -lrumpdev_bpf -lrumpdev -lrumpnet_netinet -lrumpnet_net +LDADD+= -lrumpnet -lrumpvfs -lrump -lrumpuser -lpthread .include <bsd.test.mk> Index: src/tests/net/bpf/t_bpf.c diff -u src/tests/net/bpf/t_bpf.c:1.1 src/tests/net/bpf/t_bpf.c:1.2 --- src/tests/net/bpf/t_bpf.c:1.1 Mon Dec 6 06:32:01 2010 +++ src/tests/net/bpf/t_bpf.c Sun Jan 2 21:53:15 2011 @@ -1,4 +1,4 @@ -/* $NetBSD: t_bpf.c,v 1.1 2010/12/06 11:32:01 pooka Exp $ */ +/* $NetBSD: t_bpf.c,v 1.2 2011/01/03 02:53:15 christos Exp $ */ /*- * Copyright (c) 2010 Antti Kantee. All Rights Reserved. @@ -30,6 +30,8 @@ #include <sys/socket.h> #include <sys/mbuf.h> #include <sys/sysctl.h> +#include <sys/mman.h> +#include <unistd.h> #include <net/if.h> #include <net/bpf.h> @@ -47,6 +49,7 @@ #include <atf-c.h> #include "../../h_macros.h" +#include "../config/netconfig.c" ATF_TC(bpfwriteleak); ATF_TC_HEAD(bpfwriteleak, tc) @@ -93,9 +96,81 @@ ATF_REQUIRE_EQ(getmtdata(), 0); } +#if (SIZE_MAX > UINT_MAX) +ATF_TC(bpfwritetrunc); +ATF_TC_HEAD(bpfwritetrunc, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checks that write to /dev/bpf " + "does not truncate size_t to int"); +} + +ATF_TC_BODY(bpfwritetrunc, tc) +{ + int bpfd; + struct ifreq ifr; + struct iovec *iov; + size_t iovlen, sz; + const size_t extra_bytes = 28; + const size_t total = extra_bytes + UINT_MAX + 1; + long iov_max, vm_page_size; /* round_page wants vm_page_size variable */ + + memset(&ifr, 0, sizeof(ifr)); + + iov_max = sysconf(_SC_IOV_MAX); + vm_page_size = sysconf(_SC_PAGE_SIZE); + ATF_REQUIRE(iov_max > 1 && vm_page_size > 1); + + /* Minimize memory consumption by using many iovecs + * all pointing to one memory region */ + iov = calloc(iov_max, sizeof(struct iovec)); + ATF_REQUIRE(iov != NULL); + + sz = round_page((total + (iov_max - 1)) / iov_max); + + iov[0].iov_len = sz; + iov[0].iov_base = mmap(NULL, sz, PROT_READ, MAP_ANON, -1, 0); + ATF_REQUIRE(iov[0].iov_base != MAP_FAILED); + + iovlen = 1; + while(sz + iov[0].iov_len <= total) + { + iov[iovlen].iov_len = iov[0].iov_len; + iov[iovlen].iov_base = iov[0].iov_base; + sz += iov[0].iov_len; + iovlen++; + } + + if(sz < total) + { + iov[iovlen].iov_len = total - sz; + iov[iovlen].iov_base = iov[0].iov_base; + iovlen++; + } + + /* Sanity checks */ + ATF_REQUIRE(iovlen >= 1 && iovlen <= (size_t)iov_max); + ATF_REQUIRE_EQ(iov[iovlen-1].iov_len, total % iov[0].iov_len); + + RZ(rump_init()); + netcfg_rump_makeshmif("bpfwritetrunc", ifr.ifr_name); + netcfg_rump_if(ifr.ifr_name, "10.1.1.1", "255.0.0.0"); + + RL(bpfd = rump_sys_open("/dev/bpf", O_RDWR)); + RL(rump_sys_ioctl(bpfd, BIOCSETIF, &ifr)); + + ATF_CHECK_ERRNO(EMSGSIZE, rump_sys_writev(bpfd, iov, iovlen) == -1); + + munmap(iov[0].iov_base, iov[0].iov_len); + free(iov); +} +#endif /* #if (SIZE_MAX > UINT_MAX) */ + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, bpfwriteleak); +#if (SIZE_MAX > UINT_MAX) + ATF_TP_ADD_TC(tp, bpfwritetrunc); +#endif return atf_no_error(); }