[pacman-dev] [PATCH] Reject files larger than INT_MAX in read_sigfile.

Tobias Stoeckmann tobias at stoeckmann.org
Sat Jun 18 16:41:07 UTC 2016


If signature files are larger than SIZE_MAX, not enough memory could
be allocated for this file. The script repo-add rejects files which
are larger than 16384 bytes, therefore handle these as errors here,
too.

While at it, I also rearranged the code to avoid a quite harmless
TOCTOU race condition between stat() and fopen().

Signed-off-by: Tobias Stoeckmann <tobias at stoeckmann.org>
---
 lib/libalpm/be_package.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index c9ed770..8307d81 100644
--- a/lib/libalpm/be_package.c
+++ b/lib/libalpm/be_package.c
@@ -24,6 +24,7 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
+#include <limits.h>
 
 /* libarchive */
 #include <archive.h>
@@ -695,22 +696,25 @@ error:
 	return NULL;
 }
 
+/* adopted limit from repo-add */
+#define MAX_SIGFILE_SIZE 16384
+
 static int read_sigfile(const char *sigpath, unsigned char **sig)
 {
 	struct stat st;
 	FILE *fp;
 
-	if(stat(sigpath, &st) != 0) {
+	if((fp = fopen(sigpath, "rb")) == NULL) {
 		return -1;
 	}
 
-	MALLOC(*sig, st.st_size, return -1);
-
-	if((fp = fopen(sigpath, "rb")) == NULL) {
-		free(*sig);
+	if(fstat(fileno(fp), &st) != 0 || st.st_size > MAX_SIGFILE_SIZE) {
+		fclose(fp);
 		return -1;
 	}
 
+	MALLOC(*sig, st.st_size, fclose(fp); return -1);
+
 	if(fread(*sig, st.st_size, 1, fp) != 1) {
 		free(*sig);
 		fclose(fp);
-- 
2.9.0


More information about the pacman-dev mailing list