Module Name:    src
Committed By:   mrg
Date:           Thu Aug 10 20:36:29 UTC 2023

Modified Files:
        src/external/bsd/pdisk/dist: io.c
        src/usr.bin/find: misc.c
        src/usr.bin/mail: extern.h fio.c thread.c thread.h
        src/usr.bin/rs: rs.c
        src/usr.bin/sort: files.c

Log Message:
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.


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/external/bsd/pdisk/dist/io.c
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/find/misc.c
cvs rdiff -u -r1.35 -r1.36 src/usr.bin/mail/extern.h
cvs rdiff -u -r1.43 -r1.44 src/usr.bin/mail/fio.c
cvs rdiff -u -r1.14 -r1.15 src/usr.bin/mail/thread.c
cvs rdiff -u -r1.2 -r1.3 src/usr.bin/mail/thread.h
cvs rdiff -u -r1.16 -r1.17 src/usr.bin/rs/rs.c
cvs rdiff -u -r1.42 -r1.43 src/usr.bin/sort/files.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/pdisk/dist/io.c
diff -u src/external/bsd/pdisk/dist/io.c:1.2 src/external/bsd/pdisk/dist/io.c:1.3
--- src/external/bsd/pdisk/dist/io.c:1.2	Sat Mar 23 15:39:43 2013
+++ src/external/bsd/pdisk/dist/io.c	Thu Aug 10 20:36:28 2023
@@ -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: src/usr.bin/find/misc.c
diff -u src/usr.bin/find/misc.c:1.15 src/usr.bin/find/misc.c:1.16
--- src/usr.bin/find/misc.c:1.15	Sat Jan 22 14:08:19 2022
+++ src/usr.bin/find/misc.c	Thu Aug 10 20:36:28 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: misc.c,v 1.15 2022/01/22 14:08:19 christos Exp $	*/
+/*	$NetBSD: misc.c,v 1.16 2023/08/10 20:36:28 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1990, 1993, 1994
@@ -37,7 +37,7 @@
 #if 0
 static char sccsid[] = "from: @(#)misc.c	8.2 (Berkeley) 4/1/94";
 #else
-__RCSID("$NetBSD: misc.c,v 1.15 2022/01/22 14:08:19 christos Exp $");
+__RCSID("$NetBSD: misc.c,v 1.16 2023/08/10 20:36:28 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -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: src/usr.bin/mail/extern.h
diff -u src/usr.bin/mail/extern.h:1.35 src/usr.bin/mail/extern.h:1.36
--- src/usr.bin/mail/extern.h:1.35	Tue Aug  1 07:04:17 2023
+++ src/usr.bin/mail/extern.h	Thu Aug 10 20:36:28 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: extern.h,v 1.35 2023/08/01 07:04:17 mrg Exp $	*/
+/*	$NetBSD: extern.h,v 1.36 2023/08/10 20:36:28 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1992, 1993
@@ -29,7 +29,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)extern.h	8.2 (Berkeley) 4/20/95
- *	$NetBSD: extern.h,v 1.35 2023/08/01 07:04:17 mrg Exp $
+ *	$NetBSD: extern.h,v 1.36 2023/08/10 20:36:28 mrg Exp $
  */
 
 #ifndef __EXTERN_H__
