summaryrefslogtreecommitdiffstats
path: root/usr.sbin/acpi
diff options
context:
space:
mode:
authortruckman <truckman@FreeBSD.org>2016-05-24 23:41:36 +0000
committertruckman <truckman@FreeBSD.org>2016-05-24 23:41:36 +0000
commitb29064e902d9e5a98dcbbbeffb19e29bb5c62834 (patch)
treec8579ada06f383fd213c22dee434e2fcd48cb386 /usr.sbin/acpi
parent4b5433e33a1d4f5587905894fb1c76a5f99a49d4 (diff)
downloadFreeBSD-src-b29064e902d9e5a98dcbbbeffb19e29bb5c62834.zip
FreeBSD-src-b29064e902d9e5a98dcbbbeffb19e29bb5c62834.tar.gz
Fix acpidb CIDs 1011279 (Buffer not null terminated) and 978405 and
1199380 (Resource leak). load_dsdt() calls strncpy() to copy a filename and Coverity warns that the destination buffer may not be NUL terminated. Fix this by using strlcpy() instead. If silent truncation occurs, then the filename was not valid anyway. load_dsdt() leaks an fd (CID 978405) and a memory region allocated using mmap() (CID 1199380) when it returns. Fix these by calling close() and munmap() as appropriate. Don't bother fixing the minor memory leak "list", allocated by AcGetAllTablesFromFile() (CID 1355191). Check for truncation when creating the temp file name. Set a flag to indicate that the temp file should be unlinked. Relying on a strcmp() test could delete the input file in contrived cases. Reported by: Coverity CID: 1011279, 978405, 1199380 Reviewed by: jkim MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D6368
Diffstat (limited to 'usr.sbin/acpi')
-rw-r--r--usr.sbin/acpi/acpidb/acpidb.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/usr.sbin/acpi/acpidb/acpidb.c b/usr.sbin/acpi/acpidb/acpidb.c
index cc14177..fefe6da 100644
--- a/usr.sbin/acpi/acpidb/acpidb.c
+++ b/usr.sbin/acpi/acpidb/acpidb.c
@@ -385,8 +385,7 @@ load_dsdt(const char *dsdtfile)
ACPI_NEW_TABLE_DESC *list;
u_int8_t *code;
struct stat sb;
- int fd, fd2;
- int error;
+ int dounlink, error, fd;
fd = open(dsdtfile, O_RDONLY, 0);
if (fd == -1) {
@@ -399,11 +398,13 @@ load_dsdt(const char *dsdtfile)
return (-1);
}
code = mmap(NULL, (size_t)sb.st_size, PROT_READ, MAP_PRIVATE, fd, (off_t)0);
+ close(fd);
if (code == NULL) {
perror("mmap");
return (-1);
}
if ((error = AcpiInitializeSubsystem()) != AE_OK) {
+ munmap(code, (size_t)sb.st_size);
return (-1);
}
@@ -411,21 +412,30 @@ load_dsdt(const char *dsdtfile)
* make sure DSDT data contains table header or not.
*/
if (strncmp((char *)code, "DSDT", 4) == 0) {
- strncpy(filetmp, dsdtfile, sizeof(filetmp));
+ dounlink = 0;
+ strlcpy(filetmp, dsdtfile, sizeof(filetmp));
} else {
+ dounlink = 1;
mode_t mode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dummy_dsdt_table.Length = sizeof(ACPI_TABLE_HEADER) + sb.st_size;
- snprintf(filetmp, sizeof(filetmp), "%s.tmp", dsdtfile);
- fd2 = open(filetmp, O_WRONLY | O_CREAT | O_TRUNC, mode);
- if (fd2 == -1) {
+ if ((size_t)snprintf(filetmp, sizeof(filetmp), "%s.tmp",
+ dsdtfile) > sizeof(filetmp) - 1) {
+ fprintf(stderr, "file name too long\n");
+ munmap(code, (size_t)sb.st_size);
+ return (-1);
+ }
+ fd = open(filetmp, O_WRONLY | O_CREAT | O_TRUNC, mode);
+ if (fd == -1) {
perror("open");
+ munmap(code, (size_t)sb.st_size);
return (-1);
}
- write(fd2, &dummy_dsdt_table, sizeof(ACPI_TABLE_HEADER));
+ write(fd, &dummy_dsdt_table, sizeof(ACPI_TABLE_HEADER));
- write(fd2, code, sb.st_size);
- close(fd2);
+ write(fd, code, sb.st_size);
+ close(fd);
}
+ munmap(code, (size_t)sb.st_size);
/*
* Install the virtual machine version of address space handlers.
@@ -487,7 +497,7 @@ load_dsdt(const char *dsdtfile)
AcpiGbl_DebuggerConfiguration = 0;
AcpiDbUserCommands(':', NULL);
- if (strcmp(dsdtfile, filetmp) != 0) {
+ if (dounlink) {
unlink(filetmp);
}
OpenPOWER on IntegriCloud