indent: Fix buffer overflow

The function used to create a backup of the input before starting work
used a static buffer and did not check that the file name it constructed
did not overflow.  Switch to using asprintf(), clean up the rest of the
function, and update some comments that still referred to an earlier
version of the code.

MFC after:	1 week
Sponsored by:	Klara, Inc.
Reviewed by:	bnovkov
Differential Revision:	https://reviews.freebsd.org/D51796
This commit is contained in:
Dag-Erling Smørgrav 2025-08-08 01:34:07 +02:00
parent 0ecc679fd3
commit eb41613d22
2 changed files with 34 additions and 22 deletions

View file

@ -83,7 +83,6 @@ const char *out_name = "Standard Output"; /* will always point to name
* of output file */
const char *simple_backup_suffix = ".BAK"; /* Suffix to use for backup
* files */
char bakfile[MAXPATHLEN] = "";
int
main(int argc, char **argv)
@ -1231,41 +1230,35 @@ check_type:
}
/*
* copy input file to backup file if in_name is /blah/blah/blah/file, then
* backup file will be ".Bfile" then make the backup file the input and
* copy input file to backup file then make the backup file the input and
* original input file the output
*/
static void
bakcopy(void)
{
int n,
bakchn;
char buff[8 * 1024];
const char *p;
static char buff[8 * 1024];
char *bakfile;
ssize_t len;
int bakfd;
/* construct file name .Bfile */
for (p = in_name; *p; p++); /* skip to end of string */
while (p > in_name && *p != '/') /* find last '/' */
p--;
if (*p == '/')
p++;
sprintf(bakfile, "%s%s", p, simple_backup_suffix);
/* generate the backup file name */
if (asprintf(&bakfile, "%s%s", in_name, simple_backup_suffix) < 0)
err(1, "%s%s", in_name, simple_backup_suffix);
/* copy in_name to backup file */
bakchn = creat(bakfile, 0600);
if (bakchn < 0)
bakfd = open(bakfile, O_RDWR | O_CREAT | O_TRUNC, 0600);
if (bakfd < 0)
err(1, "%s", bakfile);
while ((n = read(fileno(input), buff, sizeof(buff))) > 0)
if (write(bakchn, buff, n) != n)
while ((len = read(fileno(input), buff, sizeof(buff))) > 0)
if (write(bakfd, buff, len) != len)
err(1, "%s", bakfile);
if (n < 0)
if (len < 0)
err(1, "%s", in_name);
close(bakchn);
fclose(input);
/* re-open backup file as the input file */
input = fopen(bakfile, "r");
if (input == NULL)
input = fdopen(bakfd, "r");
if (input == NULL || fseek(input, 0, SEEK_SET) != 0)
err(1, "%s", bakfile);
/* now the original input file will be the output */
output = fopen(in_name, "w");
@ -1273,6 +1266,7 @@ bakcopy(void)
unlink(bakfile);
err(1, "%s", in_name);
}
free(bakfile);
}
static void

View file

@ -3,6 +3,7 @@
#
# Copyright 2016 Dell EMC
# All rights reserved.
# Copyright (c) 2025 Klara, Inc.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
@ -56,9 +57,26 @@ add_legacy_testcase()
atf_add_test_case ${tc%.[0-9]}
}
atf_test_case backup_suffix
backup_suffix_body()
{
local argmax=$(sysctl -n kern.argmax)
local suffix=$(jot -b .bak -s '' $((argmax/5)))
local code=$'int main() {}\n'
printf "${code}" >input.c
atf_check indent input.c
atf_check -o inline:"${code}" cat input.c.BAK
atf_check -s exit:1 -e match:"name too long"\
env SIMPLE_BACKUP_SUFFIX=${suffix} indent input.c
}
atf_init_test_cases()
{
for tc in $(find -s "${SRCDIR}" -name '*.[0-9]'); do
add_legacy_testcase "${tc##*/}"
done
atf_add_test_case backup_suffix
}