diff options
author | Hitendra Prajapati <hprajapati@mvista.com> | 2024-09-06 13:49:40 +0530 |
---|---|---|
committer | Armin Kuster <akuster808@gmail.com> | 2024-09-09 19:43:52 -0400 |
commit | e0bfd27ca0dcd0800bdb2e2a6805a40d83e276a1 (patch) | |
tree | 6fc1f752c199b7c7fed5723af95de4d9753ffe6d | |
parent | 2d5aaeb70501953ce29641cdcb01857827510fe9 (diff) | |
download | meta-security-e0bfd27ca0dcd0800bdb2e2a6805a40d83e276a1.tar.gz |
clamav: fix CVE-2024-20505 & CVE-2024-20506
Backport fixes for:
* CVE-2024-20505 - Upstream-Status: Backport from https://github.com/Cisco-Talos/clamav/commit/8915bd22570ee608907f1b88a68e587d17813812
* CVE-2024-20506 - Upstream-Status: Backport from https://github.com/Cisco-Talos/clamav/commit/88efeda2a4cb93a69cf0994c02a8987f06fa204d
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r-- | recipes-scanners/clamav/clamav_0.104.4.bb | 2 | ||||
-rw-r--r-- | recipes-scanners/clamav/files/CVE-2024-20505.patch | 118 | ||||
-rw-r--r-- | recipes-scanners/clamav/files/CVE-2024-20506.patch | 124 |
3 files changed, 244 insertions, 0 deletions
diff --git a/recipes-scanners/clamav/clamav_0.104.4.bb b/recipes-scanners/clamav/clamav_0.104.4.bb index 102f267..d7beade 100644 --- a/recipes-scanners/clamav/clamav_0.104.4.bb +++ b/recipes-scanners/clamav/clamav_0.104.4.bb | |||
@@ -20,6 +20,8 @@ SRC_URI = "git://github.com/Cisco-Talos/clamav;branch=rel/0.104;protocol=https \ | |||
20 | file://tmpfiles.clamav \ | 20 | file://tmpfiles.clamav \ |
21 | file://headers_fixup.patch \ | 21 | file://headers_fixup.patch \ |
22 | file://oe_cmake_fixup.patch \ | 22 | file://oe_cmake_fixup.patch \ |
23 | file://CVE-2024-20505.patch \ | ||
24 | file://CVE-2024-20506.patch \ | ||
23 | " | 25 | " |
24 | S = "${WORKDIR}/git" | 26 | S = "${WORKDIR}/git" |
25 | 27 | ||
diff --git a/recipes-scanners/clamav/files/CVE-2024-20505.patch b/recipes-scanners/clamav/files/CVE-2024-20505.patch new file mode 100644 index 0000000..9c73051 --- /dev/null +++ b/recipes-scanners/clamav/files/CVE-2024-20505.patch | |||
@@ -0,0 +1,118 @@ | |||
1 | From 8915bd22570ee608907f1b88a68e587d17813812 Mon Sep 17 00:00:00 2001 | ||
2 | From: Micah Snyder <micasnyd@cisco.com> | ||
3 | Date: Tue, 16 Jul 2024 11:22:05 -0400 | ||
4 | Subject: [PATCH] Fix possible out of bounds read in PDF parser | ||
5 | |||
6 | The `find_length()` function in the PDF parser incorrectly assumes that | ||
7 | objects found are located in the main PDF file map, and fails to take | ||
8 | into account whether the objects were in fact found in extracted PDF | ||
9 | object streams. The resulting pointer is then invalid and may be an out | ||
10 | of bounds read. | ||
11 | |||
12 | This issue was found by OSS-Fuzz. | ||
13 | |||
14 | This fix checks if the object is from an object stream, and then | ||
15 | calculates the pointer based on the start of the object stream instead | ||
16 | of based on the start of the PDF. | ||
17 | |||
18 | I've also added extra checks to verify the calculated pointer and object | ||
19 | size are within the stream (or PDF file map). I'm not entirely sure this | ||
20 | is necessary, but better safe than sorry. | ||
21 | |||
22 | Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=69617 | ||
23 | |||
24 | Upstream-Status: Backport [https://github.com/Cisco-Talos/clamav/commit/8915bd22570ee608907f1b88a68e587d17813812] | ||
25 | CVE: CVE-2024-20505 | ||
26 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
27 | --- | ||
28 | libclamav/pdf.c | 45 +++++++++++++++++++++++++++++++++++++++------ | ||
29 | libclamav/pdfng.c | 5 +++++ | ||
30 | 2 files changed, 44 insertions(+), 6 deletions(-) | ||
31 | |||
32 | diff --git a/libclamav/pdf.c b/libclamav/pdf.c | ||
33 | index 01f32e07a..40eea19eb 100644 | ||
34 | --- a/libclamav/pdf.c | ||
35 | +++ b/libclamav/pdf.c | ||
36 | @@ -1009,8 +1009,26 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha | ||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | - indirect_obj_start = pdf->map + obj->start; | ||
41 | - bytes_remaining = pdf->size - obj->start; | ||
42 | + if (NULL == obj->objstm) { | ||
43 | + indirect_obj_start = (const char *)(obj->start + pdf->map); | ||
44 | + | ||
45 | + if (!CLI_ISCONTAINED(pdf->map, pdf->size, indirect_obj_start, obj->size)) { | ||
46 | + cli_dbgmsg("find_length: indirect object found, but not contained in PDF\n"); | ||
47 | + return 0; | ||
48 | + } | ||
49 | + | ||
50 | + bytes_remaining = pdf->size - obj->start; | ||
51 | + | ||
52 | + } else { | ||
53 | + indirect_obj_start = (const char *)(obj->start + obj->objstm->streambuf); | ||
54 | + | ||
55 | + if (!CLI_ISCONTAINED(obj->objstm->streambuf, obj->objstm->streambuf_len, indirect_obj_start, obj->size)) { | ||
56 | + cli_dbgmsg("find_length: indirect object found, but not contained in PDF streambuf\n"); | ||
57 | + return 0; | ||
58 | + } | ||
59 | + | ||
60 | + bytes_remaining = obj->objstm->streambuf_len - obj->start; | ||
61 | + } | ||
62 | |||
63 | /* Ok so we found the indirect object, lets read the value. */ | ||
64 | index = pdf_nextobject(indirect_obj_start, bytes_remaining); | ||
65 | @@ -3093,15 +3111,30 @@ void pdf_handle_enc(struct pdf_struct *pdf) | ||
66 | |||
67 | obj = find_obj(pdf, pdf->objs[0], pdf->enc_objid); | ||
68 | if (!obj) { | ||
69 | - cli_dbgmsg("pdf_handle_enc: can't find encrypted object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff); | ||
70 | - noisy_warnmsg("pdf_handle_enc: can't find encrypted object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff); | ||
71 | + cli_dbgmsg("pdf_handle_enc: can't find encryption object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff); | ||
72 | + noisy_warnmsg("pdf_handle_enc: can't find encryption object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff); | ||
73 | return; | ||
74 | } | ||
75 | |||
76 | len = obj->size; | ||
77 | |||
78 | - q = (obj->objstm) ? (const char *)(obj->start + obj->objstm->streambuf) | ||
79 | - : (const char *)(obj->start + pdf->map); | ||
80 | + if (NULL == obj->objstm) { | ||
81 | + q = (const char *)(obj->start + pdf->map); | ||
82 | + | ||
83 | + if (!CLI_ISCONTAINED(pdf->map, pdf->size, q, len)) { | ||
84 | + cli_dbgmsg("pdf_handle_enc: encryption object found, but not contained in PDF\n"); | ||
85 | + noisy_warnmsg("pdf_handle_enc: encryption object found, but not contained in PDF\n"); | ||
86 | + return; | ||
87 | + } | ||
88 | + } else { | ||
89 | + q = (const char *)(obj->start + obj->objstm->streambuf); | ||
90 | + | ||
91 | + if (!CLI_ISCONTAINED(obj->objstm->streambuf, obj->objstm->streambuf_len, q, len)) { | ||
92 | + cli_dbgmsg("pdf_handle_enc: encryption object found, but not contained in PDF streambuf\n"); | ||
93 | + noisy_warnmsg("pdf_handle_enc: encryption object found, but not contained in PDF streambuf\n"); | ||
94 | + return; | ||
95 | + } | ||
96 | + } | ||
97 | |||
98 | O = U = UE = StmF = StrF = EFF = NULL; | ||
99 | do { | ||
100 | diff --git a/libclamav/pdfng.c b/libclamav/pdfng.c | ||
101 | index a5daa2891..977a95e4d 100644 | ||
102 | --- a/libclamav/pdfng.c | ||
103 | +++ b/libclamav/pdfng.c | ||
104 | @@ -450,6 +450,11 @@ char *pdf_parse_string(struct pdf_struct *pdf, struct pdf_obj *obj, const char * | ||
105 | if (!(newobj)) | ||
106 | return NULL; | ||
107 | |||
108 | + if (!CLI_ISCONTAINED(pdf->map, pdf->size, newobj->start, newobj->size)) { | ||
109 | + cli_dbgmsg("pdf_parse_string: object not contained in PDF\n"); | ||
110 | + return NULL; | ||
111 | + } | ||
112 | + | ||
113 | if (newobj == obj) | ||
114 | return NULL; | ||
115 | |||
116 | -- | ||
117 | 2.25.1 | ||
118 | |||
diff --git a/recipes-scanners/clamav/files/CVE-2024-20506.patch b/recipes-scanners/clamav/files/CVE-2024-20506.patch new file mode 100644 index 0000000..4462780 --- /dev/null +++ b/recipes-scanners/clamav/files/CVE-2024-20506.patch | |||
@@ -0,0 +1,124 @@ | |||
1 | From 88efeda2a4cb93a69cf0994c02a8987f06fa204d Mon Sep 17 00:00:00 2001 | ||
2 | From: Micah Snyder <micasnyd@cisco.com> | ||
3 | Date: Mon, 26 Aug 2024 14:00:51 -0400 | ||
4 | Subject: [PATCH] Disable following symlinks when opening log files | ||
5 | |||
6 | The log module used by clamd and freshclam may follow symlinks. | ||
7 | This is a potential security concern since the log may be owned by | ||
8 | the unprivileged service but may be opened by the service running as | ||
9 | root on startup. | ||
10 | |||
11 | For Windows, we'll define O_NOFOLLOW so the code works, though the issue | ||
12 | does not affect Windows. | ||
13 | |||
14 | Issue reported by Detlef. | ||
15 | |||
16 | Upstream-Status: Backport [https://github.com/Cisco-Talos/clamav/commit/88efeda2a4cb93a69cf0994c02a8987f06fa204d] | ||
17 | CVE: CVE-2024-20506 | ||
18 | Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com> | ||
19 | --- | ||
20 | common/output.c | 51 ++++++++++++++++++++++++++++++++++++++----------- | ||
21 | 1 file changed, 40 insertions(+), 11 deletions(-) | ||
22 | |||
23 | diff --git a/common/output.c b/common/output.c | ||
24 | index 968cea09f..f3ea7f980 100644 | ||
25 | --- a/common/output.c | ||
26 | +++ b/common/output.c | ||
27 | @@ -58,6 +58,12 @@ | ||
28 | |||
29 | #include "output.h" | ||
30 | |||
31 | +// Define O_NOFOLLOW for systems that don't have it. | ||
32 | +// Notably, Windows doesn't have O_NOFOLLOW. | ||
33 | +#ifndef O_NOFOLLOW | ||
34 | +#define O_NOFOLLOW 0 | ||
35 | +#endif | ||
36 | + | ||
37 | #ifdef CL_THREAD_SAFE | ||
38 | #include <pthread.h> | ||
39 | pthread_mutex_t logg_mutex = PTHREAD_MUTEX_INITIALIZER; | ||
40 | @@ -323,7 +329,6 @@ int logg(const char *str, ...) | ||
41 | char buffer[1025], *abuffer = NULL, *buff; | ||
42 | time_t currtime; | ||
43 | size_t len; | ||
44 | - mode_t old_umask; | ||
45 | #ifdef F_WRLCK | ||
46 | struct flock fl; | ||
47 | #endif | ||
48 | @@ -357,18 +362,36 @@ int logg(const char *str, ...) | ||
49 | logg_open(); | ||
50 | |||
51 | if (!logg_fp && logg_file) { | ||
52 | - old_umask = umask(0037); | ||
53 | - if ((logg_fp = fopen(logg_file, "at")) == NULL) { | ||
54 | - umask(old_umask); | ||
55 | + int logg_file_fd = -1; | ||
56 | + | ||
57 | + logg_file_fd = open(logg_file, O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW, 0640); | ||
58 | + if (-1 == logg_file_fd) { | ||
59 | + char errbuf[128]; | ||
60 | + cli_strerror(errno, errbuf, sizeof(errbuf)); | ||
61 | + printf("ERROR: Failed to open log file %s: %s\n", logg_file, errbuf); | ||
62 | + | ||
63 | #ifdef CL_THREAD_SAFE | ||
64 | pthread_mutex_unlock(&logg_mutex); | ||
65 | #endif | ||
66 | - printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file); | ||
67 | - if (len > sizeof(buffer)) | ||
68 | + if (abuffer) | ||
69 | free(abuffer); | ||
70 | return -1; | ||
71 | - } else | ||
72 | - umask(old_umask); | ||
73 | + } | ||
74 | + | ||
75 | + logg_fp = fdopen(logg_file_fd, "at"); | ||
76 | + if (NULL == logg_fp) { | ||
77 | + char errbuf[128]; | ||
78 | + cli_strerror(errno, errbuf, sizeof(errbuf)); | ||
79 | + printf("ERROR: Failed to convert the open log file descriptor for %s to a FILE* handle: %s\n", logg_file, errbuf); | ||
80 | + | ||
81 | + close(logg_file_fd); | ||
82 | +#ifdef CL_THREAD_SAFE | ||
83 | + pthread_mutex_unlock(&logg_mutex); | ||
84 | +#endif | ||
85 | + if (abuffer) | ||
86 | + free(abuffer); | ||
87 | + return -1; | ||
88 | + } | ||
89 | |||
90 | #ifdef F_WRLCK | ||
91 | if (logg_lock) { | ||
92 | @@ -381,11 +404,16 @@ int logg(const char *str, ...) | ||
93 | else | ||
94 | #endif | ||
95 | { | ||
96 | + char errbuf[128]; | ||
97 | + cli_strerror(errno, errbuf, sizeof(errbuf)); | ||
98 | + printf("ERROR: Failed to lock the log file %s: %s\n", logg_file, errbuf); | ||
99 | + | ||
100 | #ifdef CL_THREAD_SAFE | ||
101 | pthread_mutex_unlock(&logg_mutex); | ||
102 | #endif | ||
103 | - printf("ERROR: %s is locked by another process\n", logg_file); | ||
104 | - if (len > sizeof(buffer)) | ||
105 | + fclose(logg_fp); | ||
106 | + logg_fp = NULL; | ||
107 | + if (abuffer) | ||
108 | free(abuffer); | ||
109 | return -1; | ||
110 | } | ||
111 | @@ -462,8 +490,9 @@ int logg(const char *str, ...) | ||
112 | pthread_mutex_unlock(&logg_mutex); | ||
113 | #endif | ||
114 | |||
115 | - if (len > sizeof(buffer)) | ||
116 | + if (abuffer) | ||
117 | free(abuffer); | ||
118 | + | ||
119 | return 0; | ||
120 | } | ||
121 | |||
122 | -- | ||
123 | 2.25.1 | ||
124 | |||