From d08ae85ee42d1914e60bd2566c533db6ec3e3598 Mon Sep 17 00:00:00 2001 From: Dave Barach Date: Wed, 5 Dec 2018 08:41:11 -0500 Subject: Improve strncpy_s src/dst overlap check Let m = user estimate of the (max) src string length, low = smaller address of (src, dst), hi = larger address (src, dst). if (low + (m - 1) >= hi), we have a *potential* overlapping copy which is not allowed. Before we declare overlap - and return an error - retry the check with m = actual src string length. The resulting "test string" failure affected aarch64 (only) because of differences in test code stack variable placement / alignment. Change-Id: I2931d1ce2c61af3d3880075b033d2a4c4e421f09 Signed-off-by: Dave Barach --- src/vppinfra/string.h | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/vppinfra/string.h b/src/vppinfra/string.h index a25d461868b..d5686704c22 100644 --- a/src/vppinfra/string.h +++ b/src/vppinfra/string.h @@ -1031,10 +1031,20 @@ strncpy_s_inline (char *__restrict__ dest, rsize_t dmax, low = (uword) (src < dest ? src : dest); hi = (uword) (src < dest ? dest : src); + /* + * This check may fail innocently if src + dmax >= dst, but + * src + strlen(src) < dst. If it fails, check more carefully before + * blowing the whistle. + */ if (PREDICT_FALSE (low + (m - 1) >= hi)) { - clib_c11_violation ("src/dest overlap"); - return EINVAL; + m = clib_strnlen (src, m); + + if (low + (m - 1) >= hi) + { + clib_c11_violation ("src/dest overlap"); + return EINVAL; + } } clib_memcpy_fast (dest, src, m); -- cgit 1.2.3-korg