Support gcc FORTIFY_SOURCE features for nuttx libc
This function will use gcc's function __builtin_dynamic_object_size and __builtin_object_size Its function is to obtain the size of the object through compilation, so as to judge whether there are out-of-bounds operations in commonly used functions. It should be noted that the option -O2 and above is required to enable this function Signed-off-by: anjiahao <1090959677@qq.com>
This commit is contained in:
parent
880d78f903
commit
d5981375a6
12
Kconfig
12
Kconfig
@ -597,6 +597,18 @@ endmenu # Customize Header Files
|
||||
|
||||
menu "Debug Options"
|
||||
|
||||
config FORTIFY_SOURCE
|
||||
int "Fortify Source"
|
||||
default 0
|
||||
range 0 3
|
||||
---help---
|
||||
Detect overflows of buffers in common string and memory functions
|
||||
where the compiler can determine and validate the buffer sizes.
|
||||
0 does not have any checks.
|
||||
1 will only check for out-of-bounds at compile time.
|
||||
2 will only perform out-of-bounds checks on stack variables.
|
||||
3 On the basis of 2, add an out-of-bounds check for dynamically allocated variables.
|
||||
|
||||
config NDEBUG
|
||||
bool "Define NDEBUG globally"
|
||||
default !DEBUG_ASSERTIONS
|
||||
|
@ -87,6 +87,38 @@
|
||||
# define CONFIG_HAVE_BUILTIN_FFSLL 1
|
||||
# endif
|
||||
|
||||
# if CONFIG_FORTIFY_SOURCE > 0
|
||||
# if !defined(__OPTIMIZE__) || (__OPTIMIZE__) <= 0
|
||||
# warning requires compiling with optimization (-O2 or higher)
|
||||
# endif
|
||||
# if CONFIG_FORTIFY_SOURCE == 3
|
||||
# if __GNUC__ < 12 || (defined(__clang__) && __clang_major__ < 12)
|
||||
# error compiler version less than 12 does not support dynamic object size
|
||||
# endif
|
||||
|
||||
# define fortify_size(__o, type) __builtin_dynamic_object_size(__o, type)
|
||||
# else
|
||||
# define fortify_size(__o, type) __builtin_object_size(__o, type)
|
||||
# endif
|
||||
|
||||
# define fortify_assert(condition) do \
|
||||
{ \
|
||||
if (!(condition)) \
|
||||
{ \
|
||||
__builtin_trap(); \
|
||||
} \
|
||||
} \
|
||||
while (0)
|
||||
|
||||
# define fortify_va_arg_pack __builtin_va_arg_pack
|
||||
# define fortify_str(s) #s
|
||||
# define fortify_real(p,fn) __typeof__(fn) __real_##fn __asm__(fortify_str(p) #fn)
|
||||
# define fortify_function(fn) fortify_real(__USER_LABEL_PREFIX__, fn); \
|
||||
extern __inline__ \
|
||||
__attribute__((__always_inline__, \
|
||||
__gnu_inline__, __artificial__))
|
||||
# endif
|
||||
|
||||
/* Pre-processor */
|
||||
|
||||
# define CONFIG_CPP_HAVE_VARARGS 1 /* Supports variable argument macros */
|
||||
|
@ -244,6 +244,67 @@ int pclose(FILE *stream);
|
||||
FILE *popen(FAR const char *command, FAR const char *mode) popen_like;
|
||||
#endif
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(fgets) FAR char *fgets(FAR char *s, int n, FAR FILE *stream)
|
||||
{
|
||||
fortify_assert((size_t)n <= fortify_size(s, 0));
|
||||
return __real_fgets(s, n, stream);
|
||||
}
|
||||
|
||||
fortify_function(fread) size_t fread(FAR void *ptr, size_t size,
|
||||
size_t n_items, FAR FILE *stream)
|
||||
{
|
||||
fortify_assert(n_items == 0 || (n_items * size) / n_items == size);
|
||||
fortify_assert(n_items * size <= fortify_size(ptr, 0));
|
||||
return __real_fread(ptr, size, n_items, stream);
|
||||
}
|
||||
|
||||
fortify_function(fwrite) size_t fwrite(FAR const void *ptr, size_t size,
|
||||
size_t n_items, FAR FILE *stream)
|
||||
{
|
||||
fortify_assert(n_items == 0 || (n_items * size) / n_items == size);
|
||||
fortify_assert(n_items * size <= fortify_size(ptr, 0));
|
||||
return __real_fwrite(ptr, size, n_items, stream);
|
||||
}
|
||||
|
||||
fortify_function(vsnprintf) int vsnprintf(FAR char *buf, size_t size,
|
||||
FAR const IPTR char *format,
|
||||
va_list ap)
|
||||
{
|
||||
fortify_assert(size <= fortify_size(buf, 0));
|
||||
return __real_vsnprintf(buf, size, format, ap);
|
||||
}
|
||||
|
||||
fortify_function(vsprintf) int vsprintf(FAR char *dest,
|
||||
FAR const IPTR char *src,
|
||||
va_list ap)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __real_vsprintf(dest, src, ap);
|
||||
fortify_assert(ret == -1 || (size_t)ret <= fortify_size(dest, 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
fortify_function(snprintf) int snprintf(FAR char *buf, size_t size,
|
||||
FAR const IPTR char *format, ...)
|
||||
{
|
||||
fortify_assert(size <= fortify_size(buf, 0));
|
||||
return __real_snprintf(buf, size, format, fortify_va_arg_pack());
|
||||
}
|
||||
|
||||
fortify_function(sprintf) int sprintf(FAR char *buf,
|
||||
FAR const IPTR char *fmt,
|
||||
...)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __real_sprintf(buf, fmt, fortify_va_arg_pack());
|
||||
fortify_assert(ret == -1 || (size_t)ret <= fortify_size(buf, 0));
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -291,6 +291,29 @@ FAR const char *getprogname(void);
|
||||
int __cxa_atexit(CODE void (*func)(FAR void *), FAR void *arg,
|
||||
FAR void *dso_handle);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(realpath) FAR char *realpath(FAR const char *path,
|
||||
FAR char *resolved)
|
||||
{
|
||||
FAR char *ret = __real_realpath(path, resolved);
|
||||
if (ret != NULL && resolved != NULL)
|
||||
{
|
||||
size_t len = 1;
|
||||
FAR char *p;
|
||||
|
||||
p = ret;
|
||||
while (*p++ != '\0')
|
||||
{
|
||||
len++;
|
||||
}
|
||||
|
||||
fortify_assert(len <= fortify_size(resolved, 0));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
101
include/string.h
101
include/string.h
@ -108,6 +108,107 @@ FAR void *memmem(FAR const void *haystack, size_t haystacklen,
|
||||
void explicit_bzero(FAR void *s, size_t n);
|
||||
int timingsafe_bcmp(FAR const void *b1, FAR const void *b2, size_t n);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(strcat) FAR char *strcat(FAR char *dest,
|
||||
FAR const char *src)
|
||||
{
|
||||
fortify_assert(strlen(dest) + strlen(src) + 1 <= fortify_size(dest, 0));
|
||||
return __real_strcat(dest, src);
|
||||
}
|
||||
|
||||
fortify_function(strlcat) size_t strlcat(FAR char *dst,
|
||||
FAR const char *src,
|
||||
size_t dsize)
|
||||
{
|
||||
fortify_assert(dsize <= fortify_size(dst, 0));
|
||||
return __real_strlcat(dst, src, dsize);
|
||||
}
|
||||
|
||||
fortify_function(strncat) FAR char *strncat(FAR char *dest,
|
||||
FAR const char *src,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(dest, 0));
|
||||
return __real_strncat(dest, src, n);
|
||||
}
|
||||
|
||||
fortify_function(strcpy) FAR char *strcpy(FAR char *dest,
|
||||
FAR const char *src)
|
||||
{
|
||||
fortify_assert(strlen(src) + 1 <= fortify_size(dest, 0));
|
||||
return __real_strcpy(dest, src);
|
||||
}
|
||||
|
||||
fortify_function(stpcpy) FAR char *stpcpy(FAR char *dest,
|
||||
FAR const char *src)
|
||||
{
|
||||
fortify_assert(strlen(src) + 1 <= fortify_size(dest, 0));
|
||||
return __real_stpcpy(dest, src);
|
||||
}
|
||||
|
||||
fortify_function(stpncpy) FAR char *stpncpy(FAR char *dest,
|
||||
FAR const char *src,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(dest, 0));
|
||||
return __real_stpncpy(dest, src, n);
|
||||
}
|
||||
|
||||
fortify_function(strlcpy) size_t strlcpy(FAR char *dst,
|
||||
FAR const char *src,
|
||||
size_t siz)
|
||||
{
|
||||
fortify_assert(siz <= fortify_size(dst, 0));
|
||||
return __real_strlcpy(dst, src, siz);
|
||||
}
|
||||
|
||||
fortify_function(strncpy) FAR char *strncpy(FAR char *dest,
|
||||
FAR const char *src,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(dest, 0));
|
||||
return __real_strncpy(dest, src, n);
|
||||
}
|
||||
|
||||
fortify_function(memmove) FAR void *memmove(FAR void *dest,
|
||||
FAR const void *src,
|
||||
size_t count)
|
||||
{
|
||||
fortify_assert(count <= fortify_size(dest, 0) &&
|
||||
count <= fortify_size(src, 0));
|
||||
return __real_memmove(dest, src, count);
|
||||
}
|
||||
|
||||
fortify_function(memcpy) FAR void *memcpy(FAR void *dest,
|
||||
FAR const void *src,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(dest, 0) && n <= fortify_size(src, 0));
|
||||
return __real_memcpy(dest, src, n);
|
||||
}
|
||||
|
||||
fortify_function(memset) FAR void *memset(FAR void *s, int c, size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(s, 0));
|
||||
return __real_memset(s, c, n);
|
||||
}
|
||||
|
||||
fortify_function(mempcpy) FAR void *mempcpy(FAR void *dest,
|
||||
FAR const void *src,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(dest, 0) && n <= fortify_size(src, 0));
|
||||
return __real_mempcpy(dest, src, n);
|
||||
}
|
||||
|
||||
fortify_function(explicit_bzero) void explicit_bzero(FAR void *s,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(s, 0));
|
||||
__real_explicit_bzero(s, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -93,6 +93,14 @@ int strncasecmp(FAR const char *, FAR const char *, size_t);
|
||||
|
||||
void bzero(FAR void *s, size_t n);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(bzero) void bzero(FAR void *s, size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(s, 0));
|
||||
return bzero(s, n);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -149,6 +149,23 @@ int poll_fdsetup(int fd, FAR struct pollfd *fds, bool setup);
|
||||
void poll_default_cb(FAR struct pollfd *fds);
|
||||
void poll_notify(FAR struct pollfd **afds, int nfds, pollevent_t eventset);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(poll) int poll(FAR struct pollfd *fds,
|
||||
nfds_t nfds, int timeout)
|
||||
{
|
||||
fortify_assert(nfds <= fortify_size(fds, 0) / sizeof(struct pollfd));
|
||||
return __real_poll(fds, nfds, timeout);
|
||||
}
|
||||
|
||||
fortify_function(ppoll) int ppoll(FAR struct pollfd *fds, nfds_t nfds,
|
||||
FAR const struct timespec *timeout_ts,
|
||||
FAR const sigset_t *sigmask)
|
||||
{
|
||||
fortify_assert(nfds <= fortify_size(fds, 0) / sizeof(struct pollfd));
|
||||
return __real_ppoll(fds, nfds, timeout_ts, sigmask);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -435,6 +435,40 @@ int getpeername(int sockfd, FAR struct sockaddr *addr,
|
||||
ssize_t recvmsg(int sockfd, FAR struct msghdr *msg, int flags);
|
||||
ssize_t sendmsg(int sockfd, FAR struct msghdr *msg, int flags);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(send) ssize_t send(int sockfd, FAR const void *buf,
|
||||
size_t len, int flags)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(buf, 0));
|
||||
return __real_send(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
fortify_function(sendto) ssize_t sendto(int sockfd, FAR const void *buf,
|
||||
size_t len, int flags,
|
||||
FAR const struct sockaddr *to,
|
||||
socklen_t tolen)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(buf, 0));
|
||||
return __real_sendto(sockfd, buf, len, flags, to, tolen);
|
||||
}
|
||||
|
||||
fortify_function(recv) ssize_t recv(int sockfd, FAR void *buf,
|
||||
size_t len, int flags)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(buf, 0));
|
||||
return __real_recv(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
fortify_function(recvfrom) ssize_t recvfrom(int sockfd, FAR void *buf,
|
||||
size_t len, int flags,
|
||||
FAR struct sockaddr *from,
|
||||
FAR socklen_t *fromlen)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(buf, 0));
|
||||
return __real_recvfrom(sockfd, buf, len, flags, from, fromlen);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
@ -434,6 +434,74 @@ int getentropy(FAR void *buffer, size_t length);
|
||||
|
||||
void sync(void);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(getcwd) FAR char *getcwd(FAR char *buf,
|
||||
size_t size)
|
||||
{
|
||||
fortify_assert(size <= fortify_size(buf, 0));
|
||||
return __real_getcwd(buf, size);
|
||||
}
|
||||
|
||||
fortify_function(gethostname) int gethostname(FAR char *name,
|
||||
size_t namelen)
|
||||
{
|
||||
fortify_assert(namelen <= fortify_size(name, 0));
|
||||
return __real_gethostname(name, namelen);
|
||||
}
|
||||
|
||||
fortify_function(pread) ssize_t pread(int fd, FAR void *buf,
|
||||
size_t nbytes, off_t offset)
|
||||
{
|
||||
fortify_assert(nbytes <= fortify_size(buf, 0));
|
||||
return __real_pread(fd, buf, nbytes, offset);
|
||||
}
|
||||
|
||||
fortify_function(read) ssize_t read(int fd, FAR void *buf,
|
||||
size_t nbytes)
|
||||
{
|
||||
fortify_assert(nbytes <= fortify_size(buf, 0));
|
||||
return __real_read(fd, buf, nbytes);
|
||||
}
|
||||
|
||||
fortify_function(readlink) ssize_t readlink(FAR const char *path,
|
||||
FAR char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
fortify_assert(bufsize <= fortify_size(buf, 0));
|
||||
return __real_readlink(path, buf, bufsize);
|
||||
}
|
||||
|
||||
fortify_function(readlinkat) ssize_t readlinkat(int dirfd,
|
||||
FAR const char *path,
|
||||
FAR char *buf,
|
||||
size_t bufsize)
|
||||
{
|
||||
fortify_assert(bufsize <= fortify_size(buf, 0));
|
||||
return __real_readlinkat(dirfd, path, buf, bufsize);
|
||||
}
|
||||
|
||||
fortify_function(ttyname_r) int ttyname_r(int fd, FAR char *buf,
|
||||
size_t buflen)
|
||||
{
|
||||
fortify_assert(buflen <= fortify_size(buf, 0));
|
||||
return __real_ttyname_r(fd, buf, buflen);
|
||||
}
|
||||
|
||||
fortify_function(pwrite) ssize_t pwrite(int fd, FAR const void *buf,
|
||||
size_t nbytes, off_t offset)
|
||||
{
|
||||
fortify_assert(nbytes <= fortify_size(buf, 0));
|
||||
return __real_pwrite(fd, buf, nbytes, offset);
|
||||
}
|
||||
|
||||
fortify_function(write) ssize_t write(int fd, FAR const void *buf,
|
||||
size_t nbytes)
|
||||
{
|
||||
fortify_assert(nbytes <= fortify_size(buf, 0));
|
||||
return __real_write(fd, buf, nbytes);
|
||||
}
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
|
127
include/wchar.h
127
include/wchar.h
@ -218,6 +218,133 @@ FAR wchar_t *wmemset(FAR wchar_t *, wchar_t, size_t);
|
||||
int wprintf(FAR const wchar_t *, ...);
|
||||
int wscanf(FAR const wchar_t *, ...);
|
||||
|
||||
#if CONFIG_FORTIFY_SOURCE > 0
|
||||
fortify_function(fgetws) FAR wchar_t *fgetws(FAR wchar_t *s, int n,
|
||||
FAR FILE *stream)
|
||||
{
|
||||
fortify_assert((size_t)n <= fortify_size(s, 0) / sizeof(wchar_t));
|
||||
return __real_fgetws(s, n, stream);
|
||||
}
|
||||
|
||||
fortify_function(mbsnrtowcs) size_t mbsnrtowcs(FAR wchar_t *dst,
|
||||
FAR const char **src,
|
||||
size_t nms,
|
||||
size_t len,
|
||||
FAR mbstate_t *ps)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_mbsnrtowcs(dst, src, nms, len, ps);
|
||||
}
|
||||
|
||||
fortify_function(mbsrtowcs) size_t mbsrtowcs(FAR wchar_t *dst,
|
||||
FAR const char **src,
|
||||
size_t len,
|
||||
FAR mbstate_t *ps)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_mbsrtowcs(dst, src, len, ps);
|
||||
}
|
||||
|
||||
fortify_function(wcrtomb) size_t wcrtomb(FAR char *s, wchar_t wc,
|
||||
FAR mbstate_t *ps)
|
||||
{
|
||||
size_t ret = __real_wcrtomb(s, wc, ps);
|
||||
|
||||
fortify_assert(s == NULL || ret <= fortify_size(s, 0));
|
||||
return ret;
|
||||
}
|
||||
|
||||
fortify_function(wcscpy) FAR wchar_t *wcscpy(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src)
|
||||
{
|
||||
fortify_assert(wcslen(src) + 1 <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcscpy(dst, src);
|
||||
}
|
||||
|
||||
fortify_function(wcslcpy) size_t wcslcpy(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src,
|
||||
size_t siz)
|
||||
{
|
||||
fortify_assert(siz <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcslcpy(dst, src, siz);
|
||||
}
|
||||
|
||||
fortify_function(wcscat) FAR wchar_t *wcscat(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src)
|
||||
{
|
||||
fortify_assert(wcslen(dst) + wcslen(src) + 1 <=
|
||||
fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcscat(dst, src);
|
||||
}
|
||||
|
||||
fortify_function(wcsncat) FAR wchar_t *wcsncat(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src,
|
||||
size_t siz)
|
||||
{
|
||||
fortify_assert(siz <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcsncat(dst, src, siz);
|
||||
}
|
||||
|
||||
fortify_function(wcslcat) size_t wcslcat(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src,
|
||||
size_t siz)
|
||||
{
|
||||
fortify_assert(siz <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcslcat(dst, src, siz);
|
||||
}
|
||||
|
||||
fortify_function(wcsncpy) FAR wchar_t *wcsncpy(FAR wchar_t *dst,
|
||||
FAR const wchar_t *src,
|
||||
size_t siz)
|
||||
{
|
||||
fortify_assert(siz <= fortify_size(dst, 0) / sizeof(wchar_t));
|
||||
return __real_wcsncpy(dst, src, siz);
|
||||
}
|
||||
|
||||
fortify_function(wcsnrtombs) size_t wcsnrtombs(FAR char *dst,
|
||||
FAR const wchar_t **src,
|
||||
size_t nwc, size_t len,
|
||||
FAR mbstate_t *ps)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(dst, 0));
|
||||
return __real_wcsnrtombs(dst, src, nwc, len, ps);
|
||||
}
|
||||
|
||||
fortify_function(wcsrtombs) size_t wcsrtombs(FAR char *dst,
|
||||
FAR const wchar_t **src,
|
||||
size_t len,
|
||||
FAR mbstate_t *ps)
|
||||
{
|
||||
fortify_assert(len <= fortify_size(dst, 0));
|
||||
return __real_wcsrtombs(dst, src, len, ps);
|
||||
}
|
||||
|
||||
fortify_function(wmemcpy) FAR wchar_t *wmemcpy(FAR wchar_t *d,
|
||||
FAR const wchar_t *s,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(d, 0) / sizeof(wchar_t));
|
||||
return __real_wmemcpy(d, s, n);
|
||||
}
|
||||
|
||||
fortify_function(wmemmove) FAR wchar_t *wmemmove(FAR wchar_t *d,
|
||||
FAR const wchar_t *s,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(d, 0) / sizeof(wchar_t));
|
||||
return __real_wmemmove(d, s, n);
|
||||
}
|
||||
|
||||
fortify_function(wmemset) FAR wchar_t *wmemset(FAR wchar_t *s,
|
||||
wchar_t c,
|
||||
size_t n)
|
||||
{
|
||||
fortify_assert(n <= fortify_size(s, 0) / sizeof(wchar_t));
|
||||
return __real_wmemset(s, c, n);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user