See https://gerrit.fd.io/r/#/c/16352, which computes strlen if necessary for a 
precise copy-overlap check. Strncpy_s was always slightly wrong in this regard.

The "make test" failure showed up [only] on aarch64 due to test code stack 
variable placement / alignment differences between aarch64 and x86_64.

HTH... Dave

From: Lijian Zhang (Arm Technology China) <lijian.zh...@arm.com>
Sent: Wednesday, December 5, 2018 4:39 AM
To: Dave Barach (dbarach) <dbar...@cisco.com>
Cc: Juraj Linkeš <juraj.lin...@pantheon.tech>; Dave Barach (dbarach) 
<dbar...@cisco.com>; Damjan Marion <dmar...@me.com>
Subject: String tests failures

Hi Dave,
StringTest is failing on ARM machines.
I narrowed down the problem and commit an internal code review as below.
Once the internal code review process is passed, I'll upstream the patch for 
community review.

#define clib_strncpy(d,s,n) strncpy_s_inline(d,CLIB_STRING_MACRO_MAX,s,n)

errno_t
strncpy_s (char *__restrict__ dest, rsize_t dmax,
           const char *__restrict__ src, rsize_t n);

always_inline errno_t
strncpy_s_inline (char *__restrict__ dest, rsize_t dmax,
                  const char *__restrict__ src, rsize_t n)
{
   u8 bad;
   uword low, hi;
   rsize_t m;
   errno_t status = EOK;

   bad = (dest == 0) + (dmax == 0) + (src == 0) + (n == 0);
   if (PREDICT_FALSE (bad != 0))
     {
       /* Not actually trying to copy anything is OK */
       if (n == 0)
        return EOK;
       if (dest == 0)
        clib_c11_violation ("dest NULL");
       if (src == 0)
        clib_c11_violation ("src NULL");
       if (dmax == 0)
        clib_c11_violation ("dmax 0");
       return EINVAL;
     }

   if (PREDICT_FALSE (n >= dmax))
     {
       /* Relax and use strnlen of src */
       clib_c11_violation ("n >= dmax");
       m = clib_strnlen (src, dmax);
       if (m >= dmax)
        {
          /* Truncate, adjust copy length to fit dest */
          m = dmax - 1;
          status = EOVERFLOW;
        }
     }
   else
-    m = n;
+    m = clib_strnlen (src, n);

   /* Check for src/dst overlap, which is not allowed */
   low = (uword) (src < dest ? src : dest);
   hi = (uword) (src < dest ? dest : src);

   if (PREDICT_FALSE (low + (m - 1) >= hi))
     {
       clib_c11_violation ("src/dest overlap");
       return EINVAL;
     }

   clib_memcpy_fast (dest, src, m);
   dest[m] = '\0';
   return status;
}
IMPORTANT NOTICE: The contents of this email and any attachments are 
confidential and may also be privileged. If you are not the intended recipient, 
please notify the sender immediately and do not disclose the contents to any 
other person, use it for any purpose, or store or copy the information in any 
medium. Thank you.
-=-=-=-=-=-=-=-=-=-=-=-
Links: You receive all messages sent to this group.

View/Reply Online (#11497): https://lists.fd.io/g/vpp-dev/message/11497
Mute This Topic: https://lists.fd.io/mt/28611039/21656
Group Owner: vpp-dev+ow...@lists.fd.io
Unsubscribe: https://lists.fd.io/g/vpp-dev/unsub  [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-

Reply via email to