Page MenuHomeFreeBSD

D45679.id140080.diff
No OneTemporary

D45679.id140080.diff

diff --git a/include/ssp/ssp.h b/include/ssp/ssp.h
--- a/include/ssp/ssp.h
+++ b/include/ssp/ssp.h
@@ -67,21 +67,25 @@
#define __ssp_bos0(ptr) __builtin_object_size(ptr, 0)
#define __ssp_check(buf, len, bos) \
- if (bos(buf) != (size_t)-1 && len > bos(buf)) \
+ if (bos(buf) != (size_t)-1 && (size_t)len > bos(buf)) \
__chk_fail()
-#define __ssp_redirect_raw(rtype, fun, symbol, args, call, cond, bos) \
+
+#define __ssp_redirect_raw_impl(rtype, fun, symbol, args) \
rtype __ssp_real_(fun) args __RENAME(symbol); \
__ssp_inline rtype fun args __RENAME(__ssp_protected_ ## fun); \
-__ssp_inline rtype fun args { \
+__ssp_inline rtype fun args
+
+#define __ssp_redirect_raw(rtype, fun, symbol, args, call, cond, bos, len) \
+__ssp_redirect_raw_impl(rtype, fun, symbol, args) { \
if (cond) \
- __ssp_check(__buf, __len, bos); \
+ __ssp_check(__buf, len, bos); \
return __ssp_real_(fun) call; \
}
#define __ssp_redirect(rtype, fun, args, call) \
- __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos)
+ __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos, __len)
#define __ssp_redirect0(rtype, fun, args, call) \
- __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0)
+ __ssp_redirect_raw(rtype, fun, fun, args, call, 1, __ssp_bos0, __len)
/*
* Take caution when using __ssp_overlap! Don't use it in contexts where we
diff --git a/include/ssp/stdio.h b/include/ssp/stdio.h
--- a/include/ssp/stdio.h
+++ b/include/ssp/stdio.h
@@ -37,6 +37,24 @@
#include <ssp/ssp.h>
__BEGIN_DECLS
+#if __SSP_FORTIFY_LEVEL > 0
+#if __POSIX_VISIBLE
+__ssp_redirect_raw(char *, ctermid, ctermid, (char *__buf), (__buf),
+ __buf != NULL, __ssp_bos, L_ctermid);
+#if __BSD_VISIBLE
+__ssp_redirect_raw(char *, ctermid_r, ctermid_r, (char *__buf), (__buf),
+ __buf != NULL, __ssp_bos, L_ctermid);
+#endif /* __BSD_VISIBLE */
+#endif /* __POSIX_VISIBLE */
+__ssp_redirect(size_t, fread, (void *__restrict __buf, size_t __len,
+ size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp));
+__ssp_redirect(size_t, fread_unlocked, (void *__restrict __buf, size_t __len,
+ size_t __nmemb, FILE *__restrict __fp), (__buf, __len, __nmemb, __fp));
+__ssp_redirect(char *, gets_s, (char *__buf, rsize_t __len), (__buf, __len));
+__ssp_redirect_raw(char *, tmpnam, tmpnam, (char *__buf), (__buf), 1,
+ __ssp_bos, L_tmpnam);
+#endif
+
int __sprintf_chk(char *__restrict, int, size_t, const char *__restrict, ...)
__printflike(4, 5);
int __vsprintf_chk(char *__restrict, int, size_t, const char *__restrict,
diff --git a/include/ssp/string.h b/include/ssp/string.h
--- a/include/ssp/string.h
+++ b/include/ssp/string.h
@@ -45,7 +45,9 @@
char *__strcat_chk(char *, const char *, size_t);
char *__strcpy_chk(char *, const char *, size_t);
char *__strncat_chk(char *, const char *, size_t, size_t);
+size_t __strlcat_chk(char *, const char *, size_t, size_t);
char *__strncpy_chk(char *, const char *, size_t, size_t);
+size_t __strlcpy_chk(char *, const char *, size_t, size_t);
__END_DECLS
#if __SSP_FORTIFY_LEVEL > 0
@@ -110,8 +112,24 @@
__ssp_bos_icheck3_restrict(stpncpy, char *, const char *)
__ssp_bos_icheck2_restrict(strcpy, char *, const char *)
__ssp_bos_icheck2_restrict(strcat, char *, const char *)
+__ssp_redirect0(int, strerror_r, (int __errnum, char *__buf, size_t __len),
+ (__errnum, __buf, __len));
__ssp_bos_icheck3_restrict(strncpy, char *, const char *)
__ssp_bos_icheck3_restrict(strncat, char *, const char *)
+
+__ssp_redirect_raw_impl(void *, mempcpy, mempcpy,
+ (void *__restrict buf, const void *__restrict src, size_t len))
+{
+ const size_t slen = __ssp_bos(buf);
+
+ if (len > slen)
+ __chk_fail();
+
+ if (__ssp_overlap((const char *)src, (const char *)buf, len))
+ __chk_fail();
+
+ return (__ssp_real(mempcpy)(buf, src, len));
+}
__END_DECLS
#define memcpy(dst, src, len) __ssp_bos_check3(memcpy, dst, src, len)
@@ -122,7 +140,11 @@
#define stpncpy(dst, src, len) __ssp_bos_check3(stpncpy, dst, src, len)
#define strcpy(dst, src) __ssp_bos_check2(strcpy, dst, src)
#define strcat(dst, src) __ssp_bos_check2(strcat, dst, src)
+#define strlcpy(dst, src, dstlen) \
+ __strlcpy_chk(dst, src, dstlen, __ssp_bos(dst))
#define strncpy(dst, src, len) __ssp_bos_check3(strncpy, dst, src, len)
+#define strlcat(dst, src, dstlen) \
+ __strlcat_chk(dst, src, dstlen, __ssp_bos(dst))
#define strncat(dst, src, len) __ssp_bos_check3(strncat, dst, src, len)
#endif /* __SSP_FORTIFY_LEVEL > 0 */
diff --git a/include/ssp/strings.h b/include/ssp/strings.h
--- a/include/ssp/strings.h
+++ b/include/ssp/strings.h
@@ -63,5 +63,10 @@
#define bzero(dst, len) _ssp_bzero(__ssp_var(dstv), dst, __ssp_var(lenv), len)
+__BEGIN_DECLS
+__ssp_redirect(void, explicit_bzero, (void *__buf, size_t __len),
+ (__buf, __len));
+__END_DECLS
+
#endif /* __SSP_FORTIFY_LEVEL > 0 */
#endif /* _SSP_STRINGS_H_ */
diff --git a/include/ssp/unistd.h b/include/ssp/unistd.h
--- a/include/ssp/unistd.h
+++ b/include/ssp/unistd.h
@@ -43,14 +43,46 @@
#define _FORTIFY_SOURCE_read read
#endif
-__ssp_redirect0(ssize_t, _FORTIFY_SOURCE_read, (int __fd, void *__buf,
+__ssp_inline size_t
+__ssp_gid_bos(const void *ptr)
+{
+ size_t ptrsize = __ssp_bos(ptr);
+
+ if (ptrsize == (size_t)-1)
+ return (ptrsize);
+
+ return (ptrsize / sizeof(gid_t));
+}
+
+__ssp_redirect_raw(int, getgrouplist, getgrouplist,
+ (const char *__name, gid_t __base, gid_t *__buf, int *__lenp),
+ (__name, __base, __buf, __lenp), 1, __ssp_gid_bos, *__lenp);
+
+__ssp_redirect_raw(int, getgroups, getgroups, (int __len, gid_t *__buf),
+ (__len, __buf), 1, __ssp_gid_bos, __len);
+
+__ssp_redirect(int, getloginclass, (char *__buf, size_t __len),
+ (__buf, __len));
+
+__ssp_redirect(ssize_t, _FORTIFY_SOURCE_read, (int __fd, void *__buf,
size_t __len), (__fd, __buf, __len));
+__ssp_redirect(ssize_t, pread, (int __fd, void *__buf, size_t __len,
+ off_t __offset), (__fd, __buf, __len, __offset));
__ssp_redirect(ssize_t, readlink, (const char *__restrict __path, \
char *__restrict __buf, size_t __len), (__path, __buf, __len));
+__ssp_redirect(ssize_t, readlinkat, (int __fd, const char *__restrict __path,
+ char *__restrict __buf, size_t __len), (__fd, __path, __buf, __len));
__ssp_redirect_raw(char *, getcwd, getcwd, (char *__buf, size_t __len),
- (__buf, __len), __buf != 0, __ssp_bos);
+ (__buf, __len), __buf != 0, __ssp_bos, __len);
+
+__ssp_redirect(int, getdomainname, (char *__buf, int __len), (__buf, __len));
+__ssp_redirect(int, getentropy, (void *__buf, size_t __len), (__buf, __len));
+__ssp_redirect(int, gethostname, (char *__buf, size_t __len), (__buf, __len));
+__ssp_redirect(int, getlogin_r, (char *__buf, size_t __len), (__buf, __len));
+__ssp_redirect(int, ttyname_r, (int __fd, char *__buf, size_t __len),
+ (__fd, __buf, __len));
__END_DECLS
diff --git a/include/stdio.h b/include/stdio.h
--- a/include/stdio.h
+++ b/include/stdio.h
@@ -238,6 +238,21 @@
#define stdout __stdoutp
#define stderr __stderrp
+/*
+ * Functions defined in all versions of POSIX 1003.1.
+ */
+#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 199506)
+#define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, legacy */
+#endif
+
+#if __POSIX_VISIBLE
+#define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */
+#endif /* __POSIX_VISIBLE */
+
+#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/stdio.h>
+#endif
+
__BEGIN_DECLS
#ifdef _XLOCALE_H_
#include <xlocale/_stdio.h>
@@ -252,7 +267,7 @@
int fflush(FILE *);
int fgetc(FILE *);
int fgetpos(FILE * __restrict, fpos_t * __restrict);
-char *fgets(char * __restrict, int, FILE * __restrict);
+char *(fgets)(char * __restrict, int, FILE * __restrict);
FILE *fopen(const char * __restrict, const char * __restrict);
int fprintf(FILE * __restrict, const char * __restrict, ...);
int fputc(int, FILE *);
@@ -280,7 +295,7 @@
int scanf(const char * __restrict, ...);
void setbuf(FILE * __restrict, char * __restrict);
int setvbuf(FILE * __restrict, char * __restrict, int, size_t);
-int sprintf(char * __restrict, const char * __restrict, ...);
+int (sprintf)(char * __restrict, const char * __restrict, ...);
int sscanf(const char * __restrict, const char * __restrict, ...);
FILE *tmpfile(void);
char *tmpnam(char *);
@@ -288,13 +303,13 @@
int vfprintf(FILE * __restrict, const char * __restrict,
__va_list);
int vprintf(const char * __restrict, __va_list);
-int vsprintf(char * __restrict, const char * __restrict,
+int (vsprintf)(char * __restrict, const char * __restrict,
__va_list);
#if __ISO_C_VISIBLE >= 1999 || __POSIX_VISIBLE >= 199506
-int snprintf(char * __restrict, size_t, const char * __restrict,
+int (snprintf)(char * __restrict, size_t, const char * __restrict,
...) __printflike(3, 4);
-int vsnprintf(char * __restrict, size_t, const char * __restrict,
+int (vsnprintf)(char * __restrict, size_t, const char * __restrict,
__va_list) __printflike(3, 0);
#endif
#if __ISO_C_VISIBLE >= 1999
@@ -305,16 +320,7 @@
__scanflike(2, 0);
#endif
-/*
- * Functions defined in all versions of POSIX 1003.1.
- */
-#if __BSD_VISIBLE || (__POSIX_VISIBLE && __POSIX_VISIBLE <= 199506)
-#define L_cuserid 17 /* size for cuserid(3); MAXLOGNAME, legacy */
-#endif
-
#if __POSIX_VISIBLE
-#define L_ctermid 1024 /* size for ctermid(3); PATH_MAX */
-
char *ctermid(char *);
FILE *fdopen(int, const char *);
int fileno(FILE *);
@@ -530,7 +536,4 @@
__END_DECLS
__NULLABILITY_PRAGMA_POP
-#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
-#include <ssp/stdio.h>
-#endif
#endif /* !_STDIO_H_ */
diff --git a/include/string.h b/include/string.h
--- a/include/string.h
+++ b/include/string.h
@@ -49,6 +49,10 @@
#define _SIZE_T_DECLARED
#endif
+#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/string.h>
+#endif
+
__BEGIN_DECLS
#if __XSI_VISIBLE >= 600
void *memccpy(void * __restrict, const void * __restrict, int, size_t);
@@ -58,23 +62,23 @@
void *memrchr(const void *, int, size_t) __pure;
#endif
int memcmp(const void *, const void *, size_t) __pure;
-void *memcpy(void * __restrict, const void * __restrict, size_t);
+void *(memcpy)(void * __restrict, const void * __restrict, size_t);
#if __BSD_VISIBLE
void *memmem(const void *, size_t, const void *, size_t) __pure;
#endif
-void *memmove(void *, const void *, size_t);
+void *(memmove)(void *, const void *, size_t);
#if __BSD_VISIBLE
void *mempcpy(void * __restrict, const void * __restrict, size_t);
#endif
-void *memset(void *, int, size_t);
+void *(memset)(void *, int, size_t);
#if __POSIX_VISIBLE >= 200809
-char *stpcpy(char * __restrict, const char * __restrict);
-char *stpncpy(char * __restrict, const char * __restrict, size_t);
+char *(stpcpy)(char * __restrict, const char * __restrict);
+char *(stpncpy)(char * __restrict, const char * __restrict, size_t);
#endif
#if __BSD_VISIBLE
char *strcasestr(const char *, const char *) __pure;
#endif
-char *strcat(char * __restrict, const char * __restrict);
+char *(strcat)(char * __restrict, const char * __restrict);
char *strchr(const char *, int) __pure;
#if __BSD_VISIBLE
char *strchrnul(const char*, int) __pure;
@@ -82,7 +86,7 @@
#endif
int strcmp(const char *, const char *) __pure;
int strcoll(const char *, const char *);
-char *strcpy(char * __restrict, const char * __restrict);
+char *(strcpy)(char * __restrict, const char * __restrict);
size_t strcspn(const char *, const char *) __pure;
#if __POSIX_VISIBLE >= 200112 || __XSI_VISIBLE
char *strdup(const char *) __malloc_like;
@@ -92,8 +96,8 @@
int strerror_r(int, char *, size_t);
#endif
#if __BSD_VISIBLE
-size_t strlcat(char * __restrict, const char * __restrict, size_t);
-size_t strlcpy(char * __restrict, const char * __restrict, size_t);
+size_t (strlcat)(char * __restrict, const char * __restrict, size_t);
+size_t (strlcpy)(char * __restrict, const char * __restrict, size_t);
#endif
size_t strlen(const char *) __pure;
#if __BSD_VISIBLE
@@ -105,9 +109,9 @@
void strmode(mode_t, char *);
#endif
-char *strncat(char * __restrict, const char * __restrict, size_t);
+char *(strncat)(char * __restrict, const char * __restrict, size_t);
int strncmp(const char *, const char *, size_t) __pure;
-char *strncpy(char * __restrict, const char * __restrict, size_t);
+char *(strncpy)(char * __restrict, const char * __restrict, size_t);
#if __POSIX_VISIBLE >= 200809
char *strndup(const char *, size_t) __malloc_like;
size_t strnlen(const char *, size_t) __pure;
@@ -168,7 +172,4 @@
#endif /* __EXT1_VISIBLE */
__END_DECLS
-#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
-#include <ssp/string.h>
-#endif
#endif /* _STRING_H_ */
diff --git a/include/strings.h b/include/strings.h
--- a/include/strings.h
+++ b/include/strings.h
@@ -37,11 +37,15 @@
#define _SIZE_T_DECLARED
#endif
+#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
+#include <ssp/strings.h>
+#endif
+
__BEGIN_DECLS
#if __BSD_VISIBLE || __POSIX_VISIBLE <= 200112
int bcmp(const void *, const void *, size_t) __pure; /* LEGACY */
-void bcopy(const void *, void *, size_t); /* LEGACY */
-void bzero(void *, size_t); /* LEGACY */
+void (bcopy)(const void *, void *, size_t); /* LEGACY */
+void (bzero)(void *, size_t); /* LEGACY */
#endif
#if __BSD_VISIBLE
void explicit_bzero(void *, size_t);
@@ -68,7 +72,4 @@
#endif
__END_DECLS
-#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
-#include <ssp/strings.h>
-#endif
#endif /* _STRINGS_H_ */
diff --git a/lib/libc/amd64/string/strlcat.c b/lib/libc/amd64/string/strlcat.c
--- a/lib/libc/amd64/string/strlcat.c
+++ b/lib/libc/amd64/string/strlcat.c
@@ -8,6 +8,8 @@
#include <string.h>
+#undef strlcat /* FORTIFY_SOURCE */
+
void *__memchr(const void *, int, size_t);
size_t __strlcpy(char *restrict, const char *restrict, size_t);
diff --git a/lib/libc/gen/ctermid.c b/lib/libc/gen/ctermid.c
--- a/lib/libc/gen/ctermid.c
+++ b/lib/libc/gen/ctermid.c
@@ -34,11 +34,12 @@
#include <paths.h>
#include <stdio.h>
#include <string.h>
+#include <ssp/ssp.h>
#define LEN_PATH_DEV (sizeof(_PATH_DEV) - 1)
char *
-ctermid(char *s)
+__ssp_real(ctermid)(char *s)
{
static char def[sizeof(_PATH_DEV) + SPECNAMELEN];
struct stat sb;
@@ -62,7 +63,7 @@
}
char *
-ctermid_r(char *s)
+__ssp_real(ctermid_r)(char *s)
{
return (s != NULL ? ctermid(s) : NULL);
diff --git a/lib/libc/gen/getdomainname.c b/lib/libc/gen/getdomainname.c
--- a/lib/libc/gen/getdomainname.c
+++ b/lib/libc/gen/getdomainname.c
@@ -33,9 +33,10 @@
#include <sys/sysctl.h>
#include <unistd.h>
+#include <ssp/ssp.h>
int
-getdomainname(char *name, int namelen)
+__ssp_real(getdomainname)(char *name, int namelen)
{
int mib[2];
size_t size;
diff --git a/lib/libc/gen/getentropy.c b/lib/libc/gen/getentropy.c
--- a/lib/libc/gen/getentropy.c
+++ b/lib/libc/gen/getentropy.c
@@ -105,7 +105,7 @@
}
int
-getentropy(void *buf, size_t buflen)
+__ssp_real(getentropy)(void *buf, size_t buflen)
{
ssize_t rd;
bool have_getrandom;
diff --git a/lib/libc/gen/getgrouplist.c b/lib/libc/gen/getgrouplist.c
--- a/lib/libc/gen/getgrouplist.c
+++ b/lib/libc/gen/getgrouplist.c
@@ -37,11 +37,12 @@
#include <grp.h>
#include <string.h>
#include <unistd.h>
+#include <ssp/ssp.h>
extern int __getgroupmembership(const char *, gid_t, gid_t *, int, int *);
int
-getgrouplist(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt)
+__ssp_real(getgrouplist)(const char *uname, gid_t agroup, gid_t *groups, int *grpcnt)
{
return __getgroupmembership(uname, agroup, groups, *grpcnt, grpcnt);
}
diff --git a/lib/libc/gen/gethostname.c b/lib/libc/gen/gethostname.c
--- a/lib/libc/gen/gethostname.c
+++ b/lib/libc/gen/gethostname.c
@@ -36,7 +36,7 @@
#include <unistd.h>
int
-gethostname(char *name, size_t namelen)
+__ssp_real(gethostname)(char *name, size_t namelen)
{
int mib[2];
diff --git a/lib/libc/gen/getlogin.c b/lib/libc/gen/getlogin.c
--- a/lib/libc/gen/getlogin.c
+++ b/lib/libc/gen/getlogin.c
@@ -54,7 +54,7 @@
}
int
-getlogin_r(char *logname, size_t namelen)
+__ssp_real(getlogin_r)(char *logname, size_t namelen)
{
char tmpname[MAXLOGNAME];
int len;
diff --git a/lib/libc/gen/ttyname.c b/lib/libc/gen/ttyname.c
--- a/lib/libc/gen/ttyname.c
+++ b/lib/libc/gen/ttyname.c
@@ -53,7 +53,7 @@
static int ttyname_keycreated = 0;
int
-ttyname_r(int fd, char *buf, size_t len)
+__ssp_real(ttyname_r)(int fd, char *buf, size_t len)
{
size_t used;
diff --git a/lib/libc/secure/Makefile.inc b/lib/libc/secure/Makefile.inc
--- a/lib/libc/secure/Makefile.inc
+++ b/lib/libc/secure/Makefile.inc
@@ -6,8 +6,8 @@
# _FORTIFY_SOURCE
SRCS+= fgets_chk.c memcpy_chk.c memmove_chk.c memset_chk.c \
snprintf_chk.c sprintf_chk.c stpcpy_chk.c stpncpy_chk.c \
- strcat_chk.c strcpy_chk.c strncat_chk.c strncpy_chk.c \
- vsnprintf_chk.c vsprintf_chk.c
+ strcat_chk.c strcpy_chk.c strlcat_chk.c strncat_chk.c strlcpy_chk.c \
+ strncpy_chk.c vsnprintf_chk.c vsprintf_chk.c
CFLAGS.snprintf_chk.c+= -Wno-unused-parameter
CFLAGS.sprintf_chk.c+= -Wno-unused-parameter
diff --git a/lib/libc/secure/Symbol.map b/lib/libc/secure/Symbol.map
--- a/lib/libc/secure/Symbol.map
+++ b/lib/libc/secure/Symbol.map
@@ -15,7 +15,9 @@
__stpncpy_chk;
__strcat_chk;
__strcpy_chk;
+ __strlcat_chk;
__strncat_chk;
+ __strlcpy_chk;
__strncpy_chk;
__vsnprintf_chk;
__vsprintf_chk;
diff --git a/lib/libc/string/strlcat.c b/lib/libc/secure/strlcat_chk.c
copy from lib/libc/string/strlcat.c
copy to lib/libc/secure/strlcat_chk.c
--- a/lib/libc/string/strlcat.c
+++ b/lib/libc/secure/strlcat_chk.c
@@ -1,6 +1,8 @@
/* $OpenBSD: strlcat.c,v 1.15 2015/03/02 21:41:08 millert Exp $ */
/*
+ * SPDX-License-Identifier: ISC
+ *
* Copyright (c) 1998, 2015 Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
@@ -16,9 +18,11 @@
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
-#include <sys/types.h>
+#include <stdio.h>
#include <string.h>
+#include <ssp/string.h>
+
/*
* Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most dsize-1 characters
@@ -27,29 +31,42 @@
* If retval >= dsize, truncation occurred.
*/
size_t
-strlcat(char * __restrict dst, const char * __restrict src, size_t dsize)
+__strlcat_chk(char * __restrict dst, const char * __restrict src, size_t dsize,
+ size_t dbufsize)
{
const char *odst = dst;
const char *osrc = src;
size_t n = dsize;
size_t dlen;
+ if (dsize > dbufsize)
+ __chk_fail();
+
/* Find the end of dst and adjust bytes left but don't go past end. */
- while (n-- != 0 && *dst != '\0')
+ while (n-- != 0 && *dst != '\0') {
+ if (dbufsize-- == 0)
+ __chk_fail();
dst++;
+ }
+
dlen = dst - odst;
n = dsize - dlen;
if (n-- == 0)
- return(dlen + strlen(src));
+ return (dlen + strlen(src));
while (*src != '\0') {
if (n != 0) {
+ if (dbufsize-- == 0)
+ __chk_fail();
*dst++ = *src;
n--;
}
+
src++;
}
- *dst = '\0';
- return(dlen + (src - osrc)); /* count does not include NUL */
+ if (dbufsize-- == 0)
+ __chk_fail();
+ *dst = '\0';
+ return (dlen + (src - osrc)); /* count does not include NUL */
}
diff --git a/lib/libc/string/strlcpy.c b/lib/libc/secure/strlcpy_chk.c
copy from lib/libc/string/strlcpy.c
copy to lib/libc/secure/strlcpy_chk.c
--- a/lib/libc/string/strlcpy.c
+++ b/lib/libc/secure/strlcpy_chk.c
@@ -19,20 +19,29 @@
#include <sys/types.h>
#include <string.h>
+#include <ssp/string.h>
+#undef strlcpy
+
/*
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
* Returns strlen(src); if retval >= dsize, truncation occurred.
*/
size_t
-strlcpy(char * __restrict dst, const char * __restrict src, size_t dsize)
+__strlcpy_chk(char * __restrict dst, const char * __restrict src, size_t dsize,
+ size_t dbufsize)
{
const char *osrc = src;
size_t nleft = dsize;
+ if (dsize > dbufsize)
+ __chk_fail();
+
/* Copy as many bytes as will fit. */
if (nleft != 0) {
while (--nleft != 0) {
+ if (dbufsize-- == 0)
+ __chk_fail();
if ((*dst++ = *src++) == '\0')
break;
}
diff --git a/lib/libc/stdio/fread.c b/lib/libc/stdio/fread.c
--- a/lib/libc/stdio/fread.c
+++ b/lib/libc/stdio/fread.c
@@ -37,6 +37,7 @@
#include <stdint.h>
#include <stdio.h>
#include <string.h>
+#include <ssp/ssp.h>
#include "un-namespace.h"
#include "local.h"
#include "libc_private.h"
@@ -46,7 +47,7 @@
*/
size_t
-fread(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
+__ssp_real(fread)(void * __restrict buf, size_t size, size_t count, FILE * __restrict fp)
{
size_t ret;
diff --git a/lib/libc/stdio/gets_s.c b/lib/libc/stdio/gets_s.c
--- a/lib/libc/stdio/gets_s.c
+++ b/lib/libc/stdio/gets_s.c
@@ -39,6 +39,7 @@
#include <unistd.h>
#include <stdint.h>
#include <stdio.h>
+#include <ssp/ssp.h>
#include "un-namespace.h"
#include "libc_private.h"
#include "local.h"
@@ -77,7 +78,7 @@
/* ISO/IEC 9899:2011 K.3.7.4.1 */
char *
-gets_s(char *buf, rsize_t n)
+__ssp_real(gets_s)(char *buf, rsize_t n)
{
char *ret;
if (buf == NULL) {
diff --git a/lib/libc/stdio/tmpnam.c b/lib/libc/stdio/tmpnam.c
--- a/lib/libc/stdio/tmpnam.c
+++ b/lib/libc/stdio/tmpnam.c
@@ -36,6 +36,7 @@
#include <stdio.h>
#include <unistd.h>
+#include <ssp/ssp.h>
__warn_references(tmpnam,
"warning: tmpnam() possibly used unsafely; consider using mkstemp()");
@@ -43,7 +44,7 @@
extern char *_mktemp(char *);
char *
-tmpnam(char *s)
+__ssp_real(tmpnam)(char *s)
{
static u_long tmpcount;
static char buf[L_tmpnam];
diff --git a/lib/libc/string/mempcpy.c b/lib/libc/string/mempcpy.c
--- a/lib/libc/string/mempcpy.c
+++ b/lib/libc/string/mempcpy.c
@@ -29,9 +29,11 @@
*/
#include <string.h>
+#include <ssp/ssp.h>
void *
-mempcpy(void *__restrict dst, const void *__restrict src, size_t len)
+__ssp_real(mempcpy)(void *__restrict dst, const void *__restrict src,
+ size_t len)
{
return ((char *)memcpy(dst, src, len) + len);
}
diff --git a/lib/libc/string/strerror.c b/lib/libc/string/strerror.c
--- a/lib/libc/string/strerror.c
+++ b/lib/libc/string/strerror.c
@@ -38,6 +38,8 @@
#include <string.h>
#include <stdio.h>
+#include <ssp/ssp.h>
+
#include "errlst.h"
#include "../locale/xlocale_private.h"
#include "libc_private.h"
@@ -114,7 +116,7 @@
}
int
-strerror_r(int errnum, char *strerrbuf, size_t buflen)
+__ssp_real(strerror_r)(int errnum, char *strerrbuf, size_t buflen)
{
return (__strerror_rl(errnum, strerrbuf, buflen, __get_locale()));
}
diff --git a/lib/libc/string/strlcat.c b/lib/libc/string/strlcat.c
--- a/lib/libc/string/strlcat.c
+++ b/lib/libc/string/strlcat.c
@@ -19,6 +19,8 @@
#include <sys/types.h>
#include <string.h>
+#undef strlcat /* FORTIFY_SOURCE */
+
/*
* Appends src to string dst of size dsize (unlike strncat, dsize is the
* full size of dst, not space left). At most dsize-1 characters
diff --git a/lib/libc/string/strlcpy.c b/lib/libc/string/strlcpy.c
--- a/lib/libc/string/strlcpy.c
+++ b/lib/libc/string/strlcpy.c
@@ -19,6 +19,8 @@
#include <sys/types.h>
#include <string.h>
+#undef strlcpy /* FORTIFY_SOURCE */
+
/*
* Copy string src to buffer dst of size dsize. At most dsize-1
* chars will be copied. Always NUL terminates (unless dsize == 0).
diff --git a/lib/libc/string/strncpy.c b/lib/libc/string/strncpy.c
--- a/lib/libc/string/strncpy.c
+++ b/lib/libc/string/strncpy.c
@@ -34,6 +34,8 @@
#include <string.h>
+#undef strncpy /* FORTIFY_SOURCE */
+
/*
* Copy src to dst, truncating or null-padding to always copy n bytes.
* Return dst.
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
@@ -19,6 +19,23 @@
#include <unistd.h>
#include <atf-c.h>
+static FILE * __unused
+new_fp(size_t __len)
+{
+ static char fpbuf[LINE_MAX];
+ FILE *fp;
+
+ ATF_REQUIRE(__len <= sizeof(fpbuf));
+
+ memset(fpbuf, 'A', sizeof(fpbuf) - 1);
+ fpbuf[sizeof(fpbuf) - 1] = '\0';
+
+ fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
+ ATF_REQUIRE(fp != NULL);
+
+ return (fp);
+}
+
/*
* Create a new symlink to use for readlink(2) style tests, we'll just use a
* random target name to have something interesting to look at.
@@ -34,47 +51,654 @@
arc4random_buf(target, sizeof(target));
- error = unlink(linkname);
- ATF_REQUIRE(error == 0 || errno == ENOENT);
+ error = unlink(linkname);
+ ATF_REQUIRE(error == 0 || errno == ENOENT);
+
+ error = symlink(target, linkname);
+ ATF_REQUIRE(error == 0);
+
+ return (linkname);
+}
+
+/*
+ * Constructs a tmpfile that we can use for testing read(2) and friends.
+ */
+static int __unused
+new_tmpfile(void)
+{
+ char buf[1024];
+ ssize_t rv;
+ size_t written;
+ int fd;
+
+ fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
+ ATF_REQUIRE(fd >= 0);
+
+ written = 0;
+ while (written < TMPFILE_SIZE) {
+ rv = write(fd, buf, sizeof(buf));
+ ATF_REQUIRE(rv > 0);
+
+ written += rv;
+ }
+
+ lseek(fd, 0, SEEK_SET);
+ return (fd);
+}
+
+static void
+disable_coredumps(void)
+{
+ struct rlimit rl = { 0 };
+
+ setrlimit(RLIMIT_CORE, &rl);
+}
+
+/*
+ * Replaces stdin with a file that we can actually read from, for tests where
+ * we want a FILE * or fd that we can get data from.
+ */
+static void __unused
+replace_stdin(void)
+{
+ int fd;
+
+ fd = new_tmpfile();
+
+ (void)dup2(fd, STDIN_FILENO);
+ if (fd != STDIN_FILENO)
+ close(fd);
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_before_end);
+ATF_TC_BODY(ctermid_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_ctermid + 1];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_ctermid + 1;
+ const size_t __idx __unused = __len - 1;
+
+ ctermid(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_end);
+ATF_TC_BODY(ctermid_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_ctermid];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_ctermid;
+ const size_t __idx __unused = __len - 1;
+
+ ctermid(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_heap_before_end);
+ATF_TC_BODY(ctermid_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) * (L_ctermid + 1);
+ const size_t __len = L_ctermid + 1;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_heap_end);
+ATF_TC_BODY(ctermid_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) * (L_ctermid);
+ const size_t __len = L_ctermid;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_heap_after_end);
+ATF_TC_BODY(ctermid_heap_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) * (L_ctermid - 1);
+ const size_t __len = L_ctermid - 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid(__stack.__buf);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_r_before_end);
+ATF_TC_BODY(ctermid_r_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_ctermid + 1];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_ctermid + 1;
+ const size_t __idx __unused = __len - 1;
+
+ ctermid_r(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_r_end);
+ATF_TC_BODY(ctermid_r_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_ctermid];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_ctermid;
+ const size_t __idx __unused = __len - 1;
+
+ ctermid_r(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_r_heap_before_end);
+ATF_TC_BODY(ctermid_r_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) * (L_ctermid + 1);
+ const size_t __len = L_ctermid + 1;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid_r(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_r_heap_end);
+ATF_TC_BODY(ctermid_r_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) * (L_ctermid);
+ const size_t __len = L_ctermid;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid_r(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ctermid_r_heap_after_end);
+ATF_TC_BODY(ctermid_r_heap_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) * (L_ctermid - 1);
+ const size_t __len = L_ctermid - 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ ctermid_r(__stack.__buf);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_before_end);
+ATF_TC_BODY(fread_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;
+
+ replace_stdin();
+
+ fread(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_end);
+ATF_TC_BODY(fread_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;
+
+ replace_stdin();
+
+ fread(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_heap_before_end);
+ATF_TC_BODY(fread_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_heap_end);
+ATF_TC_BODY(fread_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_heap_after_end);
+ATF_TC_BODY(fread_heap_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;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread(__stack.__buf, __len, 1, stdin);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_unlocked_before_end);
+ATF_TC_BODY(fread_unlocked_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;
+
+ replace_stdin();
+
+ fread_unlocked(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_unlocked_end);
+ATF_TC_BODY(fread_unlocked_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;
+
+ replace_stdin();
+
+ fread_unlocked(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_before_end);
+ATF_TC_BODY(fread_unlocked_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread_unlocked(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_end);
+ATF_TC_BODY(fread_unlocked_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread_unlocked(__stack.__buf, __len, 1, stdin);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fread_unlocked_heap_after_end);
+ATF_TC_BODY(fread_unlocked_heap_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;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ fread_unlocked(__stack.__buf, __len, 1, stdin);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gets_s_before_end);
+ATF_TC_BODY(gets_s_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;
+
+ replace_stdin();
+
+ gets_s(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gets_s_end);
+ATF_TC_BODY(gets_s_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;
+
+ replace_stdin();
+
+ gets_s(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gets_s_heap_before_end);
+ATF_TC_BODY(gets_s_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
+
+ gets_s(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gets_s_heap_end);
+ATF_TC_BODY(gets_s_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;
+
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
- error = symlink(target, linkname);
- ATF_REQUIRE(error == 0);
+ gets_s(__stack.__buf, __len);
+#undef BUF
- return (linkname);
}
-/*
- * Constructs a tmpfile that we can use for testing read(2) and friends.
- */
-static int __unused
-new_tmpfile(void)
+ATF_TC_WITHOUT_HEAD(gets_s_heap_after_end);
+ATF_TC_BODY(gets_s_heap_after_end, tc)
{
- char buf[1024];
- ssize_t rv;
- size_t written;
- int fd;
+#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;
+ pid_t __child;
+ int __status;
- fd = open("tmpfile", O_RDWR | O_CREAT | O_TRUNC, 0644);
- ATF_REQUIRE(fd >= 0);
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
- written = 0;
- while (written < TMPFILE_SIZE) {
- rv = write(fd, buf, sizeof(buf));
- ATF_REQUIRE(rv > 0);
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ replace_stdin();
- written += rv;
- }
+ gets_s(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
- lseek(fd, 0, SEEK_SET);
- return (fd);
-}
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
-static void
-disable_coredumps(void)
-{
- struct rlimit rl = { 0 };
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
- setrlimit(RLIMIT_CORE, &rl);
}
ATF_TC_WITHOUT_HEAD(sprintf_before_end);
@@ -339,8 +963,273 @@
}
+ATF_TC_WITHOUT_HEAD(tmpnam_before_end);
+ATF_TC_BODY(tmpnam_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_tmpnam + 1];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_tmpnam + 1;
+ const size_t __idx __unused = __len - 1;
+
+ tmpnam(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(tmpnam_end);
+ATF_TC_BODY(tmpnam_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[L_tmpnam];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = L_tmpnam;
+ const size_t __idx __unused = __len - 1;
+
+ tmpnam(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(tmpnam_heap_before_end);
+ATF_TC_BODY(tmpnam_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) * (L_tmpnam + 1);
+ const size_t __len = L_tmpnam + 1;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ tmpnam(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(tmpnam_heap_end);
+ATF_TC_BODY(tmpnam_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) * (L_tmpnam);
+ const size_t __len = L_tmpnam;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ tmpnam(__stack.__buf);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(tmpnam_heap_after_end);
+ATF_TC_BODY(tmpnam_heap_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) * (L_tmpnam - 1);
+ const size_t __len = L_tmpnam - 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ tmpnam(__stack.__buf);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fgets_before_end);
+ATF_TC_BODY(fgets_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;
+ FILE *fp;
+
+ fp = new_fp(__len);
+
+ fgets(__stack.__buf, __len, fp);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fgets_end);
+ATF_TC_BODY(fgets_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;
+ FILE *fp;
+
+ fp = new_fp(__len);
+
+ fgets(__stack.__buf, __len, fp);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fgets_heap_before_end);
+ATF_TC_BODY(fgets_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;
+ FILE *fp;
+
+ __stack.__buf = malloc(__bufsz);
+ fp = new_fp(__len);
+
+ fgets(__stack.__buf, __len, fp);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fgets_heap_end);
+ATF_TC_BODY(fgets_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;
+ FILE *fp;
+
+ __stack.__buf = malloc(__bufsz);
+ fp = new_fp(__len);
+
+ fgets(__stack.__buf, __len, fp);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(fgets_heap_after_end);
+ATF_TC_BODY(fgets_heap_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;
+ pid_t __child;
+ int __status;
+ FILE *fp;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ fp = new_fp(__len);
+
+ fgets(__stack.__buf, __len, fp);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
ATF_TP_ADD_TCS(tp)
{
+ ATF_TP_ADD_TC(tp, ctermid_before_end);
+ ATF_TP_ADD_TC(tp, ctermid_end);
+ ATF_TP_ADD_TC(tp, ctermid_heap_before_end);
+ ATF_TP_ADD_TC(tp, ctermid_heap_end);
+ ATF_TP_ADD_TC(tp, ctermid_heap_after_end);
+ ATF_TP_ADD_TC(tp, ctermid_r_before_end);
+ ATF_TP_ADD_TC(tp, ctermid_r_end);
+ ATF_TP_ADD_TC(tp, ctermid_r_heap_before_end);
+ ATF_TP_ADD_TC(tp, ctermid_r_heap_end);
+ ATF_TP_ADD_TC(tp, ctermid_r_heap_after_end);
+ ATF_TP_ADD_TC(tp, fread_before_end);
+ ATF_TP_ADD_TC(tp, fread_end);
+ ATF_TP_ADD_TC(tp, fread_heap_before_end);
+ ATF_TP_ADD_TC(tp, fread_heap_end);
+ ATF_TP_ADD_TC(tp, fread_heap_after_end);
+ ATF_TP_ADD_TC(tp, fread_unlocked_before_end);
+ ATF_TP_ADD_TC(tp, fread_unlocked_end);
+ ATF_TP_ADD_TC(tp, fread_unlocked_heap_before_end);
+ ATF_TP_ADD_TC(tp, fread_unlocked_heap_end);
+ ATF_TP_ADD_TC(tp, fread_unlocked_heap_after_end);
+ ATF_TP_ADD_TC(tp, gets_s_before_end);
+ ATF_TP_ADD_TC(tp, gets_s_end);
+ ATF_TP_ADD_TC(tp, gets_s_heap_before_end);
+ ATF_TP_ADD_TC(tp, gets_s_heap_end);
+ ATF_TP_ADD_TC(tp, gets_s_heap_after_end);
ATF_TP_ADD_TC(tp, sprintf_before_end);
ATF_TP_ADD_TC(tp, sprintf_end);
ATF_TP_ADD_TC(tp, sprintf_heap_before_end);
@@ -351,5 +1240,15 @@
ATF_TP_ADD_TC(tp, snprintf_heap_before_end);
ATF_TP_ADD_TC(tp, snprintf_heap_end);
ATF_TP_ADD_TC(tp, snprintf_heap_after_end);
+ ATF_TP_ADD_TC(tp, tmpnam_before_end);
+ ATF_TP_ADD_TC(tp, tmpnam_end);
+ ATF_TP_ADD_TC(tp, tmpnam_heap_before_end);
+ ATF_TP_ADD_TC(tp, tmpnam_heap_end);
+ ATF_TP_ADD_TC(tp, tmpnam_heap_after_end);
+ ATF_TP_ADD_TC(tp, fgets_before_end);
+ ATF_TP_ADD_TC(tp, fgets_end);
+ ATF_TP_ADD_TC(tp, fgets_heap_before_end);
+ ATF_TP_ADD_TC(tp, fgets_heap_end);
+ ATF_TP_ADD_TC(tp, fgets_heap_after_end);
return (atf_no_error());
}
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
@@ -19,6 +19,23 @@
#include <unistd.h>
#include <atf-c.h>
+static FILE * __unused
+new_fp(size_t __len)
+{
+ static char fpbuf[LINE_MAX];
+ FILE *fp;
+
+ ATF_REQUIRE(__len <= sizeof(fpbuf));
+
+ memset(fpbuf, 'A', sizeof(fpbuf) - 1);
+ fpbuf[sizeof(fpbuf) - 1] = '\0';
+
+ fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
+ ATF_REQUIRE(fp != NULL);
+
+ return (fp);
+}
+
/*
* Create a new symlink to use for readlink(2) style tests, we'll just use a
* random target name to have something interesting to look at.
@@ -77,6 +94,22 @@
setrlimit(RLIMIT_CORE, &rl);
}
+/*
+ * Replaces stdin with a file that we can actually read from, for tests where
+ * we want a FILE * or fd that we can get data from.
+ */
+static void __unused
+replace_stdin(void)
+{
+ int fd;
+
+ fd = new_tmpfile();
+
+ (void)dup2(fd, STDIN_FILENO);
+ if (fd != STDIN_FILENO)
+ close(fd);
+}
+
ATF_TC_WITHOUT_HEAD(memcpy_before_end);
ATF_TC_BODY(memcpy_before_end, tc)
{
@@ -196,6 +229,125 @@
}
+ATF_TC_WITHOUT_HEAD(mempcpy_before_end);
+ATF_TC_BODY(mempcpy_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 + 10];
+
+ mempcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(mempcpy_end);
+ATF_TC_BODY(mempcpy_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 + 10];
+
+ mempcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(mempcpy_heap_before_end);
+ATF_TC_BODY(mempcpy_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 + 10];
+
+ __stack.__buf = malloc(__bufsz);
+
+ mempcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(mempcpy_heap_end);
+ATF_TC_BODY(mempcpy_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 + 10];
+
+ __stack.__buf = malloc(__bufsz);
+
+ mempcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(mempcpy_heap_after_end);
+ATF_TC_BODY(mempcpy_heap_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;
+ pid_t __child;
+ int __status;
+ char src[__len + 10];
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ mempcpy(__stack.__buf, src, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
ATF_TC_WITHOUT_HEAD(memmove_before_end);
ATF_TC_BODY(memmove_before_end, tc)
{
@@ -837,6 +989,142 @@
}
+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];
+
+ memset(__stack.__buf, 0, __len);
+ memset(src, 'A', __len - 1);
+ src[__len - 1] = '\0';
+
+ strlcat(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+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];
+
+ memset(__stack.__buf, 0, __len);
+ memset(src, 'A', __len - 1);
+ src[__len - 1] = '\0';
+
+ strlcat(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(strlcat_heap_before_end);
+ATF_TC_BODY(strlcat_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];
+
+ __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
+
+}
+
+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];
+
+ __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
+
+}
+
+ATF_TC_WITHOUT_HEAD(strlcat_heap_after_end);
+ATF_TC_BODY(strlcat_heap_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;
+ 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';
+
+ strlcat(__stack.__buf, src, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
ATF_TC_WITHOUT_HEAD(strncat_before_end);
ATF_TC_BODY(strncat_before_end, tc)
{
@@ -1109,6 +1397,142 @@
}
+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)
+{
+#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';
+
+ strlcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(strlcpy_heap_end);
+ATF_TC_BODY(strlcpy_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';
+
+ strlcpy(__stack.__buf, src, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(strlcpy_heap_after_end);
+ATF_TC_BODY(strlcpy_heap_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;
+ 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';
+
+ strlcpy(__stack.__buf, src, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
ATF_TC_WITHOUT_HEAD(strncpy_before_end);
ATF_TC_BODY(strncpy_before_end, tc)
{
@@ -1252,6 +1676,11 @@
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);
@@ -1277,6 +1706,11 @@
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);
@@ -1287,6 +1721,11 @@
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);
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
@@ -19,6 +19,23 @@
#include <unistd.h>
#include <atf-c.h>
+static FILE * __unused
+new_fp(size_t __len)
+{
+ static char fpbuf[LINE_MAX];
+ FILE *fp;
+
+ ATF_REQUIRE(__len <= sizeof(fpbuf));
+
+ memset(fpbuf, 'A', sizeof(fpbuf) - 1);
+ fpbuf[sizeof(fpbuf) - 1] = '\0';
+
+ fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
+ ATF_REQUIRE(fp != NULL);
+
+ return (fp);
+}
+
/*
* Create a new symlink to use for readlink(2) style tests, we'll just use a
* random target name to have something interesting to look at.
@@ -77,6 +94,22 @@
setrlimit(RLIMIT_CORE, &rl);
}
+/*
+ * Replaces stdin with a file that we can actually read from, for tests where
+ * we want a FILE * or fd that we can get data from.
+ */
+static void __unused
+replace_stdin(void)
+{
+ int fd;
+
+ fd = new_tmpfile();
+
+ (void)dup2(fd, STDIN_FILENO);
+ if (fd != STDIN_FILENO)
+ close(fd);
+}
+
ATF_TC_WITHOUT_HEAD(bcopy_before_end);
ATF_TC_BODY(bcopy_before_end, tc)
{
@@ -310,6 +343,120 @@
}
+ATF_TC_WITHOUT_HEAD(explicit_bzero_before_end);
+ATF_TC_BODY(explicit_bzero_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;
+
+ explicit_bzero(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(explicit_bzero_end);
+ATF_TC_BODY(explicit_bzero_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;
+
+ explicit_bzero(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_before_end);
+ATF_TC_BODY(explicit_bzero_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;
+
+ __stack.__buf = malloc(__bufsz);
+
+ explicit_bzero(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_end);
+ATF_TC_BODY(explicit_bzero_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;
+
+ __stack.__buf = malloc(__bufsz);
+
+ explicit_bzero(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(explicit_bzero_heap_after_end);
+ATF_TC_BODY(explicit_bzero_heap_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;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ explicit_bzero(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
ATF_TP_ADD_TCS(tp)
{
ATF_TP_ADD_TC(tp, bcopy_before_end);
@@ -322,5 +469,10 @@
ATF_TP_ADD_TC(tp, bzero_heap_before_end);
ATF_TP_ADD_TC(tp, bzero_heap_end);
ATF_TP_ADD_TC(tp, bzero_heap_after_end);
+ ATF_TP_ADD_TC(tp, explicit_bzero_before_end);
+ ATF_TP_ADD_TC(tp, explicit_bzero_end);
+ ATF_TP_ADD_TC(tp, explicit_bzero_heap_before_end);
+ ATF_TP_ADD_TC(tp, explicit_bzero_heap_end);
+ ATF_TP_ADD_TC(tp, explicit_bzero_heap_after_end);
return (atf_no_error());
}
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
@@ -19,6 +19,23 @@
#include <unistd.h>
#include <atf-c.h>
+static FILE * __unused
+new_fp(size_t __len)
+{
+ static char fpbuf[LINE_MAX];
+ FILE *fp;
+
+ ATF_REQUIRE(__len <= sizeof(fpbuf));
+
+ memset(fpbuf, 'A', sizeof(fpbuf) - 1);
+ fpbuf[sizeof(fpbuf) - 1] = '\0';
+
+ fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
+ ATF_REQUIRE(fp != NULL);
+
+ return (fp);
+}
+
/*
* Create a new symlink to use for readlink(2) style tests, we'll just use a
* random target name to have something interesting to look at.
@@ -77,6 +94,22 @@
setrlimit(RLIMIT_CORE, &rl);
}
+/*
+ * Replaces stdin with a file that we can actually read from, for tests where
+ * we want a FILE * or fd that we can get data from.
+ */
+static void __unused
+replace_stdin(void)
+{
+ int fd;
+
+ fd = new_tmpfile();
+
+ (void)dup2(fd, STDIN_FILENO);
+ if (fd != STDIN_FILENO)
+ close(fd);
+}
+
ATF_TC_WITHOUT_HEAD(getcwd_before_end);
ATF_TC_BODY(getcwd_before_end, tc)
{
@@ -191,107 +224,215 @@
}
-ATF_TC_WITHOUT_HEAD(read_before_end);
-ATF_TC_BODY(read_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getgrouplist_before_end);
+ATF_TC_BODY(getgrouplist_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[41];
+ gid_t __buf[4];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 41 - 1;
+ const size_t __len = 4 - 1;
const size_t __idx __unused = __len - 1;
- int fd;
+ int intlen = (int)__len;
- fd = new_tmpfile(); /* Cannot fail */
+ getgrouplist("root", 0, __stack.__buf, &intlen);
+#undef BUF
- read(fd, __stack.__buf, __len);
+}
+
+ATF_TC_WITHOUT_HEAD(getgrouplist_end);
+ATF_TC_BODY(getgrouplist_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ gid_t __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ int intlen = (int)__len;
+
+ getgrouplist("root", 0, __stack.__buf, &intlen);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(read_end);
-ATF_TC_BODY(read_end, tc)
+ATF_TC_WITHOUT_HEAD(getgrouplist_heap_before_end);
+ATF_TC_BODY(getgrouplist_heap_before_end, tc)
+{
+#define BUF __stack.__buf
+ struct {
+ uint8_t padding_l;
+ gid_t * __buf;
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4 - 1;
+ const size_t __idx __unused = __len - 1;
+ int intlen = (int)__len;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getgrouplist("root", 0, __stack.__buf, &intlen);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getgrouplist_heap_end);
+ATF_TC_BODY(getgrouplist_heap_end, tc)
+{
+#define BUF __stack.__buf
+ struct {
+ uint8_t padding_l;
+ gid_t * __buf;
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ int intlen = (int)__len;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getgrouplist("root", 0, __stack.__buf, &intlen);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getgrouplist_heap_after_end);
+ATF_TC_BODY(getgrouplist_heap_after_end, tc)
+{
+#define BUF __stack.__buf
+ struct {
+ uint8_t padding_l;
+ gid_t * __buf;
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+ int intlen = (int)__len;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ getgrouplist("root", 0, __stack.__buf, &intlen);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getgroups_before_end);
+ATF_TC_BODY(getgroups_before_end, tc)
{
#define BUF &__stack.__buf
struct {
uint8_t padding_l;
- unsigned char __buf[41];
+ gid_t __buf[4];
uint8_t padding_r;
} __stack;
const size_t __bufsz __unused = sizeof(__stack.__buf);
- const size_t __len = 41;
+ const size_t __len = 4 - 1;
const size_t __idx __unused = __len - 1;
- int fd;
- fd = new_tmpfile(); /* Cannot fail */
+ getgroups(__len, __stack.__buf);
+#undef BUF
- read(fd, __stack.__buf, __len);
+}
+
+ATF_TC_WITHOUT_HEAD(getgroups_end);
+ATF_TC_BODY(getgroups_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ gid_t __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+
+ getgroups(__len, __stack.__buf);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(read_heap_before_end);
-ATF_TC_BODY(read_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getgroups_heap_before_end);
+ATF_TC_BODY(getgroups_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ gid_t * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41);
- const size_t __len = 41 - 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4 - 1;
const size_t __idx __unused = __len - 1;
- int fd;
__stack.__buf = malloc(__bufsz);
- fd = new_tmpfile(); /* Cannot fail */
- read(fd, __stack.__buf, __len);
+ getgroups(__len, __stack.__buf);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(read_heap_end);
-ATF_TC_BODY(read_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(getgroups_heap_end);
+ATF_TC_BODY(getgroups_heap_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ gid_t * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41);
- const size_t __len = 41;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4;
const size_t __idx __unused = __len - 1;
- int fd;
__stack.__buf = malloc(__bufsz);
- fd = new_tmpfile(); /* Cannot fail */
- read(fd, __stack.__buf, __len);
+ getgroups(__len, __stack.__buf);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(read_heap_after_end);
-ATF_TC_BODY(read_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(getgroups_heap_after_end);
+ATF_TC_BODY(getgroups_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
uint8_t padding_l;
- unsigned char * __buf;
+ gid_t * __buf;
uint8_t padding_r;
} __stack;
- const size_t __bufsz __unused = sizeof(*__stack.__buf) * (41);
- const size_t __len = 41 + 1;
+ const size_t __bufsz __unused = sizeof(*__stack.__buf) * (4);
+ const size_t __len = 4 + 1;
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- int fd;
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -301,9 +442,8 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- fd = new_tmpfile(); /* Cannot fail */
- read(fd, __stack.__buf, __len);
+ getgroups(__len, __stack.__buf);
_exit(1); /* Should have aborted. */
monitor:
@@ -317,8 +457,8 @@
}
-ATF_TC_WITHOUT_HEAD(readlink_before_end);
-ATF_TC_BODY(readlink_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getloginclass_before_end);
+ATF_TC_BODY(getloginclass_before_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -329,17 +469,14 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- const char *path;
- path = new_link(__len); /* Cannot fail */
-
- readlink(path, __stack.__buf, __len);
+ getloginclass(__stack.__buf, __len);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(readlink_end);
-ATF_TC_BODY(readlink_end, tc)
+ATF_TC_WITHOUT_HEAD(getloginclass_end);
+ATF_TC_BODY(getloginclass_end, tc)
{
#define BUF &__stack.__buf
struct {
@@ -350,17 +487,14 @@
const size_t __bufsz __unused = sizeof(__stack.__buf);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- const char *path;
-
- path = new_link(__len); /* Cannot fail */
- readlink(path, __stack.__buf, __len);
+ getloginclass(__stack.__buf, __len);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(readlink_heap_before_end);
-ATF_TC_BODY(readlink_heap_before_end, tc)
+ATF_TC_WITHOUT_HEAD(getloginclass_heap_before_end);
+ATF_TC_BODY(getloginclass_heap_before_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -371,18 +505,16 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42 - 1;
const size_t __idx __unused = __len - 1;
- const char *path;
__stack.__buf = malloc(__bufsz);
- path = new_link(__len); /* Cannot fail */
- readlink(path, __stack.__buf, __len);
+ getloginclass(__stack.__buf, __len);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(readlink_heap_end);
-ATF_TC_BODY(readlink_heap_end, tc)
+ATF_TC_WITHOUT_HEAD(getloginclass_heap_end);
+ATF_TC_BODY(getloginclass_heap_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -393,18 +525,16 @@
const size_t __bufsz __unused = sizeof(*__stack.__buf) * (42);
const size_t __len = 42;
const size_t __idx __unused = __len - 1;
- const char *path;
__stack.__buf = malloc(__bufsz);
- path = new_link(__len); /* Cannot fail */
- readlink(path, __stack.__buf, __len);
+ getloginclass(__stack.__buf, __len);
#undef BUF
}
-ATF_TC_WITHOUT_HEAD(readlink_heap_after_end);
-ATF_TC_BODY(readlink_heap_after_end, tc)
+ATF_TC_WITHOUT_HEAD(getloginclass_heap_after_end);
+ATF_TC_BODY(getloginclass_heap_after_end, tc)
{
#define BUF __stack.__buf
struct {
@@ -417,7 +547,6 @@
const size_t __idx __unused = __len - 1;
pid_t __child;
int __status;
- const char *path;
__child = fork();
ATF_REQUIRE(__child >= 0);
@@ -427,9 +556,1162 @@
/* Child */
disable_coredumps();
__stack.__buf = malloc(__bufsz);
- path = new_link(__len); /* Cannot fail */
- readlink(path, __stack.__buf, __len);
+ getloginclass(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(pread_before_end);
+ATF_TC_BODY(pread_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[41];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 41 - 1;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ fd = new_tmpfile(); /* Cannot fail */
+
+ pread(fd, __stack.__buf, __len, 0);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(pread_end);
+ATF_TC_BODY(pread_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[41];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 41;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ fd = new_tmpfile(); /* Cannot fail */
+
+ pread(fd, __stack.__buf, __len, 0);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(pread_heap_before_end);
+ATF_TC_BODY(pread_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) * (41);
+ const size_t __len = 41 - 1;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ pread(fd, __stack.__buf, __len, 0);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(pread_heap_end);
+ATF_TC_BODY(pread_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) * (41);
+ const size_t __len = 41;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ pread(fd, __stack.__buf, __len, 0);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(pread_heap_after_end);
+ATF_TC_BODY(pread_heap_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) * (41);
+ const size_t __len = 41 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+ int fd;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ pread(fd, __stack.__buf, __len, 0);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(read_before_end);
+ATF_TC_BODY(read_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[41];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 41 - 1;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ fd = new_tmpfile(); /* Cannot fail */
+
+ read(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(read_end);
+ATF_TC_BODY(read_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[41];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 41;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ fd = new_tmpfile(); /* Cannot fail */
+
+ read(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(read_heap_before_end);
+ATF_TC_BODY(read_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) * (41);
+ const size_t __len = 41 - 1;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ read(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(read_heap_end);
+ATF_TC_BODY(read_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) * (41);
+ const size_t __len = 41;
+ const size_t __idx __unused = __len - 1;
+ int fd;
+
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ read(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(read_heap_after_end);
+ATF_TC_BODY(read_heap_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) * (41);
+ const size_t __len = 41 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+ int fd;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ fd = new_tmpfile(); /* Cannot fail */
+
+ read(fd, __stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlink_before_end);
+ATF_TC_BODY(readlink_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;
+ const char *path;
+
+ path = new_link(__len); /* Cannot fail */
+
+ readlink(path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlink_end);
+ATF_TC_BODY(readlink_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;
+ const char *path;
+
+ path = new_link(__len); /* Cannot fail */
+
+ readlink(path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlink_heap_before_end);
+ATF_TC_BODY(readlink_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;
+ const char *path;
+
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlink(path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlink_heap_end);
+ATF_TC_BODY(readlink_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;
+ const char *path;
+
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlink(path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlink_heap_after_end);
+ATF_TC_BODY(readlink_heap_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;
+ pid_t __child;
+ int __status;
+ const char *path;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlink(path, __stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlinkat_before_end);
+ATF_TC_BODY(readlinkat_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;
+ const char *path;
+
+ path = new_link(__len); /* Cannot fail */
+
+ readlinkat(AT_FDCWD, path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlinkat_end);
+ATF_TC_BODY(readlinkat_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;
+ const char *path;
+
+ path = new_link(__len); /* Cannot fail */
+
+ readlinkat(AT_FDCWD, path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlinkat_heap_before_end);
+ATF_TC_BODY(readlinkat_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;
+ const char *path;
+
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlinkat(AT_FDCWD, path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlinkat_heap_end);
+ATF_TC_BODY(readlinkat_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;
+ const char *path;
+
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlinkat(AT_FDCWD, path, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(readlinkat_heap_after_end);
+ATF_TC_BODY(readlinkat_heap_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;
+ pid_t __child;
+ int __status;
+ const char *path;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+ path = new_link(__len); /* Cannot fail */
+
+ readlinkat(AT_FDCWD, path, __stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getdomainname_before_end);
+ATF_TC_BODY(getdomainname_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4 - 1;
+ const size_t __idx __unused = __len - 1;
+ char sysdomain[256];
+
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+
+ getdomainname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getdomainname_end);
+ATF_TC_BODY(getdomainname_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ char sysdomain[256];
+
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+
+ getdomainname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getdomainname_heap_before_end);
+ATF_TC_BODY(getdomainname_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) * (4);
+ const size_t __len = 4 - 1;
+ const size_t __idx __unused = __len - 1;
+ char sysdomain[256];
+
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+
+ __stack.__buf = malloc(__bufsz);
+
+ getdomainname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getdomainname_heap_end);
+ATF_TC_BODY(getdomainname_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) * (4);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ char sysdomain[256];
+
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+
+ __stack.__buf = malloc(__bufsz);
+
+ getdomainname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getdomainname_heap_after_end);
+ATF_TC_BODY(getdomainname_heap_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) * (4);
+ const size_t __len = 4 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+ char sysdomain[256];
+
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ getdomainname(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getentropy_before_end);
+ATF_TC_BODY(getentropy_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;
+
+ getentropy(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getentropy_end);
+ATF_TC_BODY(getentropy_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;
+
+ getentropy(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getentropy_heap_before_end);
+ATF_TC_BODY(getentropy_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;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getentropy(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getentropy_heap_end);
+ATF_TC_BODY(getentropy_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;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getentropy(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getentropy_heap_after_end);
+ATF_TC_BODY(getentropy_heap_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;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ getentropy(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gethostname_before_end);
+ATF_TC_BODY(gethostname_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4 - 1;
+ const size_t __idx __unused = __len - 1;
+ char syshost[256];
+ int error;
+
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+
+ gethostname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gethostname_end);
+ATF_TC_BODY(gethostname_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[4];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ char syshost[256];
+ int error;
+
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+
+ gethostname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gethostname_heap_before_end);
+ATF_TC_BODY(gethostname_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) * (4);
+ const size_t __len = 4 - 1;
+ const size_t __idx __unused = __len - 1;
+ char syshost[256];
+ int error;
+
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+
+ __stack.__buf = malloc(__bufsz);
+
+ gethostname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gethostname_heap_end);
+ATF_TC_BODY(gethostname_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) * (4);
+ const size_t __len = 4;
+ const size_t __idx __unused = __len - 1;
+ char syshost[256];
+ int error;
+
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+
+ __stack.__buf = malloc(__bufsz);
+
+ gethostname(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(gethostname_heap_after_end);
+ATF_TC_BODY(gethostname_heap_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) * (4);
+ const size_t __len = 4 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+ char syshost[256];
+ int error;
+
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ gethostname(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getlogin_r_before_end);
+ATF_TC_BODY(getlogin_r_before_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[MAXLOGNAME + 1];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = MAXLOGNAME + 1 - 1;
+ const size_t __idx __unused = __len - 1;
+
+ getlogin_r(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getlogin_r_end);
+ATF_TC_BODY(getlogin_r_end, tc)
+{
+#define BUF &__stack.__buf
+ struct {
+ uint8_t padding_l;
+ unsigned char __buf[MAXLOGNAME + 1];
+ uint8_t padding_r;
+ } __stack;
+ const size_t __bufsz __unused = sizeof(__stack.__buf);
+ const size_t __len = MAXLOGNAME + 1;
+ const size_t __idx __unused = __len - 1;
+
+ getlogin_r(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getlogin_r_heap_before_end);
+ATF_TC_BODY(getlogin_r_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) * (MAXLOGNAME + 1);
+ const size_t __len = MAXLOGNAME + 1 - 1;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getlogin_r(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getlogin_r_heap_end);
+ATF_TC_BODY(getlogin_r_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) * (MAXLOGNAME + 1);
+ const size_t __len = MAXLOGNAME + 1;
+ const size_t __idx __unused = __len - 1;
+
+ __stack.__buf = malloc(__bufsz);
+
+ getlogin_r(__stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(getlogin_r_heap_after_end);
+ATF_TC_BODY(getlogin_r_heap_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) * (MAXLOGNAME + 1);
+ const size_t __len = MAXLOGNAME + 1 + 1;
+ const size_t __idx __unused = __len - 1;
+ pid_t __child;
+ int __status;
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ getlogin_r(__stack.__buf, __len);
+ _exit(1); /* Should have aborted. */
+
+monitor:
+ while (waitpid(__child, &__status, 0) != __child) {
+ ATF_REQUIRE_EQ(EINTR, errno);
+ }
+
+ ATF_REQUIRE_MSG(WIFSIGNALED(__status), "not signaled, status %x", __status);
+ ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ttyname_r_before_end);
+ATF_TC_BODY(ttyname_r_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;
+ int fd;
+
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+
+ ttyname_r(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ttyname_r_end);
+ATF_TC_BODY(ttyname_r_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;
+ int fd;
+
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+
+ ttyname_r(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ttyname_r_heap_before_end);
+ATF_TC_BODY(ttyname_r_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;
+ int fd;
+
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+
+ __stack.__buf = malloc(__bufsz);
+
+ ttyname_r(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ttyname_r_heap_end);
+ATF_TC_BODY(ttyname_r_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;
+ int fd;
+
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+
+ __stack.__buf = malloc(__bufsz);
+
+ ttyname_r(fd, __stack.__buf, __len);
+#undef BUF
+
+}
+
+ATF_TC_WITHOUT_HEAD(ttyname_r_heap_after_end);
+ATF_TC_BODY(ttyname_r_heap_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;
+ pid_t __child;
+ int __status;
+ int fd;
+
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+
+ __child = fork();
+ ATF_REQUIRE(__child >= 0);
+ if (__child > 0)
+ goto monitor;
+
+ /* Child */
+ disable_coredumps();
+ __stack.__buf = malloc(__bufsz);
+
+ ttyname_r(fd, __stack.__buf, __len);
_exit(1); /* Should have aborted. */
monitor:
@@ -450,6 +1732,26 @@
ATF_TP_ADD_TC(tp, getcwd_heap_before_end);
ATF_TP_ADD_TC(tp, getcwd_heap_end);
ATF_TP_ADD_TC(tp, getcwd_heap_after_end);
+ ATF_TP_ADD_TC(tp, getgrouplist_before_end);
+ ATF_TP_ADD_TC(tp, getgrouplist_end);
+ ATF_TP_ADD_TC(tp, getgrouplist_heap_before_end);
+ ATF_TP_ADD_TC(tp, getgrouplist_heap_end);
+ ATF_TP_ADD_TC(tp, getgrouplist_heap_after_end);
+ ATF_TP_ADD_TC(tp, getgroups_before_end);
+ ATF_TP_ADD_TC(tp, getgroups_end);
+ ATF_TP_ADD_TC(tp, getgroups_heap_before_end);
+ ATF_TP_ADD_TC(tp, getgroups_heap_end);
+ ATF_TP_ADD_TC(tp, getgroups_heap_after_end);
+ ATF_TP_ADD_TC(tp, getloginclass_before_end);
+ ATF_TP_ADD_TC(tp, getloginclass_end);
+ ATF_TP_ADD_TC(tp, getloginclass_heap_before_end);
+ ATF_TP_ADD_TC(tp, getloginclass_heap_end);
+ ATF_TP_ADD_TC(tp, getloginclass_heap_after_end);
+ ATF_TP_ADD_TC(tp, pread_before_end);
+ ATF_TP_ADD_TC(tp, pread_end);
+ ATF_TP_ADD_TC(tp, pread_heap_before_end);
+ ATF_TP_ADD_TC(tp, pread_heap_end);
+ ATF_TP_ADD_TC(tp, pread_heap_after_end);
ATF_TP_ADD_TC(tp, read_before_end);
ATF_TP_ADD_TC(tp, read_end);
ATF_TP_ADD_TC(tp, read_heap_before_end);
@@ -460,5 +1762,35 @@
ATF_TP_ADD_TC(tp, readlink_heap_before_end);
ATF_TP_ADD_TC(tp, readlink_heap_end);
ATF_TP_ADD_TC(tp, readlink_heap_after_end);
+ ATF_TP_ADD_TC(tp, readlinkat_before_end);
+ ATF_TP_ADD_TC(tp, readlinkat_end);
+ ATF_TP_ADD_TC(tp, readlinkat_heap_before_end);
+ ATF_TP_ADD_TC(tp, readlinkat_heap_end);
+ ATF_TP_ADD_TC(tp, readlinkat_heap_after_end);
+ ATF_TP_ADD_TC(tp, getdomainname_before_end);
+ ATF_TP_ADD_TC(tp, getdomainname_end);
+ ATF_TP_ADD_TC(tp, getdomainname_heap_before_end);
+ ATF_TP_ADD_TC(tp, getdomainname_heap_end);
+ ATF_TP_ADD_TC(tp, getdomainname_heap_after_end);
+ ATF_TP_ADD_TC(tp, getentropy_before_end);
+ ATF_TP_ADD_TC(tp, getentropy_end);
+ ATF_TP_ADD_TC(tp, getentropy_heap_before_end);
+ ATF_TP_ADD_TC(tp, getentropy_heap_end);
+ ATF_TP_ADD_TC(tp, getentropy_heap_after_end);
+ ATF_TP_ADD_TC(tp, gethostname_before_end);
+ ATF_TP_ADD_TC(tp, gethostname_end);
+ ATF_TP_ADD_TC(tp, gethostname_heap_before_end);
+ ATF_TP_ADD_TC(tp, gethostname_heap_end);
+ ATF_TP_ADD_TC(tp, gethostname_heap_after_end);
+ ATF_TP_ADD_TC(tp, getlogin_r_before_end);
+ ATF_TP_ADD_TC(tp, getlogin_r_end);
+ ATF_TP_ADD_TC(tp, getlogin_r_heap_before_end);
+ ATF_TP_ADD_TC(tp, getlogin_r_heap_end);
+ ATF_TP_ADD_TC(tp, getlogin_r_heap_after_end);
+ ATF_TP_ADD_TC(tp, ttyname_r_before_end);
+ ATF_TP_ADD_TC(tp, ttyname_r_end);
+ ATF_TP_ADD_TC(tp, ttyname_r_heap_before_end);
+ ATF_TP_ADD_TC(tp, ttyname_r_heap_end);
+ ATF_TP_ADD_TC(tp, ttyname_r_heap_after_end);
return (atf_no_error());
}
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
@@ -61,6 +61,10 @@
srcvar[sizeof(srcvar) - 1] = '\0';
]]
+local stdio_init = [[
+ replace_stdin();
+]]
+
local string_stackvars = "\tchar src[__len];\n"
local string_init = [[
memset(__stack.__buf, 0, __len);
@@ -95,6 +99,53 @@
local all_tests = {
stdio = {
-- <stdio.h>
+ {
+ func = "ctermid",
+ bufsize = "L_ctermid",
+ arguments = {
+ "__buf",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "ctermid_r",
+ bufsize = "L_ctermid",
+ arguments = {
+ "__buf",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "fread",
+ arguments = {
+ "__buf",
+ "__len",
+ "1",
+ "stdin",
+ },
+ exclude = excludes_stack_overflow,
+ init = stdio_init,
+ },
+ {
+ func = "fread_unlocked",
+ arguments = {
+ "__buf",
+ "__len",
+ "1",
+ "stdin",
+ },
+ exclude = excludes_stack_overflow,
+ init = stdio_init,
+ },
+ {
+ func = "gets_s",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ init = stdio_init,
+ },
{
func = "sprintf",
arguments = {
@@ -120,6 +171,27 @@
stackvars = printf_stackvars,
init = printf_init,
},
+ {
+ func = "tmpnam",
+ bufsize = "L_tmpnam",
+ arguments = {
+ "__buf",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "fgets",
+ arguments = {
+ "__buf",
+ "__len",
+ "fp",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tFILE *fp;\n",
+ init = [[
+ fp = new_fp(__len);
+]],
+ },
},
string = {
-- <string.h>
@@ -133,6 +205,16 @@
exclude = excludes_stack_overflow,
stackvars = "\tchar src[__len + 10];\n",
},
+ {
+ func = "mempcpy",
+ arguments = {
+ "__buf",
+ "src",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tchar src[__len + 10];\n",
+ },
{
func = "memmove",
arguments = {
@@ -185,6 +267,17 @@
init = string_init,
uses_len = true,
},
+ {
+ func = "strlcat",
+ arguments = {
+ "__buf",
+ "src",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = string_stackvars,
+ init = string_init,
+ },
{
func = "strncat",
arguments = {
@@ -207,6 +300,17 @@
init = string_init,
uses_len = true,
},
+ {
+ func = "strlcpy",
+ arguments = {
+ "__buf",
+ "src",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = string_stackvars,
+ init = string_init,
+ },
{
func = "strncpy",
arguments = {
@@ -239,6 +343,14 @@
},
exclude = excludes_stack_overflow,
},
+ {
+ func = "explicit_bzero",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ },
},
unistd = {
-- <unistd.h>
@@ -251,6 +363,53 @@
},
exclude = excludes_stack_overflow,
},
+ {
+ func = "getgrouplist",
+ bufsize = "4",
+ buftype = "gid_t[]",
+ arguments = {
+ "\"root\"",
+ "0",
+ "__buf",
+ "&intlen",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tint intlen = (int)__len;\n",
+ uses_len = true,
+ },
+ {
+ func = "getgroups",
+ bufsize = "4",
+ buftype = "gid_t[]",
+ arguments = {
+ "__len",
+ "__buf",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "getloginclass",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "pread",
+ bufsize = "41",
+ arguments = {
+ "fd",
+ "__buf",
+ "__len",
+ "0",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tint fd;\n",
+ init = [[
+ fd = new_tmpfile(); /* Cannot fail */
+]],
+ },
{
func = "read",
bufsize = "41",
@@ -278,6 +437,85 @@
path = new_link(__len); /* Cannot fail */
]],
},
+ {
+ func = "readlinkat",
+ arguments = {
+ "AT_FDCWD",
+ "path",
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tconst char *path;\n",
+ init = [[
+ path = new_link(__len); /* Cannot fail */
+]],
+ },
+ {
+ func = "getdomainname",
+ bufsize = "4",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tchar sysdomain[256];\n",
+ early_init = [[
+ (void)getdomainname(sysdomain, __len);
+ if (strlen(sysdomain) <= __len)
+ atf_tc_skip("domain name too short for testing");
+]]
+ },
+ {
+ func = "getentropy",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "gethostname",
+ bufsize = "4",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = [[
+ char syshost[256];
+ int error;
+]],
+ early_init = [[
+ error = gethostname(syshost, __len);
+ if (error != 0 || strlen(syshost) <= __len)
+ atf_tc_skip("hostname too short for testing");
+]]
+ },
+ {
+ func = "getlogin_r",
+ bufsize = "MAXLOGNAME + 1",
+ arguments = {
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ },
+ {
+ func = "ttyname_r",
+ arguments = {
+ "fd",
+ "__buf",
+ "__len",
+ },
+ exclude = excludes_stack_overflow,
+ stackvars = "\tint fd;\n",
+ early_init = [[
+ fd = STDIN_FILENO;
+ if (!isatty(fd))
+ atf_tc_skip("stdin is not an fd");
+]]
+ },
},
}
@@ -551,6 +789,23 @@
fh:write([[
+static FILE * __unused
+new_fp(size_t __len)
+{
+ static char fpbuf[LINE_MAX];
+ FILE *fp;
+
+ ATF_REQUIRE(__len <= sizeof(fpbuf));
+
+ memset(fpbuf, 'A', sizeof(fpbuf) - 1);
+ fpbuf[sizeof(fpbuf) - 1] = '\0';
+
+ fp = fmemopen(fpbuf, sizeof(fpbuf), "rb");
+ ATF_REQUIRE(fp != NULL);
+
+ return (fp);
+}
+
/*
* Create a new symlink to use for readlink(2) style tests, we'll just use a
* random target name to have something interesting to look at.
@@ -609,6 +864,22 @@
setrlimit(RLIMIT_CORE, &rl);
}
+/*
+ * Replaces stdin with a file that we can actually read from, for tests where
+ * we want a FILE * or fd that we can get data from.
+ */
+static void __unused
+replace_stdin(void)
+{
+ int fd;
+
+ fd = new_tmpfile();
+
+ (void)dup2(fd, STDIN_FILENO);
+ if (fd != STDIN_FILENO)
+ close(fd);
+}
+
]])
for _, def in pairs(tests) do
diff --git a/sys/libkern/explicit_bzero.c b/sys/libkern/explicit_bzero.c
--- a/sys/libkern/explicit_bzero.c
+++ b/sys/libkern/explicit_bzero.c
@@ -9,6 +9,7 @@
#include <sys/libkern.h>
#else
#include <string.h>
+#include <ssp/ssp.h>
#endif /* _KERNEL */
__attribute__((weak)) void __explicit_bzero_hook(void *, size_t);
@@ -19,7 +20,7 @@
}
void
-explicit_bzero(void *buf, size_t len)
+__ssp_real(explicit_bzero)(void *buf, size_t len)
{
memset(buf, 0, len);
__explicit_bzero_hook(buf, len);
diff --git a/sys/sys/libkern.h b/sys/sys/libkern.h
--- a/sys/sys/libkern.h
+++ b/sys/sys/libkern.h
@@ -397,4 +397,10 @@
#define FNM_IGNORECASE FNM_CASEFOLD
#define FNM_FILE_NAME FNM_PATHNAME
+#if __has_include(<ssp/ssp.h>)
+#include <ssp/ssp.h> /* __ssp_real */
+#else
+#define __ssp_real(fun) fun
+#endif
+
#endif /* !_SYS_LIBKERN_H_ */

File Metadata

Mime Type
text/plain
Expires
Mon, Feb 9, 11:03 AM (21 m, 29 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28570975
Default Alt Text
D45679.id140080.diff (106 KB)

Event Timeline