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);
}