avoid various use-after-free issues. create a ptrdiff_t offset between the start of an allocation region and some interesting pointer, so it can be adjusted with this offset after realloc() returns. for pdisk(), realloc() is a locally inlind malloc() and free() pair. for mail(1), this required a little bit more effort as the old pointer was passed into another file for fix-ups there, and that code needed to be adjusted for offset vs old pointer usage. found by GCC 12. Index: external/bsd/pdisk/dist/io.c =================================================================== RCS file: /cvsroot/src/external/bsd/pdisk/dist/io.c,v retrieving revision 1.2 diff -p -u -r1.2 io.c --- external/bsd/pdisk/dist/io.c 23 Mar 2013 15:39:43 -0000 1.2 +++ external/bsd/pdisk/dist/io.c 8 Aug 2023 20:22:36 -0000 @@ -328,6 +328,7 @@ get_string(int eos) char *ret_value; char *limit; int length; + ptrdiff_t off; ret_value = (char *) malloc(STRING_CHUNK); if (ret_value == NULL) { @@ -348,8 +349,9 @@ get_string(int eos) break; } strncpy(limit, ret_value, length); + off = s - ret_value; free(ret_value); - s = limit + (s - ret_value); + s = limit + off; ret_value = limit; length += STRING_CHUNK; limit = ret_value + length; Index: usr.bin/rs/rs.c =================================================================== RCS file: /cvsroot/src/usr.bin/rs/rs.c,v retrieving revision 1.16 diff -p -u -r1.16 rs.c --- usr.bin/rs/rs.c 3 Feb 2019 03:19:30 -0000 1.16 +++ usr.bin/rs/rs.c 8 Aug 2023 20:22:36 -0000 @@ -376,13 +376,15 @@ static char ** getptrs(char **sp) { char **p; + ptrdiff_t off; allocsize += allocsize; + off = sp - elem; p = (char **)realloc(elem, allocsize * sizeof(char *)); if (p == (char **)0) err(1, "no memory"); - sp += (p - elem); + sp = p + off; endelem = (elem = p) + allocsize; return(sp); } Index: usr.bin/sort/files.c =================================================================== RCS file: /cvsroot/src/usr.bin/sort/files.c,v retrieving revision 1.42 diff -p -u -r1.42 files.c --- usr.bin/sort/files.c 5 Aug 2015 07:10:03 -0000 1.42 +++ usr.bin/sort/files.c 8 Aug 2023 20:22:36 -0000 @@ -199,13 +199,14 @@ seq(FILE *fp, u_char **line) /* Long line - double size of buffer */ /* XXX: Check here for stupidly long lines */ buf_size *= 2; + ptrdiff_t off = pos - buf; new_buf = realloc(buf, buf_size); if (!new_buf) err(2, "realloc of linebuf to %zu bytes failed", buf_size); end = new_buf + buf_size; - pos = new_buf + (pos - buf); + pos = new_buf + off; buf = new_buf; } } Index: usr.bin/find/misc.c =================================================================== RCS file: /cvsroot/src/usr.bin/find/misc.c,v retrieving revision 1.15 diff -p -u -r1.15 misc.c --- usr.bin/find/misc.c 22 Jan 2022 14:08:19 -0000 1.15 +++ usr.bin/find/misc.c 8 Aug 2023 20:22:36 -0000 @@ -78,11 +78,13 @@ brace_subst(char *orig, char **store, ch nlen *= 2; if (nlen > *len) { + ptrdiff_t off = p - *store; + ostore = *store; if ((*store = realloc(ostore, nlen)) == NULL) err(1, "realloc"); *len = nlen; - p += *store - ostore; /* Relocate. */ + p = *store + off; /* Relocate. */ } memmove(p, path, plen); p += plen; Index: usr.bin/mail/extern.h =================================================================== RCS file: /cvsroot/src/usr.bin/mail/extern.h,v retrieving revision 1.35 diff -p -u -r1.35 extern.h --- usr.bin/mail/extern.h 1 Aug 2023 07:04:17 -0000 1.35 +++ usr.bin/mail/extern.h 8 Aug 2023 20:22:36 -0000 @@ -357,7 +357,7 @@ int get_msgCount(void); /* we trash these commands */ # define do_recursion() 0 # define thread_recursion(mp,fn,args) fn(mp,args) -# define thread_fix_old_links(nmessage,message,omsgCount) +# define thread_fix_old_links(nmessage,off,omsgCount) # define thread_fix_new_links(message,omsgCount,msgCount) #endif /* THREAD_SUPPORT */ Index: usr.bin/mail/fio.c =================================================================== RCS file: /cvsroot/src/usr.bin/mail/fio.c,v retrieving revision 1.43 diff -p -u -r1.43 fio.c --- usr.bin/mail/fio.c 9 Nov 2017 20:27:50 -0000 1.43 +++ usr.bin/mail/fio.c 8 Aug 2023 20:22:36 -0000 @@ -125,20 +125,23 @@ makemessage(FILE *f, int omsgCount, int size_t size; struct message *omessage; /* old message structure array */ struct message *nmessage; + ptrdiff_t off; omessage = get_abs_message(1); size = (nmsgCount + 1) * sizeof(*nmessage); + + if (omsgCount == 0 || omessage == NULL) + off = 0; + else + off = dot - omessage; nmessage = realloc(omessage, size); if (nmessage == NULL) err(EXIT_FAILURE, "Insufficient memory for %d messages", nmsgCount); - if (omsgCount == 0 || omessage == NULL) - dot = nmessage; - else - dot = nmessage + (dot - omessage); + dot = nmessage + off; - thread_fix_old_links(nmessage, omessage, omsgCount); + thread_fix_old_links(nmessage, off, omsgCount); #ifndef THREAD_SUPPORT message = nmessage; Index: usr.bin/mail/thread.c =================================================================== RCS file: /cvsroot/src/usr.bin/mail/thread.c,v retrieving revision 1.14 diff -p -u -r1.14 thread.c --- usr.bin/mail/thread.c 17 Dec 2021 15:29:44 -0000 1.14 +++ usr.bin/mail/thread.c 8 Aug 2023 20:22:36 -0000 @@ -440,10 +440,10 @@ redepth(struct thread_s *thread) * as it needs access to current_thread.t_head. */ PUBLIC void -thread_fix_old_links(struct message *nmessage, struct message *message, int omsgCount) +thread_fix_old_links(struct message *nmessage, ptrdiff_t off, int omsgCount) { int i; - if (nmessage == message) + if (off == 0) return; #ifndef NDEBUG @@ -451,8 +451,7 @@ thread_fix_old_links(struct message *nme #endif # define FIX_LINK(p) do {\ - if (p)\ - p = nmessage + (p - message);\ + p = nmessage + off;\ } while (0) FIX_LINK(current_thread.t_head); Index: usr.bin/mail/thread.h =================================================================== RCS file: /cvsroot/src/usr.bin/mail/thread.h,v retrieving revision 1.2 diff -p -u -r1.2 thread.h --- usr.bin/mail/thread.h 28 Apr 2008 20:24:14 -0000 1.2 +++ usr.bin/mail/thread.h 8 Aug 2023 20:22:36 -0000 @@ -56,7 +56,7 @@ int get_abs_msgCount(void); /* * Support hooks used by other modules. */ -void thread_fix_old_links(struct message *, struct message *, int); +void thread_fix_old_links(struct message *, ptrdiff_t, int); void thread_fix_new_links(struct message *, int, int); int thread_hidden(void); int thread_depth(void);