1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-11-26 07:55:01 +00:00

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
This commit is contained in:
John Baldwin 2023-11-15 16:53:53 -08:00
parent 5972ffde91
commit fd9ae9ac04

View File

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