git: fd9ae9ac04ed - main - pkg: Allocate a suitably-sized string for the local ABI

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Thu, 16 Nov 2023 00:54:50 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=fd9ae9ac04edf9acef4a2ffbf663698a2b8e7ced

commit fd9ae9ac04edf9acef4a2ffbf663698a2b8e7ced
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2023-11-16 00:53:53 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2023-11-16 00:53:53 +0000

    pkg: Allocate a suitably-sized string for the local ABI
    
    Previously the local ABI string was written to an on-stack buffer and
    the pointer to that buffer was saved in a global before the function
    returned.  This had two issues: c[ABI].val pointed to a
    no-longer-valid on-stack buffer after config_init returned, and the
    string could potentially be truncated.  Fix both of those by changing
    pkg_get_myabi to return a pointer to a string allocated by asprintf.
    
    Note that the allocated string is left in the global config array
    until it is implicitly freed on process exit.
    
    Reported by:    GCC 13 -Wdangling-pointer
    Reviewed by:    emaste
    Differential Revision:  https://reviews.freebsd.org/D42623
---
 usr.sbin/pkg/config.c | 21 ++++++++++++---------
 1 file changed, 12 insertions(+), 9 deletions(-)

diff --git a/usr.sbin/pkg/config.c b/usr.sbin/pkg/config.c
index a2b005eca835..ce3a11cf8c81 100644
--- a/usr.sbin/pkg/config.c
+++ b/usr.sbin/pkg/config.c
@@ -144,32 +144,35 @@ static struct config_entry c[] = {
 	}
 };
 
-static int
-pkg_get_myabi(char *dest, size_t sz)
+static char *
+pkg_get_myabi(void)
 {
 	struct utsname uts;
 	char machine_arch[255];
+	char *abi;
 	size_t len;
 	int error;
 
 	error = uname(&uts);
 	if (error)
-		return (errno);
+		return (NULL);
 
 	len = sizeof(machine_arch);
 	error = sysctlbyname("hw.machine_arch", machine_arch, &len, NULL, 0);
 	if (error)
-		return (errno);
+		return (NULL);
 	machine_arch[len] = '\0';
 
 	/*
 	 * Use __FreeBSD_version rather than kernel version (uts.release) for
 	 * use in jails. This is equivalent to the value of uname -U.
 	 */
-	snprintf(dest, sz, "%s:%d:%s", uts.sysname, __FreeBSD_version/100000,
+	error = asprintf(&abi, "%s:%d:%s", uts.sysname, __FreeBSD_version/100000,
 	    machine_arch);
+	if (error < 0)
+		return (NULL);
 
-	return (error);
+	return (abi);
 }
 
 static void
@@ -453,10 +456,9 @@ config_init(const char *requested_repo)
 	char *val;
 	int i;
 	const char *localbase;
-	char *env_list_item;
+	char *abi, *env_list_item;
 	char confpath[MAXPATHLEN];
 	struct config_value *cv;
-	char abi[BUFSIZ];
 
 	for (i = 0; i < CONFIG_SIZE; i++) {
 		val = getenv(c[i].key);
@@ -512,7 +514,8 @@ config_init(const char *requested_repo)
 
 finalize:
 	if (c[ABI].val == NULL && c[ABI].value == NULL) {
-		if (pkg_get_myabi(abi, BUFSIZ) != 0)
+		abi = pkg_get_myabi();
+		if (abi == NULL)
 			errx(EXIT_FAILURE, "Failed to determine the system "
 			    "ABI");
 		c[ABI].val = abi;