Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/lib/libalpm/be_package.c
diff options
context:
space:
mode:
authorTobias Stoeckmann <tobias@stoeckmann.org>2016-06-18 18:41:07 +0200
committerAndrew Gregory <andrew.gregory.8@gmail.com>2017-05-08 23:27:41 -0400
commit3218360114d0e3a3a965feb2f6fd3f4e2da8c8a0 (patch)
tree620ecf9a078da881f2e954c5f1566a87276fb5f0 /lib/libalpm/be_package.c
parent8abb0cbf0e76bc9e59aa58b368ca11a2f0c189f2 (diff)
Reject files larger than 16384 bytes in read_sigfile.
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@stoeckmann.org> Signed-off-by: Allan McRae <allan@archlinux.org> (cherry picked from commit 5fcd60e2641c9293c2783aad509baf217e77aa6f)
Diffstat (limited to 'lib/libalpm/be_package.c')
-rw-r--r--lib/libalpm/be_package.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/lib/libalpm/be_package.c b/lib/libalpm/be_package.c
index a79c0c5b..430d2aeb 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);