NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
kern/44310: write to /dev/bpf truncates size_t to int
>Number: 44310
>Category: kern
>Synopsis: write to /dev/bpf truncates size_t to int
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Jan 02 12:40:00 +0000 2011
>Originator: Alexander Nasonov
>Release: NetBSD 5.99.41 amd64
>Organization:
N/A
>Environment:
NetBSD nebeda.localdomain 5.99.41 NetBSD 5.99.41 (GENERIC) #0: Sat Dec 18
22:46:18 GMT 2010
root%nebeda.localdomain@localhost:/home/alnsn/src/netbsd-current/src/sys/arch/amd64/compile/obj/GENERIC
amd64
>Description:
Write of 4G + 28 bytes of data to bpf device returns 28. It should return -1
and set errno to EMSGSIZE instead.
>How-To-Repeat:
Apply the attached patch to tests/net/bpf/t_bpf.c and run the test.
Index: tests/net/bpf/t_bpf.c
===================================================================
RCS file: /cvsroot/src/tests/net/bpf/t_bpf.c,v
retrieving revision 1.1
diff -u -r1.1 t_bpf.c
--- tests/net/bpf/t_bpf.c 6 Dec 2010 11:32:01 -0000 1.1
+++ tests/net/bpf/t_bpf.c 2 Jan 2011 12:36:13 -0000
@@ -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();
}
>Fix:
I have a patch which I'll post to tech-kern soon.
Home |
Main Index |
Thread Index |
Old Index