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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
|
From 93e090592fc6de7ec5d3d42c1bb9074ad1f3ba34 Mon Sep 17 00:00:00 2001
From: Andris Zeila <andris.zeila@zabbix.com>
Date: Fri, 12 Jan 2024 05:48:31 +0000
Subject: [PATCH] .......PS. [DEV-2695] changed fping tests to read address
from file
Merge in ZBX/zabbix from feature/DEV-2695-6.0 to release/6.0
* commit '6603893ff94620e28fc543d5d0d4c86b9be3342e':
.......PS. [DEV-2695] fixed signal blocking
.......PS. [DEV-2695] added target hostname/ip validation in fping feature tests
.......PS. [DEV-2695] added error messages when failed to prepare temporary file for fping tests
.......PS. [DEV-2695] changed fping tests to read address from file
CVE: CVE-2023-32727
Upstream-Status: BAckport [https://github.com/zabbix/zabbix/commit/93e090592fc6de7ec5d3d42c1bb9074ad1f3ba34]
Signed-off-by: Yogita Urade <yogita.urade@windriver.com>
---
src/libs/zbxicmpping/icmpping.c | 125 ++++++++++++++++++++++++++++----
1 file changed, 112 insertions(+), 13 deletions(-)
diff --git a/src/libs/zbxicmpping/icmpping.c b/src/libs/zbxicmpping/icmpping.c
index 72f7e86..9a751b7 100644
--- a/src/libs/zbxicmpping/icmpping.c
+++ b/src/libs/zbxicmpping/icmpping.c
@@ -59,6 +59,8 @@ static void get_source_ip_option(const char *fping, const char **option, unsigne
zbx_snprintf(tmp, sizeof(tmp), "%s -h 2>&1", fping);
+ zabbix_log(LOG_LEVEL_DEBUG, "executing %s", tmp);
+
if (NULL == (f = popen(tmp, "r")))
return;
@@ -85,6 +87,110 @@ static void get_source_ip_option(const char *fping, const char **option, unsigne
*checked = 1;
}
+/******************************************************************************
+ * *
+ * Purpose: execute external program and return stdout and stderr values *
+ * *
+ * Parameters: fping - [IN] location of fping program *
+ * out - [OUT] stdout and stderr values *
+ * error - [OUT] error string if function fails *
+ * max_error_len - [IN] length of error buffer *
+ * *
+ * Return value: SUCCEED if processed successfully or FAIL otherwise *
+ * *
+ ******************************************************************************/
+static int get_fping_out(const char *fping, const char *address, char **out, char *error, size_t max_error_len)
+{
+ FILE *f;
+ size_t buf_size = 0, offset = 0, len;
+ ssize_t n;
+ char tmp[MAX_STRING_LEN], *buffer = NULL;
+ int ret = FAIL, fd;
+ sigset_t mask, orig_mask;
+ char filename[MAX_STRING_LEN];
+
+ if (FAIL == zbx_validate_hostname(address) && FAIL == is_supported_ip(address))
+ {
+ zbx_strlcpy(error, "Invalid host name or IP address", max_error_len);
+ return FAIL;
+ }
+
+ zbx_snprintf(filename, sizeof(filename), "%s/%s_XXXXXX", CONFIG_TMPDIR, progname);
+ if (-1 == (fd = mkstemp(filename)))
+ {
+ zbx_snprintf(error, max_error_len, "Cannot create temporary file \"%s\": %s", filename,
+ zbx_strerror(errno));
+
+ return FAIL;
+ }
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGINT);
+ sigaddset(&mask, SIGQUIT);
+
+ len = strlen(address);
+ if (-1 == (n = write(fd, address, len)))
+ {
+ zbx_snprintf(error, max_error_len, "Cannot write address into temporary file: %s", zbx_strerror(errno));
+ (void)close(fd);
+ goto out;
+ }
+
+ if (n != (ssize_t)len)
+ {
+ zbx_strlcpy(error, "Cannot write full address into temporary file", max_error_len);
+ (void)close(fd);
+ goto out;
+ }
+
+ if (-1 == close(fd))
+ {
+ zbx_snprintf(error, max_error_len, "Cannot close temporary file: %s", zbx_strerror(errno));
+ goto out;
+ }
+
+ zbx_snprintf(tmp, sizeof(tmp), "%s 2>&1 < %s", fping, filename);
+
+ if (0 > sigprocmask(SIG_BLOCK, &mask, &orig_mask))
+ zbx_error("cannot set sigprocmask to block the user signal");
+
+ zabbix_log(LOG_LEVEL_DEBUG, "executing %s", tmp);
+
+ if (NULL == (f = popen(tmp, "r")))
+ {
+ zbx_strlcpy(error, zbx_strerror(errno), max_error_len);
+ goto out;
+ }
+
+ while (NULL != zbx_fgets(tmp, sizeof(tmp), f))
+ {
+ len = strlen(tmp);
+
+ if (MAX_EXECUTE_OUTPUT_LEN < offset + len)
+ break;
+
+ zbx_strncpy_alloc(&buffer, &buf_size, &offset, tmp, len);
+ }
+
+ pclose(f);
+
+ if (NULL == buffer)
+ {
+ zbx_strlcpy(error, "Cannot obtain the program output", max_error_len);
+ goto out;
+ }
+
+ *out = buffer;
+ ret = SUCCEED;
+out:
+ unlink(filename);
+
+ if (0 > sigprocmask(SIG_SETMASK, &orig_mask, NULL))
+ zbx_error("cannot restore sigprocmask");
+
+ return ret;
+}
+
/******************************************************************************
* *
* Function: get_interval_option *
@@ -137,19 +243,12 @@ static int get_interval_option(const char *fping, ZBX_FPING_HOST *hosts, int hos
zabbix_log(LOG_LEVEL_DEBUG, "testing fping interval %u ms", intervals[j]);
- zbx_snprintf(tmp, sizeof(tmp), "%s -c1 -t50 -i%u %s", fping, intervals[j], dst);
+ zbx_snprintf(tmp, sizeof(tmp), "%s -c1 -t50 -i%u", fping, intervals[j]);
zbx_free(out);
/* call fping, ignore its exit code but mind execution failures */
- if (TIMEOUT_ERROR == (ret_exec = zbx_execute(tmp, &out, err, sizeof(err), 1,
- ZBX_EXIT_CODE_CHECKS_DISABLED, NULL)))
- {
- zbx_snprintf(error, max_error_len, "Timeout while executing \"%s\"", tmp);
- goto out;
- }
-
- if (FAIL == ret_exec)
+ if (SUCCEED != (ret_exec = get_fping_out(tmp, dst, &out, err, sizeof(err))))
{
zbx_snprintf(error, max_error_len, "Cannot execute \"%s\": %s", tmp, err);
goto out;
@@ -251,10 +350,10 @@ static int get_ipv6_support(const char * fping, const char *dst)
int ret;
char tmp[MAX_STRING_LEN], error[255], *out = NULL;
- zbx_snprintf(tmp, sizeof(tmp), "%s -6 -c1 -t50 %s", fping, dst);
+ zbx_snprintf(tmp, sizeof(tmp), "%s -6 -c1 -t50", fping);
- if ((SUCCEED == (ret = zbx_execute(tmp, &out, error, sizeof(error), 1, ZBX_EXIT_CODE_CHECKS_DISABLED, NULL)) &&
- ZBX_KIBIBYTE > strlen(out) && NULL != strstr(out, dst)) || TIMEOUT_ERROR == ret)
+ if (SUCCEED == (ret = get_fping_out(tmp, dst, &out, error, sizeof(error)) &&
+ ZBX_KIBIBYTE > strlen(out) && NULL != strstr(out, dst)))
{
ret = SUCCEED;
}
@@ -538,7 +637,7 @@ static int process_ping(ZBX_FPING_HOST *hosts, int hosts_count, int count, int i
fclose(f);
- zabbix_log(LOG_LEVEL_DEBUG, "%s", tmp);
+ zabbix_log(LOG_LEVEL_DEBUG, "executing %s", tmp);
sigemptyset(&mask);
sigaddset(&mask, SIGINT);
--
2.40.0
|