mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-11-21 10:41:46 +01:00
include: ssp: round out fortification of current set of headers
ssp/ssp.h needed some improvements: - `len` isn't always a size_t, it may need casted - In some cases we may want to use a len that isn't specified as a parameter (e.g., L_ctermid), so __ssp_redirect() should be more flexible. - In other cases we may want additional checking, so pull all of the declaration bits out of __ssp_redirect_raw() so that some functions can implement the body themselves. strlcat/strlcpy should be the last of the fortified functions that get their own __*_chk symbols, and these cases are only done to be consistent with the rest of the str*() set. Reviewed by: markj Sponsored by: Klara, Inc. Sponsored by: Stormshield Differential Revision: https://reviews.freebsd.org/D45679
This commit is contained in:
parent
c10d567ea0
commit
cf8e5289a1
@ -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)
|
||||
|
||||
#include <machine/_stdint.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,
|
||||
|
@ -45,7 +45,9 @@ char *__stpncpy_chk(char *, const char *, size_t, size_t);
|
||||
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_icheck2_restrict(stpcpy, char *, const char *)
|
||||
__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(src, 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 @@ __END_DECLS
|
||||
#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 */
|
||||
|
@ -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_ */
|
||||
|
@ -43,14 +43,46 @@ __BEGIN_DECLS
|
||||
#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
|
||||
|
||||
|
@ -238,6 +238,21 @@ __END_DECLS
|
||||
#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 ferror(FILE *);
|
||||
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 @@ void rewind(FILE *);
|
||||
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 ungetc(int, FILE *);
|
||||
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 @@ int vsscanf(const char * __restrict, const char * __restrict, __va_list)
|
||||
__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 @@ extern int __isthreaded;
|
||||
__END_DECLS
|
||||
__NULLABILITY_PRAGMA_POP
|
||||
|
||||
#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
|
||||
#include <ssp/stdio.h>
|
||||
#endif
|
||||
#endif /* !_STDIO_H_ */
|
||||
|
@ -49,6 +49,10 @@ typedef __size_t size_t;
|
||||
#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 *memchr(const void *, int, size_t) __pure;
|
||||
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 @@ int strverscmp(const char *, const char *) __pure;
|
||||
#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 @@ char *strerror(int);
|
||||
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 @@ typedef __mode_t mode_t;
|
||||
|
||||
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 @@ errno_t memset_s(void *, rsize_t, int, rsize_t);
|
||||
#endif /* __EXT1_VISIBLE */
|
||||
__END_DECLS
|
||||
|
||||
#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
|
||||
#include <ssp/string.h>
|
||||
#endif
|
||||
#endif /* _STRING_H_ */
|
||||
|
@ -37,11 +37,15 @@ typedef __size_t size_t;
|
||||
#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 @@ int strncasecmp(const char *, const char *, size_t) __pure;
|
||||
#endif
|
||||
__END_DECLS
|
||||
|
||||
#if !defined(_STANDALONE) && defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0
|
||||
#include <ssp/strings.h>
|
||||
#endif
|
||||
#endif /* _STRINGS_H_ */
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 @@ ctermid(char *s)
|
||||
}
|
||||
|
||||
char *
|
||||
ctermid_r(char *s)
|
||||
__ssp_real(ctermid_r)(char *s)
|
||||
{
|
||||
|
||||
return (s != NULL ? ctermid(s) : NULL);
|
||||
|
@ -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;
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <ssp/ssp.h>
|
||||
|
||||
#include "libc_private.h"
|
||||
|
||||
@ -105,7 +106,7 @@ getentropy_fallback(void *buf, size_t buflen)
|
||||
}
|
||||
|
||||
int
|
||||
getentropy(void *buf, size_t buflen)
|
||||
__ssp_real(getentropy)(void *buf, size_t buflen)
|
||||
{
|
||||
ssize_t rd;
|
||||
bool have_getrandom;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -34,9 +34,10 @@
|
||||
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <ssp/ssp.h>
|
||||
|
||||
int
|
||||
gethostname(char *name, size_t namelen)
|
||||
__ssp_real(gethostname)(char *name, size_t namelen)
|
||||
{
|
||||
int mib[2];
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include <unistd.h>
|
||||
#include "namespace.h"
|
||||
#include <pthread.h>
|
||||
#include <ssp/ssp.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "libc_private.h"
|
||||
@ -54,7 +55,7 @@ getlogin(void)
|
||||
}
|
||||
|
||||
int
|
||||
getlogin_r(char *logname, size_t namelen)
|
||||
__ssp_real(getlogin_r)(char *logname, size_t namelen)
|
||||
{
|
||||
char tmpname[MAXLOGNAME];
|
||||
int len;
|
||||
|
@ -42,6 +42,7 @@
|
||||
#include <paths.h>
|
||||
#include <errno.h>
|
||||
#include "reentrant.h"
|
||||
#include <ssp/ssp.h>
|
||||
#include "un-namespace.h"
|
||||
|
||||
#include "libc_private.h"
|
||||
@ -53,7 +54,7 @@ static thread_key_t ttyname_key;
|
||||
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;
|
||||
|
||||
|
@ -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
|
||||
|
@ -15,7 +15,9 @@ FBSD_1.8 {
|
||||
__stpncpy_chk;
|
||||
__strcat_chk;
|
||||
__strcpy_chk;
|
||||
__strlcat_chk;
|
||||
__strncat_chk;
|
||||
__strlcpy_chk;
|
||||
__strncpy_chk;
|
||||
__vsnprintf_chk;
|
||||
__vsprintf_chk;
|
||||
|
70
lib/libc/secure/strlcat_chk.c
Normal file
70
lib/libc/secure/strlcat_chk.c
Normal file
@ -0,0 +1,70 @@
|
||||
/* $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
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#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
|
||||
* will be copied. Always NUL terminates (unless dsize <= strlen(dst)).
|
||||
* Returns strlen(src) + MIN(dsize, strlen(initial dst)).
|
||||
* If retval >= dsize, truncation occurred.
|
||||
*/
|
||||
size_t
|
||||
__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') {
|
||||
dst++;
|
||||
}
|
||||
|
||||
dlen = dst - odst;
|
||||
n = dsize - dlen;
|
||||
|
||||
if (n-- == 0)
|
||||
return (dlen + strlen(src));
|
||||
while (*src != '\0') {
|
||||
if (n != 0) {
|
||||
if (dbufsize-- == 0)
|
||||
__chk_fail();
|
||||
*dst++ = *src;
|
||||
n--;
|
||||
}
|
||||
|
||||
src++;
|
||||
}
|
||||
|
||||
if (dbufsize-- == 0)
|
||||
__chk_fail();
|
||||
*dst = '\0';
|
||||
return (dlen + (src - osrc)); /* count does not include NUL */
|
||||
}
|
43
lib/libc/secure/strlcpy_chk.c
Normal file
43
lib/libc/secure/strlcpy_chk.c
Normal file
@ -0,0 +1,43 @@
|
||||
/*-
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* Copyright (c) 2024, Klara, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
* POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ssp/string.h>
|
||||
#undef strlcpy
|
||||
|
||||
size_t
|
||||
__strlcpy_chk(char * __restrict dst, const char * __restrict src, size_t dsize,
|
||||
size_t dbufsize)
|
||||
{
|
||||
|
||||
if (dsize > dbufsize)
|
||||
__chk_fail();
|
||||
|
||||
return (strlcpy(dst, src, dsize));
|
||||
}
|
@ -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,8 @@
|
||||
*/
|
||||
|
||||
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;
|
||||
|
||||
|
@ -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 @@ _gets_s(char *buf, rsize_t n)
|
||||
|
||||
/* 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) {
|
||||
|
@ -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 @@ __warn_references(tmpnam,
|
||||
extern char *_mktemp(char *);
|
||||
|
||||
char *
|
||||
tmpnam(char *s)
|
||||
__ssp_real(tmpnam)(char *s)
|
||||
{
|
||||
static u_long tmpcount;
|
||||
static char buf[L_tmpnam];
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 @@ __strerror_rl(int errnum, char *strerrbuf, size_t buflen, locale_t locale)
|
||||
}
|
||||
|
||||
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()));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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).
|
||||
|
@ -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.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -20,6 +20,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.
|
||||
@ -79,6 +96,22 @@ disable_coredumps(void)
|
||||
_exit(EX_OSERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@ -211,6 +244,138 @@ monitor:
|
||||
|
||||
}
|
||||
|
||||
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(EX_SOFTWARE); /* Should have aborted. */
|
||||
|
||||
monitor:
|
||||
while (waitpid(__child, &__status, 0) != __child) {
|
||||
ATF_REQUIRE_EQ(EINTR, errno);
|
||||
}
|
||||
|
||||
if (!WIFSIGNALED(__status)) {
|
||||
switch (WEXITSTATUS(__status)) {
|
||||
case EX_SOFTWARE:
|
||||
atf_tc_fail("FORTIFY_SOURCE failed to abort");
|
||||
break;
|
||||
case EX_OSERR:
|
||||
atf_tc_fail("setrlimit(2) failed");
|
||||
break;
|
||||
default:
|
||||
atf_tc_fail("child exited with status %d",
|
||||
WEXITSTATUS(__status));
|
||||
}
|
||||
} else {
|
||||
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
|
||||
}
|
||||
#undef BUF
|
||||
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(memmove_before_end);
|
||||
ATF_TC_BODY(memmove_before_end, tc)
|
||||
{
|
||||
@ -917,6 +1082,155 @@ monitor:
|
||||
|
||||
}
|
||||
|
||||
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(EX_SOFTWARE); /* Should have aborted. */
|
||||
|
||||
monitor:
|
||||
while (waitpid(__child, &__status, 0) != __child) {
|
||||
ATF_REQUIRE_EQ(EINTR, errno);
|
||||
}
|
||||
|
||||
if (!WIFSIGNALED(__status)) {
|
||||
switch (WEXITSTATUS(__status)) {
|
||||
case EX_SOFTWARE:
|
||||
atf_tc_fail("FORTIFY_SOURCE failed to abort");
|
||||
break;
|
||||
case EX_OSERR:
|
||||
atf_tc_fail("setrlimit(2) failed");
|
||||
break;
|
||||
default:
|
||||
atf_tc_fail("child exited with status %d",
|
||||
WEXITSTATUS(__status));
|
||||
}
|
||||
} else {
|
||||
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
|
||||
}
|
||||
#undef BUF
|
||||
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(strncat_before_end);
|
||||
ATF_TC_BODY(strncat_before_end, tc)
|
||||
{
|
||||
@ -1215,6 +1529,155 @@ monitor:
|
||||
|
||||
}
|
||||
|
||||
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(EX_SOFTWARE); /* Should have aborted. */
|
||||
|
||||
monitor:
|
||||
while (waitpid(__child, &__status, 0) != __child) {
|
||||
ATF_REQUIRE_EQ(EINTR, errno);
|
||||
}
|
||||
|
||||
if (!WIFSIGNALED(__status)) {
|
||||
switch (WEXITSTATUS(__status)) {
|
||||
case EX_SOFTWARE:
|
||||
atf_tc_fail("FORTIFY_SOURCE failed to abort");
|
||||
break;
|
||||
case EX_OSERR:
|
||||
atf_tc_fail("setrlimit(2) failed");
|
||||
break;
|
||||
default:
|
||||
atf_tc_fail("child exited with status %d",
|
||||
WEXITSTATUS(__status));
|
||||
}
|
||||
} else {
|
||||
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
|
||||
}
|
||||
#undef BUF
|
||||
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(strncpy_before_end);
|
||||
ATF_TC_BODY(strncpy_before_end, tc)
|
||||
{
|
||||
@ -1371,6 +1834,11 @@ ATF_TP_ADD_TCS(tp)
|
||||
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);
|
||||
@ -1396,6 +1864,11 @@ ATF_TP_ADD_TCS(tp)
|
||||
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);
|
||||
@ -1406,6 +1879,11 @@ ATF_TP_ADD_TCS(tp)
|
||||
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);
|
||||
|
@ -20,6 +20,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.
|
||||
@ -79,6 +96,22 @@ disable_coredumps(void)
|
||||
_exit(EX_OSERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
@ -338,6 +371,133 @@ monitor:
|
||||
|
||||
}
|
||||
|
||||
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(EX_SOFTWARE); /* Should have aborted. */
|
||||
|
||||
monitor:
|
||||
while (waitpid(__child, &__status, 0) != __child) {
|
||||
ATF_REQUIRE_EQ(EINTR, errno);
|
||||
}
|
||||
|
||||
if (!WIFSIGNALED(__status)) {
|
||||
switch (WEXITSTATUS(__status)) {
|
||||
case EX_SOFTWARE:
|
||||
atf_tc_fail("FORTIFY_SOURCE failed to abort");
|
||||
break;
|
||||
case EX_OSERR:
|
||||
atf_tc_fail("setrlimit(2) failed");
|
||||
break;
|
||||
default:
|
||||
atf_tc_fail("child exited with status %d",
|
||||
WEXITSTATUS(__status));
|
||||
}
|
||||
} else {
|
||||
ATF_REQUIRE_EQ(SIGABRT, WTERMSIG(__status));
|
||||
}
|
||||
#undef BUF
|
||||
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, bcopy_before_end);
|
||||
@ -350,5 +510,10 @@ ATF_TP_ADD_TCS(tp)
|
||||
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());
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -96,6 +96,10 @@ local printf_init = [[
|
||||
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);
|
||||
@ -130,6 +134,53 @@ local string_init = [[
|
||||
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 = {
|
||||
@ -155,6 +206,27 @@ local all_tests = {
|
||||
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>
|
||||
@ -168,6 +240,16 @@ local all_tests = {
|
||||
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 = {
|
||||
@ -220,6 +302,17 @@ local all_tests = {
|
||||
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 = {
|
||||
@ -242,6 +335,17 @@ local all_tests = {
|
||||
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 = {
|
||||
@ -274,6 +378,14 @@ local all_tests = {
|
||||
},
|
||||
exclude = excludes_stack_overflow,
|
||||
},
|
||||
{
|
||||
func = "explicit_bzero",
|
||||
arguments = {
|
||||
"__buf",
|
||||
"__len",
|
||||
},
|
||||
exclude = excludes_stack_overflow,
|
||||
},
|
||||
},
|
||||
unistd = {
|
||||
-- <unistd.h>
|
||||
@ -286,6 +398,53 @@ local all_tests = {
|
||||
},
|
||||
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",
|
||||
@ -313,6 +472,85 @@ local all_tests = {
|
||||
path = new_symlink(__len); /* Cannot fail */
|
||||
]],
|
||||
},
|
||||
{
|
||||
func = "readlinkat",
|
||||
arguments = {
|
||||
"AT_FDCWD",
|
||||
"path",
|
||||
"__buf",
|
||||
"__len",
|
||||
},
|
||||
exclude = excludes_stack_overflow,
|
||||
stackvars = "\tconst char *path;\n",
|
||||
init = [[
|
||||
path = new_symlink(__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");
|
||||
]]
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -620,6 +858,23 @@ end
|
||||
|
||||
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.
|
||||
@ -679,6 +934,22 @@ disable_coredumps(void)
|
||||
_exit(EX_OSERR);
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ssp/ssp.h>
|
||||
|
||||
#define TESTDOMAIN ""
|
||||
#define TESTHOST "testhost"
|
||||
#define TESTFQDN "testhost" TESTDOMAIN
|
||||
@ -45,7 +47,7 @@ int tests = 0;
|
||||
* oddly configured systems.
|
||||
*/
|
||||
int
|
||||
gethostname(char *name, size_t namelen)
|
||||
__ssp_real(gethostname)(char *name, size_t namelen)
|
||||
{
|
||||
if (strlcpy(name, TESTFQDN, namelen) > namelen) {
|
||||
errno = ENAMETOOLONG;
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <ssp/ssp.h>
|
||||
|
||||
#define TESTDOMAIN ".domain.example.com"
|
||||
#define TESTHOST "testhost"
|
||||
#define TESTFQDN "testhost" TESTDOMAIN
|
||||
@ -45,7 +47,7 @@ int tests = 0;
|
||||
* oddly configured systems.
|
||||
*/
|
||||
int
|
||||
gethostname(char *name, size_t namelen)
|
||||
__ssp_real(gethostname)(char *name, size_t namelen)
|
||||
{
|
||||
if (strlcpy(name, TESTFQDN, namelen) > namelen) {
|
||||
errno = ENAMETOOLONG;
|
||||
|
@ -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 @@ __explicit_bzero_hook(void *buf, size_t len)
|
||||
}
|
||||
|
||||
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);
|
||||
|
@ -337,4 +337,10 @@ signed_extend32(uint32_t bitmap, int lsb, int width)
|
||||
#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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user