Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F161042894
D45686.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
84 KB
Referenced Files
None
Subscribers
None
D45686.diff
View Options
diff --git a/include/ssp/Makefile b/include/ssp/Makefile
--- a/include/ssp/Makefile
+++ b/include/ssp/Makefile
@@ -1,5 +1,5 @@
-INCS= poll.h random.h ssp.h stdio.h stdlib.h string.h strings.h uio.h unistd.h
-INCS+= wchar.h
+INCS= poll.h random.h socket.h ssp.h stdio.h stdlib.h string.h strings.h
+INCS+= uio.h unistd.h wchar.h
INCSDIR= ${INCLUDEDIR}/ssp
.include <bsd.prog.mk>
diff --git a/include/ssp/socket.h b/include/ssp/socket.h
new file mode 100644
--- /dev/null
+++ b/include/ssp/socket.h
@@ -0,0 +1,119 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024, Klara, Inc.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _SSP_SOCKET_H_
+#define _SSP_SOCKET_H_
+
+#include <ssp/ssp.h>
+
+#if __SSP_FORTIFY_LEVEL > 0
+
+#include <sys/_null.h>
+
+__BEGIN_DECLS
+
+__ssp_inline void
+__ssp_check_msghdr(struct msghdr *hdr)
+{
+ if (__ssp_bos(hdr->msg_name) < hdr->msg_namelen)
+ __chk_fail();
+
+ __ssp_check_iovec(hdr->msg_iov, hdr->msg_iovlen);
+
+ if (__ssp_bos(hdr->msg_control) < hdr->msg_controllen)
+ __chk_fail();
+}
+
+__ssp_redirect_raw_impl(int, getpeername, getpeername,
+ (int fdes, struct sockaddr *__restrict name, socklen_t *__restrict namelen))
+{
+ size_t namesz = __ssp_bos(name);
+
+ if (namesz != (size_t)-1 && namesz < *namelen)
+ __chk_fail();
+
+ return (__ssp_real(getpeername)(fdes, name, namelen));
+}
+
+__ssp_redirect_raw_impl(int, getsockname, getsockname,
+ (int fdes, struct sockaddr *__restrict name,
+ socklen_t *__restrict namelen))
+{
+ size_t namesz = __ssp_bos(name);
+
+ if (namesz != (size_t)-1 && namesz < *namelen)
+ __chk_fail();
+
+ return (__ssp_real(getsockname)(fdes, name, namelen));
+}
+
+__ssp_redirect(ssize_t, recv, (int __sock, void *__buf, size_t __len,
+ int __flags), (__sock, __buf, __len, __flags));
+
+__ssp_redirect_raw_impl(ssize_t, recvfrom, recvfrom,
+ (int s, void *buf, size_t len, int flags,
+ struct sockaddr *__restrict from,
+ socklen_t *__restrict fromlen))
+{
+ if (__ssp_bos(buf) < len)
+ __chk_fail();
+ if (from != NULL && __ssp_bos(from) < *fromlen)
+ __chk_fail();
+
+ return (__ssp_real(recvfrom)(s, buf, len, flags, from, fromlen));
+}
+
+__ssp_redirect_raw_impl(ssize_t, recvmsg, recvmsg,
+ (int s, struct msghdr *hdr, int flags))
+{
+ __ssp_check_msghdr(hdr);
+ return (__ssp_real(recvmsg)(s, hdr, flags));
+}
+
+#if __BSD_VISIBLE
+struct timespec;
+
+__ssp_redirect_raw_impl(ssize_t, recvmmsg, recvmmsg,
+ (int s, struct mmsghdr *__restrict hdrvec, size_t vlen, int flags,
+ const struct timespec *__restrict timeout))
+{
+ const size_t vecsz = __ssp_bos(hdrvec);
+
+ if (vecsz != (size_t)-1 && vecsz / sizeof(*hdrvec) < vlen)
+ __chk_fail();
+
+ for (size_t i = 0; i < vlen; i++) {
+ __ssp_check_msghdr(&hdrvec[i].msg_hdr);
+ }
+
+ return (__ssp_real(recvmmsg)(s, hdrvec, vlen, flags, timeout));
+}
+#endif
+
+__END_DECLS
+
+#endif /* __SSP_FORTIFY_LEVEL > 0 */
+#endif /* _SSP_SOCKET_H_ */
diff --git a/lib/libc/sys/recv.c b/lib/libc/sys/recv.c
--- a/lib/libc/sys/recv.c
+++ b/lib/libc/sys/recv.c
@@ -31,12 +31,13 @@
#include <sys/types.h>
#include <sys/socket.h>
+#include <ssp/ssp.h>
#include "libc_private.h"
#include <stddef.h>
ssize_t
-recv(int s, void *buf, size_t len, int flags)
+__ssp_real(recv)(int s, void *buf, size_t len, int flags)
{
/*
* POSIX says recv() shall be a cancellation point, so call the
diff --git a/lib/libc/sys/recvfrom.c b/lib/libc/sys/recvfrom.c
--- a/lib/libc/sys/recvfrom.c
+++ b/lib/libc/sys/recvfrom.c
@@ -32,13 +32,14 @@
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/socket.h>
+#include <ssp/ssp.h>
#include "libc_private.h"
__weak_reference(__sys_recvfrom, __recvfrom);
#pragma weak recvfrom
ssize_t
-recvfrom(int s, void *buf, size_t len, int flags,
+__ssp_real(recvfrom)(int s, void *buf, size_t len, int flags,
struct sockaddr * __restrict from, socklen_t * __restrict fromlen)
{
return (INTERPOS_SYS(recvfrom, s, buf, len, flags, from, fromlen));
diff --git a/lib/libc/sys/recvmsg.c b/lib/libc/sys/recvmsg.c
--- a/lib/libc/sys/recvmsg.c
+++ b/lib/libc/sys/recvmsg.c
@@ -32,13 +32,14 @@
#include <sys/types.h>
#include <sys/syscall.h>
#include <sys/socket.h>
+#include <ssp/ssp.h>
#include "libc_private.h"
__weak_reference(__sys_recvmsg, __recvmsg);
#pragma weak recvmsg
ssize_t
-recvmsg(int s, struct msghdr *msg, int flags)
+__ssp_real(recvmsg)(int s, struct msghdr *msg, int flags)
{
return (INTERPOS_SYS(recvmsg, s, msg, flags));
}
diff --git a/lib/libc/tests/secure/Makefile b/lib/libc/tests/secure/Makefile
--- a/lib/libc/tests/secure/Makefile
+++ b/lib/libc/tests/secure/Makefile
@@ -5,6 +5,7 @@
# sys/ headers
FORTIFY_TCATS+= random
FORTIFY_TCATS+= select
+FORTIFY_TCATS+= socket
FORTIFY_TCATS+= uio
# non-sys/ headers
diff --git a/lib/libc/tests/secure/fortify_poll_test.c b/lib/libc/tests/secure/fortify_poll_test.c
--- a/lib/libc/tests/secure/fortify_poll_test.c
+++ b/lib/libc/tests/secure/fortify_poll_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_random_test.c b/lib/libc/tests/secure/fortify_random_test.c
--- a/lib/libc/tests/secure/fortify_random_test.c
+++ b/lib/libc/tests/secure/fortify_random_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_select_test.c b/lib/libc/tests/secure/fortify_select_test.c
--- a/lib/libc/tests/secure/fortify_select_test.c
+++ b/lib/libc/tests/secure/fortify_select_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_socket_test.c
copy from lib/libc/tests/secure/fortify_string_test.c
copy to lib/libc/tests/secure/fortify_socket_test.c
--- a/lib/libc/tests/secure/fortify_string_test.c
+++ b/lib/libc/tests/secure/fortify_socket_test.c
@@ -1,4 +1,4 @@
-/* @generated by `generate-fortify-tests.lua "string"` */
+/* @generated by `generate-fortify-tests.lua "socket"` */
#define _FORTIFY_SOURCE 2
#define TMPFILE_SIZE (1024 * 32)
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
@@ -117,102 +162,112 @@
close(fd);
}
-ATF_TC_WITHOUT_HEAD(memcpy_before_end);
-ATF_TC_BODY(memcpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getpeername_before_end);
+ATF_TC_BODY(getpeername_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
+ new_socket(sock);
+ socklen = __len;
- memcpy(__stack.__buf, src, __len);
+ getpeername(sock[0], &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memcpy_end);
-ATF_TC_BODY(memcpy_end, tc)
+ATF_TC_WITHOUT_HEAD(getpeername_end);
+ATF_TC_BODY(getpeername_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
+ new_socket(sock);
+ socklen = __len;
- memcpy(__stack.__buf, src, __len);
+ getpeername(sock[0], &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memcpy_heap_before_end);
-ATF_TC_BODY(memcpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getpeername_heap_before_end);
+ATF_TC_BODY(getpeername_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- memcpy(__stack.__buf, src, __len);
+ getpeername(sock[0], __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memcpy_heap_end);
-ATF_TC_BODY(memcpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(getpeername_heap_end);
+ATF_TC_BODY(getpeername_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- memcpy(__stack.__buf, src, __len);
+ getpeername(sock[0], __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memcpy_heap_after_end);
-ATF_TC_BODY(memcpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(getpeername_heap_after_end);
+ATF_TC_BODY(getpeername_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__child = fork();
ATF_REQUIRE(__child >= 0);
if (__child > 0)
@@ -221,8 +276,10 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- memcpy(__stack.__buf, src, __len);
+ getpeername(sock[0], __stack.__buf, &socklen);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -249,102 +306,112 @@
}
-ATF_TC_WITHOUT_HEAD(mempcpy_before_end);
-ATF_TC_BODY(mempcpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getsockname_before_end);
+ATF_TC_BODY(getsockname_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
+ new_socket(sock);
+ socklen = __len;
- mempcpy(__stack.__buf, src, __len);
+ getsockname(sock[0], &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(mempcpy_end);
-ATF_TC_BODY(mempcpy_end, tc)
+ATF_TC_WITHOUT_HEAD(getsockname_end);
+ATF_TC_BODY(getsockname_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
+ new_socket(sock);
+ socklen = __len;
- mempcpy(__stack.__buf, src, __len);
+ getsockname(sock[0], &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(mempcpy_heap_before_end);
-ATF_TC_BODY(mempcpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getsockname_heap_before_end);
+ATF_TC_BODY(getsockname_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- mempcpy(__stack.__buf, src, __len);
+ getsockname(sock[0], __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(mempcpy_heap_end);
-ATF_TC_BODY(mempcpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(getsockname_heap_end);
+ATF_TC_BODY(getsockname_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- mempcpy(__stack.__buf, src, __len);
+ getsockname(sock[0], __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(mempcpy_heap_after_end);
-ATF_TC_BODY(mempcpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(getsockname_heap_after_end);
+ATF_TC_BODY(getsockname_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len + 10];
-
+ int sock[2] = { -1, -1 };
+ socklen_t socklen;
__child = fork();
ATF_REQUIRE(__child >= 0);
if (__child > 0)
@@ -353,8 +420,10 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
+ socklen = __len;
- mempcpy(__stack.__buf, src, __len);
+ getsockname(sock[0], __stack.__buf, &socklen);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -381,8 +450,8 @@
}
-ATF_TC_WITHOUT_HEAD(memmove_before_end);
-ATF_TC_BODY(memmove_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recv_before_end);
+ATF_TC_BODY(recv_before_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -393,15 +462,17 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
+
+ new_socket(sock);
- memmove(__stack.__buf, src, __len);
+ recv(sock[0], __stack.__buf, __len, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memmove_end);
-ATF_TC_BODY(memmove_end, tc)
+ATF_TC_WITHOUT_HEAD(recv_end);
+ATF_TC_BODY(recv_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -412,15 +483,17 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
- memmove(__stack.__buf, src, __len);
+ new_socket(sock);
+
+ recv(sock[0], __stack.__buf, __len, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memmove_heap_before_end);
-ATF_TC_BODY(memmove_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recv_heap_before_end);
+ATF_TC_BODY(recv_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -431,17 +504,18 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memmove(__stack.__buf, src, __len);
+ recv(sock[0], __stack.__buf, __len, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memmove_heap_end);
-ATF_TC_BODY(memmove_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recv_heap_end);
+ATF_TC_BODY(recv_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -452,17 +526,18 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memmove(__stack.__buf, src, __len);
+ recv(sock[0], __stack.__buf, __len, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memmove_heap_after_end);
-ATF_TC_BODY(memmove_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recv_heap_after_end);
+ATF_TC_BODY(recv_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -475,7 +550,7 @@
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len + 10];
+ int sock[2] = { -1, -1 };
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -485,8 +560,9 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memmove(__stack.__buf, src, __len);
+ recv(sock[0], __stack.__buf, __len, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -513,8 +589,8 @@
}
-ATF_TC_WITHOUT_HEAD(memset_before_end);
-ATF_TC_BODY(memset_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_before_end);
+ATF_TC_BODY(recvfrom_before_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -525,14 +601,17 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
+ int sock[2] = { -1, -1 };
+
+ new_socket(sock);
- memset(__stack.__buf, 0, __len);
+ recvfrom(sock[0], __stack.__buf, __len, 0, NULL, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memset_end);
-ATF_TC_BODY(memset_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_end);
+ATF_TC_BODY(recvfrom_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -543,14 +622,17 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
+ int sock[2] = { -1, -1 };
+
+ new_socket(sock);
- memset(__stack.__buf, 0, __len);
+ recvfrom(sock[0], __stack.__buf, __len, 0, NULL, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memset_heap_before_end);
-ATF_TC_BODY(memset_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_heap_before_end);
+ATF_TC_BODY(recvfrom_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -561,16 +643,18 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memset(__stack.__buf, 0, __len);
+ recvfrom(sock[0], __stack.__buf, __len, 0, NULL, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memset_heap_end);
-ATF_TC_BODY(memset_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_heap_end);
+ATF_TC_BODY(recvfrom_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -581,16 +665,18 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memset(__stack.__buf, 0, __len);
+ recvfrom(sock[0], __stack.__buf, __len, 0, NULL, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(memset_heap_after_end);
-ATF_TC_BODY(memset_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_heap_after_end);
+ATF_TC_BODY(recvfrom_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -603,6 +689,7 @@
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
+ int sock[2] = { -1, -1 };
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -612,8 +699,9 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
+ new_socket(sock);
- memset(__stack.__buf, 0, __len);
+ recvfrom(sock[0], __stack.__buf, __len, 0, NULL, NULL);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -640,115 +728,121 @@
}
-ATF_TC_WITHOUT_HEAD(stpcpy_before_end);
-ATF_TC_BODY(stpcpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_sockaddr_before_end);
+ATF_TC_BODY(recvfrom_sockaddr_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ char data[16];
+ socklen_t socklen;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ new_socket(sock);
+ socklen = __len;
- stpcpy(__stack.__buf, src);
+ recvfrom(sock[0], data, sizeof(data), 0, &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpcpy_end);
-ATF_TC_BODY(stpcpy_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_sockaddr_end);
+ATF_TC_BODY(recvfrom_sockaddr_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ char data[16];
+ socklen_t socklen;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ new_socket(sock);
+ socklen = __len;
- stpcpy(__stack.__buf, src);
+ recvfrom(sock[0], data, sizeof(data), 0, &__stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpcpy_heap_before_end);
-ATF_TC_BODY(stpcpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_sockaddr_heap_before_end);
+ATF_TC_BODY(recvfrom_sockaddr_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ char data[16];
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ new_socket(sock);
+ socklen = __len;
- stpcpy(__stack.__buf, src);
+ recvfrom(sock[0], data, sizeof(data), 0, __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpcpy_heap_end);
-ATF_TC_BODY(stpcpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_sockaddr_heap_end);
+ATF_TC_BODY(recvfrom_sockaddr_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ char data[16];
+ socklen_t socklen;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ new_socket(sock);
+ socklen = __len;
- stpcpy(__stack.__buf, src);
+ recvfrom(sock[0], data, sizeof(data), 0, __stack.__buf, &socklen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpcpy_heap_after_end);
-ATF_TC_BODY(stpcpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvfrom_sockaddr_heap_after_end);
+ATF_TC_BODY(recvfrom_sockaddr_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ char data[16];
+ socklen_t socklen;
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -758,11 +852,10 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ new_socket(sock);
+ socklen = __len;
- stpcpy(__stack.__buf, src);
+ recvfrom(sock[0], data, sizeof(data), 0, __stack.__buf, &socklen);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -789,115 +882,120 @@
}
-ATF_TC_WITHOUT_HEAD(stpncpy_before_end);
-ATF_TC_BODY(stpncpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_name_before_end);
+ATF_TC_BODY(recvmsg_msg_name_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
- stpncpy(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpncpy_end);
-ATF_TC_BODY(stpncpy_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_name_end);
+ATF_TC_BODY(recvmsg_msg_name_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct sockaddr __buf;
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
- stpncpy(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpncpy_heap_before_end);
-ATF_TC_BODY(stpncpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_name_heap_before_end);
+ATF_TC_BODY(recvmsg_msg_name_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
- stpncpy(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpncpy_heap_end);
-ATF_TC_BODY(stpncpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_name_heap_end);
+ATF_TC_BODY(recvmsg_msg_name_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr);
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
- stpncpy(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(stpncpy_heap_after_end);
-ATF_TC_BODY(stpncpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_name_heap_after_end);
+ATF_TC_BODY(recvmsg_msg_name_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct sockaddr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (1);
+ const size_t __len = sizeof(struct sockaddr) + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -907,11 +1005,11 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
- stpncpy(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -938,8 +1036,8 @@
}
-ATF_TC_WITHOUT_HEAD(strcat_before_end);
-ATF_TC_BODY(strcat_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_iov_before_end);
+ATF_TC_BODY(recvmsg_msg_iov_before_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -950,19 +1048,30 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+ struct iovec iov[2];
+
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
+
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
- strcat(__stack.__buf, src);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strcat_end);
-ATF_TC_BODY(strcat_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_iov_end);
+ATF_TC_BODY(recvmsg_msg_iov_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -973,67 +1082,30 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len];
-
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcat(__stack.__buf, src);
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strcat_heap_before_end);
-ATF_TC_BODY(strcat_heap_before_end, tc)
-{
-#define BUF __stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char * __buf;
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
- const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+ struct iovec iov[2];
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
- strcat(__stack.__buf, src);
-#undef BUF
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
-}
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
-ATF_TC_WITHOUT_HEAD(strcat_heap_end);
-ATF_TC_BODY(strcat_heap_end, tc)
-{
-#define BUF __stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char * __buf;
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
- const size_t __idx __unused = __len - 1;
- char src[__len];
-
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcat(__stack.__buf, src);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strcat_heap_after_end);
-ATF_TC_BODY(strcat_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_iov_heap_before_end);
+ATF_TC_BODY(recvmsg_msg_iov_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1042,99 +1114,33 @@
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
- const size_t __idx __unused = __len - 1;
- pid_t __child;
- int __status;
- char src[__len];
-
- __child = fork();
- ATF_REQUIRE(__child >= 0);
- if (__child > 0)
- goto monitor;
-
- /* Child */
- disable_coredumps();
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcat(__stack.__buf, src);
- _exit(EX_SOFTWARE); /* Should have aborted. */
-
-monitor:
- while (waitpid(__child, &__status, 0) != __child) {
- ATF_REQUIRE_EQ(EINTR, errno);
- }
-
- if (!WIFSIGNALED(__status)) {
- switch (WEXITSTATUS(__status)) {
- case EX_SOFTWARE:
- atf_tc_fail("FORTIFY_SOURCE failed to abort");
- break;
- case EX_OSERR:
- atf_tc_fail("setrlimit(2) failed");
- break;
- default:
- atf_tc_fail("child exited with status %d",
- WEXITSTATUS(__status));
- }
- } else {
- ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
- }
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strlcat_before_end);
-ATF_TC_BODY(strlcat_before_end, tc)
-{
-#define BUF &__stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char __buf[42];
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+ struct iovec iov[2];
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strlcat(__stack.__buf, src, __len);
-#undef BUF
-
-}
+ __stack.__buf = malloc(__bufsz);
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
-ATF_TC_WITHOUT_HEAD(strlcat_end);
-ATF_TC_BODY(strlcat_end, tc)
-{
-#define BUF &__stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char __buf[42];
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
- const size_t __idx __unused = __len - 1;
- char src[__len];
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
- strlcat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strlcat_heap_before_end);
-ATF_TC_BODY(strlcat_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_iov_heap_end);
+ATF_TC_BODY(recvmsg_msg_iov_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1143,46 +1149,33 @@
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+ struct iovec iov[2];
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strlcat(__stack.__buf, src, __len);
-#undef BUF
-
-}
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
-ATF_TC_WITHOUT_HEAD(strlcat_heap_end);
-ATF_TC_BODY(strlcat_heap_end, tc)
-{
-#define BUF __stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char * __buf;
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
- const size_t __idx __unused = __len - 1;
- char src[__len];
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
- strlcat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strlcat_heap_after_end);
-ATF_TC_BODY(strlcat_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_iov_heap_after_end);
+ATF_TC_BODY(recvmsg_msg_iov_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1195,7 +1188,9 @@
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+ struct iovec iov[2];
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -1205,11 +1200,20 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
+
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
- strlcat(__stack.__buf, src, __len);
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
+
+ recvmsg(sock[0], &msg, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -1236,54 +1240,58 @@
}
-ATF_TC_WITHOUT_HEAD(strncat_before_end);
-ATF_TC_BODY(strncat_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_control_before_end);
+ATF_TC_BODY(recvmsg_msg_control_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ unsigned char __buf[CMSG_SPACE(sizeof(int))];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = CMSG_SPACE(sizeof(int)) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+
+ memset(&msg, 0, sizeof(msg));
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
- strncat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncat_end);
-ATF_TC_BODY(strncat_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_control_end);
+ATF_TC_BODY(recvmsg_msg_control_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ unsigned char __buf[CMSG_SPACE(sizeof(int))];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = CMSG_SPACE(sizeof(int));
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
+
+ memset(&msg, 0, sizeof(msg));
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
- strncat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncat_heap_before_end);
-ATF_TC_BODY(strncat_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_control_heap_before_end);
+ATF_TC_BODY(recvmsg_msg_control_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1291,23 +1299,25 @@
unsigned char * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (CMSG_SPACE(sizeof(int)));
+ const size_t __len = CMSG_SPACE(sizeof(int)) - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
- strncat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncat_heap_end);
-ATF_TC_BODY(strncat_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_control_heap_end);
+ATF_TC_BODY(recvmsg_msg_control_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1315,23 +1325,25 @@
unsigned char * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (CMSG_SPACE(sizeof(int)));
+ const size_t __len = CMSG_SPACE(sizeof(int));
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
- strncat(__stack.__buf, src, __len);
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
+
+ recvmsg(sock[0], &msg, 0);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncat_heap_after_end);
-ATF_TC_BODY(strncat_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmsg_msg_control_heap_after_end);
+ATF_TC_BODY(recvmsg_msg_control_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1339,12 +1351,13 @@
unsigned char * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (CMSG_SPACE(sizeof(int)));
+ const size_t __len = CMSG_SPACE(sizeof(int)) + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct msghdr msg;
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -1354,11 +1367,12 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
- strncat(__stack.__buf, src, __len);
+ recvmsg(sock[0], &msg, 0);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -1385,115 +1399,59 @@
}
-ATF_TC_WITHOUT_HEAD(strcpy_before_end);
-ATF_TC_BODY(strcpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_before_end);
+ATF_TC_BODY(recvmmsg_msgvec_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct mmsghdr __buf[2];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
+ const size_t __len = 2 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
-
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ int sock[2] = { -1, -1 };
- strcpy(__stack.__buf, src);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strcpy_end);
-ATF_TC_BODY(strcpy_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_end);
+ATF_TC_BODY(recvmmsg_msgvec_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[42];
+ struct mmsghdr __buf[2];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
+ const size_t __len = 2;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcpy(__stack.__buf, src);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strcpy_heap_before_end);
-ATF_TC_BODY(strcpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_after_end);
+ATF_TC_BODY(recvmmsg_msgvec_after_end, tc)
{
-#define BUF __stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char * __buf;
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
- const size_t __idx __unused = __len - 1;
- char src[__len];
-
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcpy(__stack.__buf, src);
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strcpy_heap_end);
-ATF_TC_BODY(strcpy_heap_end, tc)
-{
-#define BUF __stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char * __buf;
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
- const size_t __idx __unused = __len - 1;
- char src[__len];
-
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcpy(__stack.__buf, src);
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strcpy_heap_after_end);
-ATF_TC_BODY(strcpy_heap_after_end, tc)
-{
-#define BUF __stack.__buf
+#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct mmsghdr __buf[2];
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 2 + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -1502,12 +1460,7 @@
/* Child */
disable_coredumps();
- __stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strcpy(__stack.__buf, src);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -1534,115 +1487,63 @@
}
-ATF_TC_WITHOUT_HEAD(strlcpy_before_end);
-ATF_TC_BODY(strlcpy_before_end, tc)
-{
-#define BUF &__stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char __buf[42];
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42 - 1;
- const size_t __idx __unused = __len - 1;
- char src[__len];
-
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strlcpy(__stack.__buf, src, __len);
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strlcpy_end);
-ATF_TC_BODY(strlcpy_end, tc)
-{
-#define BUF &__stack.__buf
- struct {
- uint8_t padding_l;
- unsigned char __buf[42];
- uint8_t padding_r;
- } __stack;
- const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 42;
- const size_t __idx __unused = __len - 1;
- char src[__len];
-
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
-
- strlcpy(__stack.__buf, src, __len);
-#undef BUF
-
-}
-
-ATF_TC_WITHOUT_HEAD(strlcpy_heap_before_end);
-ATF_TC_BODY(strlcpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_heap_before_end);
+ATF_TC_BODY(recvmmsg_msgvec_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct mmsghdr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
+ const size_t __len = 2 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
- strlcpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strlcpy_heap_end);
-ATF_TC_BODY(strlcpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_heap_end);
+ATF_TC_BODY(recvmmsg_msgvec_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct mmsghdr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
+ const size_t __len = 2;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
- strlcpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strlcpy_heap_after_end);
-ATF_TC_BODY(strlcpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msgvec_heap_after_end);
+ATF_TC_BODY(recvmmsg_msgvec_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ struct mmsghdr * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
- const size_t __len = 42 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (2);
+ const size_t __len = 2 + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -1652,11 +1553,8 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
- strlcpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], __stack.__buf, __len, 0, NULL);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -1683,8 +1581,8 @@
}
-ATF_TC_WITHOUT_HEAD(strncpy_before_end);
-ATF_TC_BODY(strncpy_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msghdr_before_end);
+ATF_TC_BODY(recvmmsg_msghdr_before_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -1695,19 +1593,25 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct mmsghdr msgvec[2];
+
+ memset(&msgvec[0], 0, sizeof(msgvec));
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
- strncpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], &msgvec[0], nitems(msgvec), 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncpy_end);
-ATF_TC_BODY(strncpy_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msghdr_end);
+ATF_TC_BODY(recvmmsg_msghdr_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -1718,19 +1622,25 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct mmsghdr msgvec[2];
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msgvec[0], 0, sizeof(msgvec));
- strncpy(__stack.__buf, src, __len);
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
+
+ recvmmsg(sock[0], &msgvec[0], nitems(msgvec), 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncpy_heap_before_end);
-ATF_TC_BODY(strncpy_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msghdr_heap_before_end);
+ATF_TC_BODY(recvmmsg_msghdr_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1741,20 +1651,26 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct mmsghdr msgvec[2];
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msgvec[0], 0, sizeof(msgvec));
+
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
- strncpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], &msgvec[0], nitems(msgvec), 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncpy_heap_end);
-ATF_TC_BODY(strncpy_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msghdr_heap_end);
+ATF_TC_BODY(recvmmsg_msghdr_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1765,20 +1681,26 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct mmsghdr msgvec[2];
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msgvec[0], 0, sizeof(msgvec));
- strncpy(__stack.__buf, src, __len);
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
+
+ recvmmsg(sock[0], &msgvec[0], nitems(msgvec), 0, NULL);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(strncpy_heap_after_end);
-ATF_TC_BODY(strncpy_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(recvmmsg_msghdr_heap_after_end);
+ATF_TC_BODY(recvmmsg_msghdr_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -1791,7 +1713,8 @@
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- char src[__len];
+ int sock[2] = { -1, -1 };
+ struct mmsghdr msgvec[2];
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -1801,11 +1724,16 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- memset(__stack.__buf, 0, __len);
- memset(src, 'A', __len - 1);
- src[__len - 1] = '\0';
+ memset(&msgvec[0], 0, sizeof(msgvec));
+
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
- strncpy(__stack.__buf, src, __len);
+ recvmmsg(sock[0], &msgvec[0], nitems(msgvec), 0, NULL);
_exit(EX_SOFTWARE); /* Should have aborted. */
monitor:
@@ -1834,65 +1762,56 @@
ATF_TP_ADD_TCS(tp)
{
- ATF_TP_ADD_TC(tp, memcpy_before_end);
- ATF_TP_ADD_TC(tp, memcpy_end);
- ATF_TP_ADD_TC(tp, memcpy_heap_before_end);
- ATF_TP_ADD_TC(tp, memcpy_heap_end);
- ATF_TP_ADD_TC(tp, memcpy_heap_after_end);
- ATF_TP_ADD_TC(tp, mempcpy_before_end);
- ATF_TP_ADD_TC(tp, mempcpy_end);
- ATF_TP_ADD_TC(tp, mempcpy_heap_before_end);
- ATF_TP_ADD_TC(tp, mempcpy_heap_end);
- ATF_TP_ADD_TC(tp, mempcpy_heap_after_end);
- ATF_TP_ADD_TC(tp, memmove_before_end);
- ATF_TP_ADD_TC(tp, memmove_end);
- ATF_TP_ADD_TC(tp, memmove_heap_before_end);
- ATF_TP_ADD_TC(tp, memmove_heap_end);
- ATF_TP_ADD_TC(tp, memmove_heap_after_end);
- ATF_TP_ADD_TC(tp, memset_before_end);
- ATF_TP_ADD_TC(tp, memset_end);
- ATF_TP_ADD_TC(tp, memset_heap_before_end);
- ATF_TP_ADD_TC(tp, memset_heap_end);
- ATF_TP_ADD_TC(tp, memset_heap_after_end);
- ATF_TP_ADD_TC(tp, stpcpy_before_end);
- ATF_TP_ADD_TC(tp, stpcpy_end);
- ATF_TP_ADD_TC(tp, stpcpy_heap_before_end);
- ATF_TP_ADD_TC(tp, stpcpy_heap_end);
- ATF_TP_ADD_TC(tp, stpcpy_heap_after_end);
- ATF_TP_ADD_TC(tp, stpncpy_before_end);
- ATF_TP_ADD_TC(tp, stpncpy_end);
- ATF_TP_ADD_TC(tp, stpncpy_heap_before_end);
- ATF_TP_ADD_TC(tp, stpncpy_heap_end);
- ATF_TP_ADD_TC(tp, stpncpy_heap_after_end);
- ATF_TP_ADD_TC(tp, strcat_before_end);
- ATF_TP_ADD_TC(tp, strcat_end);
- ATF_TP_ADD_TC(tp, strcat_heap_before_end);
- ATF_TP_ADD_TC(tp, strcat_heap_end);
- ATF_TP_ADD_TC(tp, strcat_heap_after_end);
- ATF_TP_ADD_TC(tp, strlcat_before_end);
- ATF_TP_ADD_TC(tp, strlcat_end);
- ATF_TP_ADD_TC(tp, strlcat_heap_before_end);
- ATF_TP_ADD_TC(tp, strlcat_heap_end);
- ATF_TP_ADD_TC(tp, strlcat_heap_after_end);
- ATF_TP_ADD_TC(tp, strncat_before_end);
- ATF_TP_ADD_TC(tp, strncat_end);
- ATF_TP_ADD_TC(tp, strncat_heap_before_end);
- ATF_TP_ADD_TC(tp, strncat_heap_end);
- ATF_TP_ADD_TC(tp, strncat_heap_after_end);
- ATF_TP_ADD_TC(tp, strcpy_before_end);
- ATF_TP_ADD_TC(tp, strcpy_end);
- ATF_TP_ADD_TC(tp, strcpy_heap_before_end);
- ATF_TP_ADD_TC(tp, strcpy_heap_end);
- ATF_TP_ADD_TC(tp, strcpy_heap_after_end);
- ATF_TP_ADD_TC(tp, strlcpy_before_end);
- ATF_TP_ADD_TC(tp, strlcpy_end);
- ATF_TP_ADD_TC(tp, strlcpy_heap_before_end);
- ATF_TP_ADD_TC(tp, strlcpy_heap_end);
- ATF_TP_ADD_TC(tp, strlcpy_heap_after_end);
- ATF_TP_ADD_TC(tp, strncpy_before_end);
- ATF_TP_ADD_TC(tp, strncpy_end);
- ATF_TP_ADD_TC(tp, strncpy_heap_before_end);
- ATF_TP_ADD_TC(tp, strncpy_heap_end);
- ATF_TP_ADD_TC(tp, strncpy_heap_after_end);
+ ATF_TP_ADD_TC(tp, getpeername_before_end);
+ ATF_TP_ADD_TC(tp, getpeername_end);
+ ATF_TP_ADD_TC(tp, getpeername_heap_before_end);
+ ATF_TP_ADD_TC(tp, getpeername_heap_end);
+ ATF_TP_ADD_TC(tp, getpeername_heap_after_end);
+ ATF_TP_ADD_TC(tp, getsockname_before_end);
+ ATF_TP_ADD_TC(tp, getsockname_end);
+ ATF_TP_ADD_TC(tp, getsockname_heap_before_end);
+ ATF_TP_ADD_TC(tp, getsockname_heap_end);
+ ATF_TP_ADD_TC(tp, getsockname_heap_after_end);
+ ATF_TP_ADD_TC(tp, recv_before_end);
+ ATF_TP_ADD_TC(tp, recv_end);
+ ATF_TP_ADD_TC(tp, recv_heap_before_end);
+ ATF_TP_ADD_TC(tp, recv_heap_end);
+ ATF_TP_ADD_TC(tp, recv_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvfrom_before_end);
+ ATF_TP_ADD_TC(tp, recvfrom_end);
+ ATF_TP_ADD_TC(tp, recvfrom_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvfrom_heap_end);
+ ATF_TP_ADD_TC(tp, recvfrom_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvfrom_sockaddr_before_end);
+ ATF_TP_ADD_TC(tp, recvfrom_sockaddr_end);
+ ATF_TP_ADD_TC(tp, recvfrom_sockaddr_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvfrom_sockaddr_heap_end);
+ ATF_TP_ADD_TC(tp, recvfrom_sockaddr_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_name_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_name_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_name_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_name_heap_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_name_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_iov_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_iov_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_iov_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_iov_heap_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_iov_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_control_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_control_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_control_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_control_heap_end);
+ ATF_TP_ADD_TC(tp, recvmsg_msg_control_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_before_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_after_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_heap_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msgvec_heap_after_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msghdr_before_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msghdr_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msghdr_heap_before_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msghdr_heap_end);
+ ATF_TP_ADD_TC(tp, recvmmsg_msghdr_heap_after_end);
return (atf_no_error());
}
diff --git a/lib/libc/tests/secure/fortify_stdio_test.c b/lib/libc/tests/secure/fortify_stdio_test.c
--- a/lib/libc/tests/secure/fortify_stdio_test.c
+++ b/lib/libc/tests/secure/fortify_stdio_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_stdlib_test.c b/lib/libc/tests/secure/fortify_stdlib_test.c
--- a/lib/libc/tests/secure/fortify_stdlib_test.c
+++ b/lib/libc/tests/secure/fortify_stdlib_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_string_test.c b/lib/libc/tests/secure/fortify_string_test.c
--- a/lib/libc/tests/secure/fortify_string_test.c
+++ b/lib/libc/tests/secure/fortify_string_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_strings_test.c b/lib/libc/tests/secure/fortify_strings_test.c
--- a/lib/libc/tests/secure/fortify_strings_test.c
+++ b/lib/libc/tests/secure/fortify_strings_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_uio_test.c b/lib/libc/tests/secure/fortify_uio_test.c
--- a/lib/libc/tests/secure/fortify_uio_test.c
+++ b/lib/libc/tests/secure/fortify_uio_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_unistd_test.c b/lib/libc/tests/secure/fortify_unistd_test.c
--- a/lib/libc/tests/secure/fortify_unistd_test.c
+++ b/lib/libc/tests/secure/fortify_unistd_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/fortify_wchar_test.c b/lib/libc/tests/secure/fortify_wchar_test.c
--- a/lib/libc/tests/secure/fortify_wchar_test.c
+++ b/lib/libc/tests/secure/fortify_wchar_test.c
@@ -7,6 +7,7 @@
#include <sys/random.h>
#include <sys/resource.h>
#include <sys/select.h>
+#include <sys/socket.h>
#include <sys/time.h>
#include <sys/uio.h>
#include <sys/wait.h>
@@ -66,6 +67,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libc/tests/secure/generate-fortify-tests.lua b/lib/libc/tests/secure/generate-fortify-tests.lua
--- a/lib/libc/tests/secure/generate-fortify-tests.lua
+++ b/lib/libc/tests/secure/generate-fortify-tests.lua
@@ -65,6 +65,7 @@
"sys/random.h",
"sys/resource.h",
"sys/select.h",
+ "sys/socket.h",
"sys/time.h",
"sys/uio.h",
"sys/wait.h",
@@ -115,6 +116,19 @@
replace_stdin();
]]
+local socket_stackvars = "\tint sock[2] = { -1, -1 };\n"
+local recvfrom_sockaddr_stackvars = socket_stackvars .. [[
+ char data[16];
+ socklen_t socklen;
+]]
+local recvmsg_stackvars = socket_stackvars .. "\tstruct msghdr msg;\n"
+local socket_init = [[
+ new_socket(sock);
+]]
+local socket_socklen_init = socket_init .. [[
+ socklen = __len;
+]]
+
local stdio_init = [[
replace_stdin();
]]
@@ -200,6 +214,187 @@
},
},
},
+ socket = {
+ -- <sys/socket.h>
+ {
+ func = "getpeername",
+ buftype = "struct sockaddr",
+ bufsize = "sizeof(struct sockaddr)",
+ arguments = {
+ "sock[0]",
+ "__buf",
+ "&socklen",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = socket_stackvars .. "\tsocklen_t socklen;",
+ init = socket_socklen_init,
+ uses_len = true,
+ },
+ {
+ func = "getsockname",
+ buftype = "struct sockaddr",
+ bufsize = "sizeof(struct sockaddr)",
+ arguments = {
+ "sock[0]",
+ "__buf",
+ "&socklen",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = socket_stackvars .. "\tsocklen_t socklen;",
+ init = socket_socklen_init,
+ uses_len = true,
+ },
+ {
+ func = "recv",
+ arguments = {
+ "sock[0]",
+ "__buf",
+ "__len",
+ "0",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = socket_stackvars,
+ init = socket_init,
+ },
+ {
+ func = "recvfrom",
+ arguments = {
+ "sock[0]",
+ "__buf",
+ "__len",
+ "0",
+ "NULL",
+ "NULL",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = socket_stackvars,
+ init = socket_init,
+ },
+ {
+ func = "recvfrom",
+ variant = "sockaddr",
+ buftype = "struct sockaddr",
+ bufsize = "sizeof(struct sockaddr)",
+ arguments = {
+ "sock[0]",
+ "data",
+ "sizeof(data)",
+ "0",
+ "__buf",
+ "&socklen",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = recvfrom_sockaddr_stackvars,
+ init = socket_socklen_init,
+ uses_len = true,
+ },
+ {
+ func = "recvmsg",
+ variant = "msg_name",
+ buftype = "struct sockaddr",
+ bufsize = "sizeof(struct sockaddr)",
+ arguments = {
+ "sock[0]",
+ "&msg",
+ "0",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = recvmsg_stackvars,
+ init = [[
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_name = BUF;
+ msg.msg_namelen = __len;
+]],
+ uses_len = true,
+ },
+ {
+ func = "recvmsg",
+ variant = "msg_iov",
+ arguments = {
+ "sock[0]",
+ "&msg",
+ "0",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = recvmsg_stackvars .. "\tstruct iovec iov[2];\n",
+ init = [[
+ memset(&msg, 0, sizeof(msg));
+ memset(&iov[0], 0, sizeof(iov));
+
+ /*
+ * We position the buffer second just so that we can confirm that the
+ * fortification bits are traversing the iovec correctly.
+ */
+ iov[1].iov_base = BUF;
+ iov[1].iov_len = __len;
+
+ msg.msg_iov = &iov[0];
+ msg.msg_iovlen = nitems(iov);
+]],
+ uses_len = true,
+ },
+ {
+ func = "recvmsg",
+ variant = "msg_control",
+ bufsize = "CMSG_SPACE(sizeof(int))",
+ arguments = {
+ "sock[0]",
+ "&msg",
+ "0",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = recvmsg_stackvars,
+ init = [[
+ memset(&msg, 0, sizeof(msg));
+
+ msg.msg_control = BUF;
+ msg.msg_controllen = __len;
+]],
+ uses_len = true,
+ },
+ {
+ func = "recvmmsg",
+ variant = "msgvec",
+ buftype = "struct mmsghdr[]",
+ bufsize = "2",
+ arguments = {
+ "sock[0]",
+ "__buf",
+ "__len",
+ "0",
+ "NULL",
+ },
+ stackvars = socket_stackvars,
+ },
+ {
+ -- We'll assume that recvmsg is covering msghdr
+ -- validation thoroughly enough, we'll just try tossing
+ -- an error in the second element of a msgvec to try and
+ -- make sure that each one is being validated.
+ func = "recvmmsg",
+ variant = "msghdr",
+ arguments = {
+ "sock[0]",
+ "&msgvec[0]",
+ "nitems(msgvec)",
+ "0",
+ "NULL",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = socket_stackvars .. "\tstruct mmsghdr msgvec[2];\n",
+ init = [[
+ memset(&msgvec[0], 0, sizeof(msgvec));
+
+ /*
+ * Same as above, make sure fortification isn't ignoring n > 1 elements
+ * of the msgvec.
+ */
+ msgvec[1].msg_hdr.msg_control = BUF;
+ msgvec[1].msg_hdr.msg_controllen = __len;
+]],
+ uses_len = true,
+ },
+ },
uio = {
-- <sys/uio.h>
{
@@ -1207,6 +1402,50 @@
return (linkname);
}
+/*
+ * For our purposes, first descriptor will be the reader; we'll send both
+ * raw data and a control message over it so that the result can be used for
+ * any of our recv*() tests.
+ */
+static void __unused
+new_socket(int sock[2])
+{
+ unsigned char ctrl[CMSG_SPACE(sizeof(int))] = { 0 };
+ static char sockbuf[256];
+ ssize_t rv;
+ size_t total = 0;
+ struct msghdr hdr = { 0 };
+ struct cmsghdr *cmsg;
+ int error, fd;
+
+ error = socketpair(AF_UNIX, SOCK_STREAM, 0, sock);
+ ATF_REQUIRE(error == 0);
+
+ while (total != sizeof(sockbuf)) {
+ rv = send(sock[1], &sockbuf[total], sizeof(sockbuf) - total, 0);
+
+ ATF_REQUIRE_MSG(rv > 0,
+ "expected bytes sent, got %zd with %zu left (size %zu, total %zu)",
+ rv, sizeof(sockbuf) - total, sizeof(sockbuf), total);
+ ATF_REQUIRE_MSG(total + (size_t)rv <= sizeof(sockbuf),
+ "%zd exceeds total %zu", rv, sizeof(sockbuf));
+ total += rv;
+ }
+
+ hdr.msg_control = ctrl;
+ hdr.msg_controllen = sizeof(ctrl);
+
+ cmsg = CMSG_FIRSTHDR(&hdr);
+ cmsg->cmsg_level = SOL_SOCKET;
+ cmsg->cmsg_type = SCM_RIGHTS;
+ cmsg->cmsg_len = CMSG_LEN(sizeof(fd));
+ fd = STDIN_FILENO;
+ memcpy(CMSG_DATA(cmsg), &fd, sizeof(fd));
+
+ error = sendmsg(sock[1], &hdr, 0);
+ ATF_REQUIRE(error != -1);
+}
+
/*
* Constructs a tmpfile that we can use for testing read(2) and friends.
*/
diff --git a/lib/libsys/recvmmsg.c b/lib/libsys/recvmmsg.c
--- a/lib/libsys/recvmmsg.c
+++ b/lib/libsys/recvmmsg.c
@@ -32,11 +32,12 @@
#include <errno.h>
#include <poll.h>
#include <stddef.h>
+#include <ssp/ssp.h>
#include "libc_private.h"
ssize_t
-recvmmsg(int s, struct mmsghdr *__restrict msgvec, size_t vlen, int flags,
- const struct timespec *__restrict timeout)
+__ssp_real(recvmmsg)(int s, struct mmsghdr *__restrict msgvec, size_t vlen,
+ int flags, const struct timespec *__restrict timeout)
{
struct pollfd pfd[1];
size_t i, rcvd;
diff --git a/sys/sys/socket.h b/sys/sys/socket.h
--- a/sys/sys/socket.h
+++ b/sys/sys/socket.h
@@ -670,6 +670,10 @@
};
#endif /* __BSD_VISIBLE */
+#if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/socket.h>
+#endif
+
#ifndef _KERNEL
#include <sys/cdefs.h>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, Jul 1, 2:04 AM (11 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
34537233
Default Alt Text
D45686.diff (84 KB)
Attached To
Mode
D45686: include: ssp: fortify <sys/socket.h>
Attached
Detach File
Event Timeline
Log In to Comment