Further improvements to memcpy_s(), memset_s(), and their man pages.

This commit is contained in:
Dag-Erling Smørgrav 2018-05-06 18:33:32 +02:00
parent a1bf5e87f0
commit 354759a9f2
9 changed files with 93 additions and 44 deletions

View file

@ -51,6 +51,7 @@ AC_TYPE_UINT8_T
AC_TYPE_UINTMAX_T
AC_TYPE_UINTPTR_T
AC_CHECK_TYPES([errno_t], [], [], [[#include <errno.h>]])
AC_CHECK_TYPES([rsize_t], [], [], [[#include <stdint.h>]])
AC_CHECK_DECL([RSIZE_MAX], [], [], [[#include <stdint.h>]])
@ -119,8 +120,6 @@ AC_CHECK_HEADERS([sys/resource.h])
AC_CHECK_FUNCS([setrlimit])
# C11 features
# XXX our version has an incorrect prototype due to the lack of a test
# for the existence of rsize_t and RSIZE_MAX.
AC_CHECK_FUNCS([memcpy_s memset_s])
############################################################################

View file

@ -24,12 +24,12 @@ cryb_HEADERS += \
endian.h \
memcpy_s.h \
memset_s.h \
rsize.h \
strchrnul.h \
string.h \
strlcat.h \
strlcmp.h \
strlcpy.h \
types.h \
wcschrnul.h \
wcslcat.h \
wcslcmp.h \

View file

@ -34,13 +34,14 @@
#include <cryb/to.h>
#endif
#ifndef CRYB_RSIZE_H_INCLUDED
#include <cryb/rsize.h>
#ifndef CRYB_TYPES_H_INCLUDED
#include <cryb/types.h>
#endif
CRYB_BEGIN
int cryb_memcpy_s(void *, rsize_t, const void *, rsize_t);
errno_t cryb_memcpy_s(void * restrict, rsize_t, const void * restrict,
rsize_t);
#if !HAVE_MEMCPY_S
#undef memcpy_s

View file

@ -34,13 +34,13 @@
#include <cryb/to.h>
#endif
#ifndef CRYB_RSIZE_H_INCLUDED
#include <cryb/rsize.h>
#ifndef CRYB_TYPES_H_INCLUDED
#include <cryb/types.h>
#endif
CRYB_BEGIN
int cryb_memset_s(void *, rsize_t, int, rsize_t);
errno_t cryb_memset_s(void *, rsize_t, int, rsize_t);
#if !HAVE_MEMSET_S
#undef memset_s

View file

@ -27,8 +27,12 @@
* SUCH DAMAGE.
*/
#ifndef CRYB_RSIZE_H_INCLUDED
#define CRYB_RSIZE_H_INCLUDED
#ifndef CRYB_TYPES_H_INCLUDED
#define CRYB_TYPES_H_INCLUDED
#if !HAVE_ERRNO_T
typedef int errno_t;
#endif
#if !HAVE_RSIZE_T
typedef size_t rsize_t;

View file

@ -1,5 +1,5 @@
.\"-
.\" Copyright (c) 2015 Universitetet i Oslo
.\" Copyright (c) 2015-2018 Universitetet i Oslo
.\" All rights reserved.
.\"
.\" Redistribution and use in source and binary forms, with or without
@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 15, 2015
.Dd May 6, 2018
.Dt cryb_memcpy_s 3
.Os
.Sh NAME
@ -36,8 +36,8 @@
.Lb libcryb-core
.Sh SYNOPSIS
.In cryb/memcpy_s.h
.Ft void *
.Fn cryb_memcpy_s "void *d" "size_t dsz" "const void *s" "size_t n"
.Ft errno_t
.Fn cryb_memcpy_s "void * restrict d" "rsize_t dsz" "const void * restrict s" "rsize_t n"
.Sh DESCRIPTION
The
.Nm cryb_memcpy_s
@ -57,7 +57,7 @@ is
is greater than
.Va dsz
or
.Dv SIZE_MAX
.Dv RSIZE_MAX
or the source and destination overlap, the buffer pointed to by
.Va d
is filled with zeroes and an error is returned.
@ -98,17 +98,36 @@ header provides a
macro as an alias to
.Fn cryb_memcpy_s .
.Pp
The argument and return types for
.Nm
differ from those of its C11 equivalent, as it is expected to be used
in environments in which
.Vt rsize_t
Software that includes
.In cryb/memcpy_s.h
should ensure that the
.Dv HAVE_ERRNO_T ,
.Dv HAVE_RSIZE_T ,
.Dv HAVE_RSIZE_MAX
and
.Dv RSIZE_MAX
are not defined.
.Dv HAVE_MEMCPY_S
macros correctly reflect the availability of these features at compile
time.
For projects that use the GNU autotools, this can be achieved by
including the following code in
.Pa configure.ac :
.Bd -literal -offset indent
AC_CHECK_TYPES([errno_t], [], [], [[#include <errno.h>]])
AC_CHECK_TYPES([rsize_t], [], [], [[#include <stdint.h>]])
AC_CHECK_DECL([RSIZE_MAX], [], [], [[#include <stdint.h>]])
AC_CHECK_FUNCS([memcpy_s])
.Ed
.Sh SEE ALSO
.Xr cryb_memset_s 3 ,
.Xr memcpy 3
.Sh STANDARDS
The
.Fn cryb_memcpy_s
function is equivalent to the
.Fn memcpy_s
function described in ISO/IEC 9899:2011
.Pq Dq C11
section K.3.7.1.1.
.Sh AUTHORS
The
.Fn cryb_memcpy_s

View file

@ -32,7 +32,6 @@
#endif
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
@ -43,10 +42,15 @@
/*
* Like memcpy(), but checks for overflow and overwrites the destination
* range with zeroes on error.
*
* ISO/IEC 9899:2011 K.3.7.1.1
*/
int
cryb_memcpy_s(void *d, rsize_t dsz, const void *s, rsize_t n)
errno_t
cryb_memcpy_s(void * restrict d, rsize_t dsz, const void * restrict s,
rsize_t n)
{
volatile uint8_t *D;
const uint8_t *S;
unsigned int i;
/* unrecoverable errors */
@ -71,7 +75,7 @@ CRYB_DISABLE_COVERAGE
CRYB_RESTORE_COVERAGE
return (EINVAL);
}
for (i = 0; i < dsz && i < n; ++i)
((volatile uint8_t *)d)[i] = ((const uint8_t *)s)[i];
for (D = d, S = s, i = 0; i < dsz && i < n; ++i)
D[i] = S[i];
return (0);
}

View file

@ -26,7 +26,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
.Dd December 15, 2015
.Dd May 6, 2018
.Dt cryb_memset_s 3
.Os
.Sh NAME
@ -36,8 +36,8 @@
.Lb libcryb-core
.Sh SYNOPSIS
.In cryb/memset_s.h
.Ft void *
.Fn cryb_memset_s "void *d" "size_t dsz" "int ch" "size_t n"
.Ft errno_t
.Fn cryb_memset_s "void *d" "rsize_t dsz" "int ch" "rsize_t n"
.Sh DESCRIPTION
The
.Nm cryb_memset_s
@ -74,7 +74,7 @@ Either or both of the
and
.Va n
arguments were greater than
.Dv SIZE_MAX .
.Dv RSIZE_MAX .
.It Bq Er EOVERFLOW
The
.Va n
@ -92,17 +92,36 @@ header provides a
macro as an alias to
.Fn cryb_memset_s .
.Pp
The argument and return types for
.Nm
differ from those of its C11 equivalent, as it is expected to be used
in environments in which
.Vt rsize_t
Software that includes
.In cryb/memset_s.h
should ensure that the
.Dv HAVE_ERRNO_T ,
.Dv HAVE_RSIZE_T ,
.Dv HAVE_RSIZE_MAX
and
.Dv RSIZE_MAX
are not defined.
.Dv HAVE_MEMSET_S
macros correctly reflect the availability of these features at compile
time.
For projects that use the GNU autotools, this can be achieved by
including the following code in
.Pa configure.ac :
.Bd -literal -offset indent
AC_CHECK_TYPES([errno_t], [], [], [[#include <errno.h>]])
AC_CHECK_TYPES([rsize_t], [], [], [[#include <stdint.h>]])
AC_CHECK_DECL([RSIZE_MAX], [], [], [[#include <stdint.h>]])
AC_CHECK_FUNCS([memset_s])
.Ed
.Sh SEE ALSO
.Xr cryb_memcpy_s 3 ,
.Xr memset 3
.Sh STANDARDS
The
.Fn cryb_memset_s
function is equivalent to the
.Fn memset_s
function described in ISO/IEC 9899:2011
.Pq Dq C11
section K.3.7.4.1.
.Sh AUTHORS
The
.Fn cryb_memset_s

View file

@ -32,7 +32,6 @@
#endif
#include <errno.h>
#include <limits.h>
#include <stdint.h>
#include <string.h>
@ -42,11 +41,15 @@
/*
* Like memset(), but checks for overflow and guarantees that the buffer
* is overwritten even if the data will never be read.
*
* ISO/IEC 9899:2011 K.3.7.4.1
*/
int
cryb_memset_s(void *d, rsize_t dsz, int ch, rsize_t n)
errno_t
cryb_memset_s(void *d, rsize_t dsz, int c, rsize_t n)
{
volatile uint8_t *D;
unsigned int i;
uint8_t C;
if (d == NULL)
return (EINVAL);
@ -54,8 +57,8 @@ CRYB_DISABLE_COVERAGE
if (dsz > RSIZE_MAX || n > RSIZE_MAX)
return (ERANGE);
CRYB_RESTORE_COVERAGE
for (i = 0; i < n && i < dsz; ++i)
((volatile uint8_t *)d)[i] = (uint8_t)ch;
for (D = d, C = (uint8_t)c, i = 0; i < n && i < dsz; ++i)
D[i] = C;
if (n > dsz)
return (EOVERFLOW);
return (0);