On Mon, Dec 06, 2021 at 01:47:52PM -0700, Todd C. Miller wrote:
> On Mon, 06 Dec 2021 09:03:43 -0600, Scott Cheloha wrote:
> 
> > In lsearch(3), the key is allowed to overlap with the last element in
> > base.  We need to memmove(3), not memcpy(3), or we could corrupt the
> > key in that edge case.
> 
> OK, but does this deserve a comment so to that effect to prevent
> someone from changing it back to memcpy() in the future?

Probably.  This is an obscure edge case.

To be clear:

If key partially overlaps base[*nelp] then lsearch(3) will mutate the
key.  We can't do anything about that.  However, if we use memmove(3)
we at least ensure that key is copied cleanly to base[*nelp].  So, the
key will still be mutated but the original value of the key will be at
base[*nelp] when we return.

I think that's preferable to mutating key *and* copying a corrupted
key to base[*nelp], no?

Index: lsearch.c
===================================================================
RCS file: /cvs/src/lib/libc/stdlib/lsearch.c,v
retrieving revision 1.5
diff -u -p -r1.5 lsearch.c
--- lsearch.c   18 Jul 2014 04:16:09 -0000      1.5
+++ lsearch.c   6 Dec 2021 21:59:48 -0000
@@ -79,6 +79,11 @@ linear_base(const void *key, const void 
         * manual.
         */
        ++*nelp;
-       memcpy((void *)end, key, width);
+
+       /*
+        * Use memmove(3) instead of memcpy(3), just in case key
+        * partially overlaps with the end of the array.
+        */
+       memmove((void *)end, key, width);
        return((void *)end);
 }

Reply via email to