@@ -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: src/usr.bin/mail/fio.c
diff -u src/usr.bin/mail/fio.c:1.43 src/usr.bin/mail/fio.c:1.44
--- src/usr.bin/mail/fio.c:1.43	Thu Nov  9 20:27:50 2017
+++ src/usr.bin/mail/fio.c	Thu Aug 10 20:36:28 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: fio.c,v 1.43 2017/11/09 20:27:50 christos Exp $	*/
+/*	$NetBSD: fio.c,v 1.44 2023/08/10 20:36:28 mrg Exp $	*/
 
 /*
  * Copyright (c) 1980, 1993
@@ -34,7 +34,7 @@
 #if 0
 static char sccsid[] = "@(#)fio.c	8.2 (Berkeley) 4/20/95";
 #else
-__RCSID("$NetBSD: fio.c,v 1.43 2017/11/09 20:27:50 christos Exp $");
+__RCSID("$NetBSD: fio.c,v 1.44 2023/08/10 20:36:28 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -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: src/usr.bin/mail/thread.c
diff -u src/usr.bin/mail/thread.c:1.14 src/usr.bin/mail/thread.c:1.15
--- src/usr.bin/mail/thread.c:1.14	Fri Dec 17 15:29:44 2021
+++ src/usr.bin/mail/thread.c	Thu Aug 10 20:36:28 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: thread.c,v 1.14 2021/12/17 15:29:44 kre Exp $	*/
+/*	$NetBSD: thread.c,v 1.15 2023/08/10 20:36:28 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -37,7 +37,7 @@
 
 #include <sys/cdefs.h>
 #ifndef __lint__
-__RCSID("$NetBSD: thread.c,v 1.14 2021/12/17 15:29:44 kre Exp $");
+__RCSID("$NetBSD: thread.c,v 1.15 2023/08/10 20:36:28 mrg Exp $");
 #endif /* not __lint__ */
 
 #include <assert.h>
@@ -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: src/usr.bin/mail/thread.h
diff -u src/usr.bin/mail/thread.h:1.2 src/usr.bin/mail/thread.h:1.3
--- src/usr.bin/mail/thread.h:1.2	Mon Apr 28 20:24:14 2008
+++ src/usr.bin/mail/thread.h	Thu Aug 10 20:36:28 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: thread.h,v 1.2 2008/04/28 20:24:14 martin Exp $	*/
+/*	$NetBSD: thread.h,v 1.3 2023/08/10 20:36:28 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -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);

Index: src/usr.bin/rs/rs.c
diff -u src/usr.bin/rs/rs.c:1.16 src/usr.bin/rs/rs.c:1.17
--- src/usr.bin/rs/rs.c:1.16	Sun Feb  3 03:19:30 2019
+++ src/usr.bin/rs/rs.c	Thu Aug 10 20:36:29 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: rs.c,v 1.16 2019/02/03 03:19:30 mrg Exp $	*/
+/*	$NetBSD: rs.c,v 1.17 2023/08/10 20:36:29 mrg Exp $	*/
 
 /*-
  * Copyright (c) 1993
@@ -39,7 +39,7 @@ __COPYRIGHT("@(#) Copyright (c) 1993\
 #if 0
 static char sccsid[] = "@(#)rs.c	8.1 (Berkeley) 6/6/93";
 #else
-__RCSID("$NetBSD: rs.c,v 1.16 2019/02/03 03:19:30 mrg Exp $");
+__RCSID("$NetBSD: rs.c,v 1.17 2023/08/10 20:36:29 mrg Exp $");
 #endif
 #endif /* not lint */
 
@@ -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: src/usr.bin/sort/files.c
diff -u src/usr.bin/sort/files.c:1.42 src/usr.bin/sort/files.c:1.43
--- src/usr.bin/sort/files.c:1.42	Wed Aug  5 07:10:03 2015
+++ src/usr.bin/sort/files.c	Thu Aug 10 20:36:29 2023
@@ -1,4 +1,4 @@
-/*	$NetBSD: files.c,v 1.42 2015/08/05 07:10:03 mrg Exp $	*/
+/*	$NetBSD: files.c,v 1.43 2023/08/10 20:36:29 mrg Exp $	*/
 
 /*-
  * Copyright (c) 2000-2003 The NetBSD Foundation, Inc.
@@ -64,7 +64,7 @@
 #include "sort.h"
 #include "fsort.h"
 
-__RCSID("$NetBSD: files.c,v 1.42 2015/08/05 07:10:03 mrg Exp $");
+__RCSID("$NetBSD: files.c,v 1.43 2023/08/10 20:36:29 mrg Exp $");
 
 #include <string.h>
 
@@ -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;
 		}
 	}

Reply via email to