Commit 18097ee961 for openssl.org
commit 18097ee96131dfe0d12cd3ecd55410669a71530d
Author: Eugene Syromiatnikov <esyr@openssl.org>
Date: Mon Mar 30 10:52:07 2026 +0200
apps/lib/apps.c: use fstat on an opened fd in app_mmap_file()
Coverity has rightfully complained that using stat() before opening file
leads to TOCTOU issues, refactor the code to open the file first and
then perform stat checks on the opened file descriptor. It is still far
from foolproof, as the file is not locked, and stat() is used elsewhere,
but at least it seems to be a step in the right direction.
Resolves: https://scan5.scan.coverity.com/#/project-view/65248/10222?selectedIssue=1690686
Fixes: 80b7e49c273f "Use mmap for pkeyutl -rawin and dgst one-shot input"
Signed-off-by: Eugene Syromiatnikov <esyr@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
MergeDate: Wed Apr 1 12:46:08 2026
(Merged from https://github.com/openssl/openssl/pull/30624)
diff --git a/apps/lib/apps.c b/apps/lib/apps.c
index 46e78ecebd..986f5954f4 100644
--- a/apps/lib/apps.c
+++ b/apps/lib/apps.c
@@ -2209,6 +2209,7 @@ int app_mmap_file(const char *path, BIO *err_bio, size_t known_size,
struct stat st;
size_t filesize;
int fd;
+ int ret = -1;
void *p;
*out_data = NULL;
@@ -2217,10 +2218,16 @@ int app_mmap_file(const char *path, BIO *err_bio, size_t known_size,
if (known_size == 0)
return 0;
+ fd = open(path, O_RDONLY);
+ if (fd < 0) {
+ BIO_puts(err_bio, "Error opening file for memory mapping\n");
+ return -1;
+ }
+
if (known_size == (size_t)-1) {
- if (stat(path, &st) != 0 || st.st_size < 0) {
+ if (fstat(fd, &st) != 0 || st.st_size < 0) {
BIO_printf(err_bio, "Error: failed to get size of file '%s'\n", path);
- return -1;
+ goto err;
}
if (!S_ISREG(st.st_mode)) {
/*
@@ -2229,24 +2236,21 @@ int app_mmap_file(const char *path, BIO *err_bio, size_t known_size,
* and fall back to the buffer path in callers.
*/
BIO_puts(err_bio, "Error: failed to use memory-mapped file\n");
- return -1;
+ goto err;
}
filesize = (size_t)st.st_size;
if ((off_t)filesize != st.st_size) {
BIO_puts(err_bio, "Error: failed to convert file size, likely too big\n");
- return -1;
+ goto err;
+ }
+ if (filesize == 0) {
+ ret = 0;
+ goto err;
}
- if (filesize == 0)
- return 0;
} else {
filesize = known_size;
}
- fd = open(path, O_RDONLY);
- if (fd < 0) {
- BIO_puts(err_bio, "Error opening file for memory mapping\n");
- return -1;
- }
p = mmap(NULL, filesize, PROT_READ, MAP_PRIVATE, fd, 0);
(void)close(fd);
if (p == MAP_FAILED) {
@@ -2256,6 +2260,10 @@ int app_mmap_file(const char *path, BIO *err_bio, size_t known_size,
*out_data = (const unsigned char *)p;
*out_size = filesize;
return 1;
+
+err:
+ close(fd);
+ return ret;
}
#endif