aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-scanners/clamav/files/CVE-2024-20506.patch
blob: 4462780d5f944325b046ebc187465382690609bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
From 88efeda2a4cb93a69cf0994c02a8987f06fa204d Mon Sep 17 00:00:00 2001
From: Micah Snyder <micasnyd@cisco.com>
Date: Mon, 26 Aug 2024 14:00:51 -0400
Subject: [PATCH] Disable following symlinks when opening log files

The log module used by clamd and freshclam may follow symlinks.
This is a potential security concern since the log may be owned by
the unprivileged service but may be opened by the service running as
root on startup.

For Windows, we'll define O_NOFOLLOW so the code works, though the issue
does not affect Windows.

Issue reported by Detlef.

Upstream-Status: Backport [https://github.com/Cisco-Talos/clamav/commit/88efeda2a4cb93a69cf0994c02a8987f06fa204d]
CVE: CVE-2024-20506
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
 common/output.c | 51 ++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 40 insertions(+), 11 deletions(-)

diff --git a/common/output.c b/common/output.c
index 968cea09f..f3ea7f980 100644
--- a/common/output.c
+++ b/common/output.c
@@ -58,6 +58,12 @@
 
 #include "output.h"
 
+// Define O_NOFOLLOW for systems that don't have it.
+// Notably, Windows doesn't have O_NOFOLLOW.
+#ifndef O_NOFOLLOW
+#define O_NOFOLLOW 0
+#endif
+
 #ifdef CL_THREAD_SAFE
 #include <pthread.h>
 pthread_mutex_t logg_mutex     = PTHREAD_MUTEX_INITIALIZER;
@@ -323,7 +329,6 @@ int logg(const char *str, ...)
     char buffer[1025], *abuffer = NULL, *buff;
     time_t currtime;
     size_t len;
-    mode_t old_umask;
 #ifdef F_WRLCK
     struct flock fl;
 #endif
@@ -357,18 +362,36 @@ int logg(const char *str, ...)
     logg_open();
 
     if (!logg_fp && logg_file) {
-        old_umask = umask(0037);
-        if ((logg_fp = fopen(logg_file, "at")) == NULL) {
-            umask(old_umask);
+        int logg_file_fd = -1;
+
+        logg_file_fd = open(logg_file, O_WRONLY | O_CREAT | O_APPEND | O_NOFOLLOW, 0640);
+        if (-1 == logg_file_fd) {
+            char errbuf[128];
+            cli_strerror(errno, errbuf, sizeof(errbuf));
+            printf("ERROR: Failed to open log file %s: %s\n", logg_file, errbuf);
+
 #ifdef CL_THREAD_SAFE
             pthread_mutex_unlock(&logg_mutex);
 #endif
-            printf("ERROR: Can't open %s in append mode (check permissions!).\n", logg_file);
-            if (len > sizeof(buffer))
+            if (abuffer)
                 free(abuffer);
             return -1;
-        } else
-            umask(old_umask);
+        }
+
+        logg_fp = fdopen(logg_file_fd, "at");
+        if (NULL == logg_fp) {
+            char errbuf[128];
+            cli_strerror(errno, errbuf, sizeof(errbuf));
+            printf("ERROR: Failed to convert the open log file descriptor for %s to a FILE* handle: %s\n", logg_file, errbuf);
+
+            close(logg_file_fd);
+#ifdef CL_THREAD_SAFE
+            pthread_mutex_unlock(&logg_mutex);
+#endif
+            if (abuffer)
+                free(abuffer);
+            return -1;
+        }
 
 #ifdef F_WRLCK
         if (logg_lock) {
@@ -381,11 +404,16 @@ int logg(const char *str, ...)
                 else
 #endif
                 {
+                    char errbuf[128];
+                    cli_strerror(errno, errbuf, sizeof(errbuf));
+                    printf("ERROR: Failed to lock the log file %s: %s\n", logg_file, errbuf);
+
 #ifdef CL_THREAD_SAFE
                     pthread_mutex_unlock(&logg_mutex);
 #endif
-                    printf("ERROR: %s is locked by another process\n", logg_file);
-                    if (len > sizeof(buffer))
+                    fclose(logg_fp);
+                    logg_fp = NULL;
+                    if (abuffer)
                         free(abuffer);
                     return -1;
                 }
@@ -462,8 +490,9 @@ int logg(const char *str, ...)
     pthread_mutex_unlock(&logg_mutex);
 #endif
 
-    if (len > sizeof(buffer))
+    if (abuffer)
         free(abuffer);
+
     return 0;
 }
 
-- 
2.25.1