[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#935474: marked as done (buster-pu: package xymon/4.3.28-5+deb10u1)



Your message dated Sat, 07 Sep 2019 14:34:49 +0100
with message-id <[🔎] f49e2985d8466065c49c03185c24465a32228fb5.camel@adam-barratt.org.uk>
and subject line Closing bugs for fixes including in 10.1 point release
has caused the Debian Bug report #935474,
regarding buster-pu: package xymon/4.3.28-5+deb10u1
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact owner@bugs.debian.org
immediately.)


-- 
935474: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=935474
Debian Bug Tracking System
Contact owner@bugs.debian.org with problems
--- Begin Message ---
Package: release.debian.org
Severity: normal
Tags: buster
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

The Debian Security Team decided to not issue a security update for
these CVE IDs:

* CVE-2019-13451: service overflows histlogfn in history.c.
* CVE-2019-13452: service overflows histlogfn in reportlog.c.
* CVE-2019-13273: srdb overflows dbfn in csvinfo.c.
* CVE-2019-13274: reflected XSS in csvinfo.c.
* CVE-2019-13455: htmlquoted(hostname) overflows msgline in
  acknowledge.c.
* CVE-2019-13484: htmlquoted(xymondreq) overflows errtxt appfeed.c.
* CVE-2019-13485: hostname overflows selfurl in history.c.
* CVE-2019-13486: htmlquoted(xymondreq) overflows errtxt in
  svcstatus.c.

Hence I propose to do these as a normal stable update.

Full source debdiff:

diff -Nru xymon-4.3.28/debian/changelog xymon-4.3.28/debian/changelog
--- xymon-4.3.28/debian/changelog	2019-03-18 01:28:51.000000000 +0100
+++ xymon-4.3.28/debian/changelog	2019-08-23 01:07:47.000000000 +0200
@@ -1,3 +1,22 @@
+xymon (4.3.28-5+deb10u1) buster; urgency=high
+
+  * Apply minimal upstream security patch to fix several (server-only)
+    vulnerabilities reported upstream by Graham Rymer:
+    + CVE-2019-13451: service overflows histlogfn in history.c.
+    + CVE-2019-13452: service overflows histlogfn in reportlog.c.
+    + CVE-2019-13273: srdb overflows dbfn in csvinfo.c.
+    + CVE-2019-13274: reflected XSS in csvinfo.c.
+    + CVE-2019-13455: htmlquoted(hostname) overflows msgline in
+      acknowledge.c.
+    + CVE-2019-13484: htmlquoted(xymondreq) overflows errtxt appfeed.c.
+    + CVE-2019-13485: hostname overflows selfurl in history.c.
+    + CVE-2019-13486: htmlquoted(xymondreq) overflows errtxt in
+      svcstatus.c.
+    + Closes: #935470
+  * Include hostname validation regression fixes from 4.3.30, too.
+
+ -- Axel Beckert <abe@debian.org>  Fri, 23 Aug 2019 01:07:47 +0200
+
 xymon (4.3.28-5) unstable; urgency=medium
 
   * xymon.postinst: Check for file existence before calling chgrp/chmod on
diff -Nru xymon-4.3.28/debian/patches/91_4.3.29-CVEs.patch xymon-4.3.28/debian/patches/91_4.3.29-CVEs.patch
--- xymon-4.3.28/debian/patches/91_4.3.29-CVEs.patch	1970-01-01 01:00:00.000000000 +0100
+++ xymon-4.3.28/debian/patches/91_4.3.29-CVEs.patch	2019-08-23 01:07:05.000000000 +0200
@@ -0,0 +1,760 @@
+Description: Isolated CVE Patchset
+	history.c (service overflows histlogfn) = CVE-2019-13451
+	reportlog.c (service overflows histlogfn) = CVE-2019-13452
+	csvinfo.c (srdb overflows dbfn) = CVE-2019-13273
+	csvinfo.c (reflected XSS) = CVE-2019-13274
+	acknowledge.c (htmlquoted(hostname) overflows msgline) = CVE-2019-13455
+
+	appfeed.c (htmlquoted(xymondreq) overflows errtxt) = CVE-2019-13484
+	history.c (hostname overflows selfurl) = CVE-2019-13485
+	svcstatus.c (htmlquoted(xymondreq) overflows errtxt) = CVE-2019-13486
+
+	Includes hostname validation regression fixes from 4.3.30.
+Author: Japheth Cleaver <cleaver@terabithia.org>
+Bug-Debian: https://bugs.debian.org/935470
+
+Index: xymon/lib/strfunc.h
+===================================================================
+--- xymon/lib/strfunc.h	(revision 8059)
++++ xymon/lib/strfunc.h	(working copy)
+@@ -29,5 +29,14 @@
+ extern char *prehtmlquoted(char *s);
+ extern strbuffer_t *replacetext(char *original, char *oldtext, char *newtext);
+ 
++#define SBUF_DEFINE(NAME) char *NAME = NULL; size_t NAME##_buflen = 0;
++#define STATIC_SBUF_DEFINE(NAME) static char *NAME = NULL; static size_t NAME##_buflen = 0;
++#define SBUF_MALLOC(NAME, LEN) { NAME##_buflen = (LEN); NAME = (char *)malloc((LEN)+1); }
++#define SBUF_CALLOC(NAME, NMEMB, LEN) { NAME##_buflen = (LEN); NAME = (char *)calloc(NMEMB, (LEN)+1); }
++#define SBUF_REALLOC(NAME, LEN) { NAME##_buflen = (LEN); NAME = (char *)realloc(NAME, (LEN)+1); }
++
++/* How much can a string expand when htmlquoted? ' ' --> '&nbsp;' */
++#define MAX_HTMLQUOTE_FACTOR 6
++
+ #endif
+ 
+Index: xymon/web/csvinfo.c
+===================================================================
+--- xymon/web/csvinfo.c	(revision 8059)
++++ xymon/web/csvinfo.c	(working copy)
+@@ -123,12 +123,13 @@
+ 		return 1;
+ 	}
+ 
+-	sprintf(dbfn, "%s/etc/%s", xgetenv("XYMONHOME"), srcdb);
++	snprintf(dbfn, sizeof(dbfn), "%s/etc/%s", xgetenv("XYMONHOME"), srcdb);
+ 	db = fopen(dbfn, "r");
+ 	if (db == NULL) {
+-		char msg[PATH_MAX];
++		SBUF_DEFINE(msg);
+ 
+-		sprintf(msg, "Cannot open sourcedb %s\n", dbfn);
++		SBUF_MALLOC(msg, 30+strlen(htmlquoted(dbfn)));
++		snprintf(msg, msg_buflen, "Cannot open sourcedb %s\n", htmlquoted(dbfn));
+ 		errormsg(msg);
+ 		return 1;
+ 	}
+Index: xymon/web/svcstatus.c
+===================================================================
+--- xymon/web/svcstatus.c	(revision 8059)
++++ xymon/web/svcstatus.c	(working copy)
+@@ -31,7 +31,7 @@
+ /* Command-line params */
+ static enum { SRC_XYMOND, SRC_HISTLOGS, SRC_CLIENTLOGS } source = SRC_XYMOND;
+ static int wantserviceid = 1;
+-static char *multigraphs = ",disk,inode,qtree,quotas,snapshot,TblSpace,if_load,";
++SBUF_DEFINE(multigraphs);
+ static int locatorbased = 0;
+ static char *critconfigfn = NULL;
+ static char *accessfn = NULL;
+@@ -42,12 +42,12 @@
+ static char *tstamp = NULL;
+ static char *nkprio = NULL, *nkttgroup = NULL, *nkttextra = NULL;
+ static enum { FRM_STATUS, FRM_CLIENT } outform = FRM_STATUS;
+-static char *clienturi = NULL;
++STATIC_SBUF_DEFINE(clienturi);
+ static int backsecs = 0;
+ static time_t fromtime = 0, endtime = 0;
+ 
+ static char errortxt[1000];
+-static char *hostdatadir = NULL;
++STATIC_SBUF_DEFINE(hostdatadir);
+ 
+ 
+ static void errormsg(int status, char *msg)
+@@ -148,12 +148,13 @@
+ 
+ 	if (outform == FRM_STATUS) {
+ 		char *p, *req;
++		char *hostquoted = htmlquoted(hostname);
+ 
+ 		req = getenv("SCRIPT_NAME");
+-		clienturi = (char *)malloc(strlen(req) + 10 + strlen(htmlquoted(hostname)));
+-		strcpy(clienturi, req);
++		SBUF_MALLOC(clienturi, strlen(req) + 10 + strlen(hostquoted));
++		strncpy(clienturi, req, clienturi_buflen);
+ 		p = strchr(clienturi, '?'); if (p) *p = '\0'; else p = clienturi + strlen(clienturi);
+-		sprintf(p, "?CLIENT=%s", htmlquoted(hostname));
++		snprintf(p, (clienturi_buflen - (clienturi - p)), "?CLIENT=%s", hostquoted);
+ 	}
+ 
+ 	return 0;
+@@ -194,7 +195,8 @@
+ 	int color = 0, flapping = 0;
+ 	char timesincechange[100];
+ 	time_t logtime = 0, acktime = 0, disabletime = 0;
+-	char *log = NULL, *firstline = NULL, *sender = NULL, *clientid = NULL, *flags = NULL;	/* These are free'd */
++	SBUF_DEFINE(firstline);
++	char *log = NULL, *sender = NULL, *clientid = NULL, *flags = NULL;	/* These are free'd */
+ 	char *restofmsg = NULL, *ackmsg = NULL, *dismsg = NULL, *acklist=NULL, *modifiers = NULL;	/* These are just used */
+ 	int ishtmlformatted = 0;
+ 	int clientavail = 0;
+@@ -231,30 +233,32 @@
+ 		
+ 		s = xgetenv("CLIENTLOGS"); 
+ 		if (s) {
+-			hostdatadir = (char *)malloc(strlen(s) + strlen(hostname) + 12);
+-			sprintf(hostdatadir, "%s/%s", s, hostname);
++			SBUF_MALLOC(hostdatadir, strlen(s) + strlen(hostname) + 12);
++			snprintf(hostdatadir, hostdatadir_buflen, "%s/%s", s, hostname);
+ 		}
+ 		else {
+ 			s = xgetenv("XYMONVAR");
+-			hostdatadir = (char *)malloc(strlen(s) + strlen(hostname) + 12);
+-			sprintf(hostdatadir, "%s/hostdata/%s", s, hostname);
++			SBUF_MALLOC(hostdatadir, strlen(s) + strlen(hostname) + 12);
++			snprintf(hostdatadir, hostdatadir_buflen, "%s/hostdata/%s", s, hostname);
+ 		}
+ 	}
+ 
+ 	if (outform == FRM_CLIENT) {
+ 		if (source == SRC_XYMOND) {
+-			char *xymondreq;
++			SBUF_DEFINE(xymondreq);
+ 			int xymondresult;
+ 			sendreturn_t *sres = newsendreturnbuf(1, NULL);
+ 
+-			xymondreq = (char *)malloc(1024 + strlen(hostname) + (service ? strlen(service) : 0));
+-			sprintf(xymondreq, "clientlog %s", hostname);
+-			if (service && *service) sprintf(xymondreq + strlen(xymondreq), " section=%s", service);
++			SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + (service ? strlen(service) : 0));
++			snprintf(xymondreq, xymondreq_buflen, "clientlog %s", hostname);
++			if (service && *service) snprintf(xymondreq + strlen(xymondreq), (xymondreq_buflen - strlen(xymondreq)), " section=%s", service);
+ 
+ 			xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres);
+ 			if (xymondresult != XYMONSEND_OK) {
+-				char *errtxt = (char *)malloc(1024 + strlen(xymondreq));
+-				sprintf(errtxt, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult);
++				SBUF_DEFINE(errtxt);
++
++				SBUF_MALLOC(errtxt, 1024 + MAX_HTMLQUOTE_FACTOR*strlen(xymondreq));
++				snprintf(errtxt, errtxt_buflen, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult);
+ 				errormsg(500, errtxt);
+ 				return 1;
+ 			}
+@@ -267,7 +271,7 @@
+ 			char logfn[PATH_MAX];
+ 			FILE *fd;
+ 
+-			sprintf(logfn, "%s/%s", hostdatadir, tstamp);
++			snprintf(logfn, sizeof(logfn), "%s/%s", hostdatadir, tstamp);
+ 			fd = fopen(logfn, "r");
+ 			if (fd) {
+ 				struct stat st;
+@@ -295,7 +299,7 @@
+ 		sethostenv_refresh(600);
+ 		color = COL_GREEN;
+ 		logtime = getcurrenttime(NULL);
+-		strcpy(timesincechange, "0 minutes");
++		strncpy(timesincechange, "0 minutes", sizeof(timesincechange));
+ 
+ 		if (strcmp(service, xgetenv("TRENDSCOLUMN")) == 0) {
+ 			if (locatorbased) {
+@@ -331,18 +335,20 @@
+ 		}
+ 	}
+ 	else if (source == SRC_XYMOND) {
+-		char *xymondreq;
++		SBUF_DEFINE(xymondreq);
+ 		int xymondresult;
+ 		char *items[25];
+ 		int icount;
+ 		time_t logage, clntstamp;
+-		char *sumline, *msg, *p, *compitem, *complist;
++		char *sumline, *msg, *compitem, *complist;
+ 		sendreturn_t *sres;
+ 
+ 		if (loadhostdata(hostname, &ip, &displayname, &compacts, 0) != 0) return 1;
+ 
+ 		complist = NULL;
+ 		if (compacts && *compacts) {
++			char *p;
++
+ 			compitem = strtok(compacts, ",");
+ 			while (compitem && !complist) {
+ 				p = strchr(compitem, '='); if (p) *p = '\0';
+@@ -363,15 +369,15 @@
+ 			}
+ 
+ 			freeregex(dummy);
+-			xymondreq = (char *)malloc(1024 + strlen(hostname) + strlen(service));
+-			sprintf(xymondreq, "xymondlog host=%s test=%s fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,ackmsg,dismsg,client,acklist,XMH_IP,XMH_DISPLAYNAME,clntstamp,flapinfo,modifiers", hostname, service);
++			SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + strlen(service));
++			snprintf(xymondreq, xymondreq_buflen, "xymondlog host=%s test=%s fields=hostname,testname,color,flags,lastchange,logtime,validtime,acktime,disabletime,sender,cookie,ackmsg,dismsg,client,acklist,XMH_IP,XMH_DISPLAYNAME,clntstamp,flapinfo,modifiers", hostname, service);
+ 		}
+ 		else {
+ 			pcre *dummy = NULL;
+-			char *re;
++			SBUF_DEFINE(re);
+ 
+-			re = (char *)malloc(5 + strlen(complist));
+-			sprintf(re, "^(%s)$", complist);
++			SBUF_MALLOC(re, 5 + strlen(complist));
++			snprintf(re, re_buflen, "^(%s)$", complist);
+ 			dummy = compileregex(re);
+ 			if (dummy == NULL) {
+ 				errormsg(500, "Invalid testname pattern");
+@@ -379,8 +385,8 @@
+ 			}
+ 
+ 			freeregex(dummy);
+-			xymondreq = (char *)malloc(1024 + strlen(hostname) + strlen(re));
+-			sprintf(xymondreq, "xymondboard host=^%s$ test=%s fields=testname,color,lastchange", hostname, re);
++			SBUF_MALLOC(xymondreq, 1024 + strlen(hostname) + strlen(re));
++			snprintf(xymondreq, xymondreq_buflen, "xymondboard host=^%s$ test=%s fields=testname,color,lastchange", hostname, re);
+ 		}
+ 
+ 		sres = newsendreturnbuf(1, NULL);
+@@ -393,6 +399,8 @@
+ 		}
+ 
+ 		if (!complist) {
++			char *p;
++
+ 			sumline = log; p = strchr(log, '\n'); *p = '\0';
+ 			msg = (p+1); p = strchr(msg, '\n');
+ 			if (!p) {
+@@ -438,20 +446,21 @@
+ 			color = parse_color(items[2]);
+ 			flags = strdup(items[3]);
+ 			logage = getcurrenttime(NULL) - atoi(items[4]);
+-			timesincechange[0] = '\0'; p = timesincechange;
++			timesincechange[0] = '\0';
++			p = timesincechange;
+ 			{
+ 				int days = (int) (logage / 86400);
+ 				int hours = (int) ((logage % 86400) / 3600);
+ 				int minutes = (int) ((logage % 3600) / 60);
+ 
+-				if (days > 1) p += sprintf(p, "%d days, ", days);
+-				else if (days == 1) p += sprintf(p, "1 day, ");
++				if (days > 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d days, ", days);
++				else if (days == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 day, ");
+ 
+-				if (hours == 1) p += sprintf(p, "1 hour, ");
+-				else p += sprintf(p, "%d hours, ", hours);
++				if (hours == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 hour, ");
++				else p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d hours, ", hours);
+ 
+-				if (minutes == 1) p += sprintf(p, "1 minute");
+-				else p += sprintf(p, "%d minutes", minutes);
++				if (minutes == 1) p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "1 minute");
++				else p += snprintf(p, (sizeof(timesincechange) - (p - timesincechange)), "%d minutes", minutes);
+ 			}
+ 			logtime = atoi(items[5]);
+ 			if (items[7] && strlen(items[7])) acktime = atoi(items[7]);
+@@ -481,7 +490,7 @@
+ 			/* Compressed status display */
+ 			strbuffer_t *cmsg;
+ 			char *row, *p_row, *p_fld;
+-			char *nonhistenv;
++			SBUF_DEFINE(nonhistenv);
+ 
+ 			color = COL_GREEN;
+ 
+@@ -520,15 +529,15 @@
+ 			sethostenv(displayname, ip, service, colorname(color), hostname);
+ 			sethostenv_refresh(60);
+ 			logtime = getcurrenttime(NULL);
+-			strcpy(timesincechange, "0 minutes");
++			strncpy(timesincechange, "0 minutes", sizeof(timesincechange));
+ 
+ 			log = restofmsg = grabstrbuffer(cmsg);
+ 
+-			firstline = (char *)malloc(1024);
+-			sprintf(firstline, "%s Compressed status display\n", colorname(color));
++			SBUF_MALLOC(firstline, 1024);
++			snprintf(firstline, firstline_buflen, "%s Compressed status display\n", colorname(color));
+ 
+-			nonhistenv = (char *)malloc(10 + strlen(service));
+-			sprintf(nonhistenv, "NONHISTS=%s", service);
++			SBUF_MALLOC(nonhistenv, 10 + strlen(service));
++			snprintf(nonhistenv, nonhistenv_buflen, "NONHISTS=%s", service);
+ 			putenv(nonhistenv);
+ 		}
+ 	}
+@@ -553,7 +562,7 @@
+ 		hostnamedash = strdup(hostname);
+ 		p = hostnamedash; while ((p = strchr(p, '.')) != NULL) *p = '_';
+ 		p = hostnamedash; while ((p = strchr(p, ',')) != NULL) *p = '_';
+-		sprintf(logfn, "%s/%s/%s/%s", xgetenv("XYMONHISTLOGS"), hostnamedash, service, tstamp);
++		snprintf(logfn, sizeof(logfn), "%s/%s/%s/%s", xgetenv("XYMONHISTLOGS"), hostnamedash, service, tstamp);
+ 		xfree(hostnamedash);
+ 		p = tstamp; while ((p = strchr(p, '_')) != NULL) *p = ' ';
+ 		sethostenv_histlog(tstamp);
+@@ -644,8 +653,8 @@
+ 					errprintf("Cannot find hostdata files for host %s\n", hostname);
+ 				}
+ 				else {
+-					clienturi = (char *)realloc(clienturi, 1024 + strlen(cgiurl) + strlen(htmlquoted(hostname)) + strlen(clientid));
+-					sprintf(clienturi, "%s/svcstatus.sh?CLIENT=%s&amp;TIMEBUF=%s", 
++					SBUF_REALLOC(clienturi, 1024 + strlen(cgiurl) + MAX_HTMLQUOTE_FACTOR*strlen(htmlquoted(hostname)) + strlen(clientid));
++					snprintf(clienturi, clienturi_buflen, "%s/svcstatus.sh?CLIENT=%s&amp;TIMEBUF=%s", 
+ 						cgiurl, htmlquoted(hostname), clientid);
+ 				}
+ 			}
+@@ -653,12 +662,14 @@
+ 				char logfn[PATH_MAX];
+ 				struct stat st;
+ 
+-				sprintf(logfn, "%s/%s", hostdatadir, clientid);
++				snprintf(logfn, sizeof(logfn), "%s/%s", hostdatadir, clientid);
+ 				clientavail = (stat(logfn, &st) == 0);
+ 
+ 				if (clientavail) {
+-					clienturi = (char *)realloc(clienturi, 1024 + strlen(clienturi) + strlen(clientid));
+-					sprintf(clienturi + strlen(clienturi), "&amp;TIMEBUF=%s", clientid);
++					int curlen = strlen(clienturi);
++
++					SBUF_REALLOC(clienturi, 1024 + curlen + strlen(clientid));
++					snprintf(clienturi + curlen, (clienturi_buflen - curlen), "&amp;TIMEBUF=%s", clientid);
+ 				}
+ 			}
+ 		}
+@@ -708,6 +719,8 @@
+ 	int argi;
+ 	char *envarea = NULL;
+ 
++	multigraphs = ",disk,inode,qtree,quotas,snapshot,TblSpace,if_load,";
++
+ 	for (argi = 1; (argi < argc); argi++) {
+ 		if (strcmp(argv[argi], "--historical") == 0) {
+ 			source = SRC_HISTLOGS;
+@@ -739,8 +752,8 @@
+ 		}
+ 		else if (argnmatch(argv[argi], "--multigraphs=")) {
+ 			char *p = strchr(argv[argi], '=');
+-			multigraphs = (char *)malloc(strlen(p+1) + 3);
+-			sprintf(multigraphs, ",%s,", p+1);
++			SBUF_MALLOC(multigraphs, strlen(p+1) + 3);
++			snprintf(multigraphs, multigraphs_buflen, ",%s,", p+1);
+ 		}
+ 		else if (strcmp(argv[argi], "--no-disable") == 0) {
+ 			showenadis = 0;
+Index: xymon/web/history.c
+===================================================================
+--- xymon/web/history.c	(revision 8059)
++++ xymon/web/history.c	(working copy)
+@@ -21,7 +21,7 @@
+ 
+ #include "libxymon.h"
+ 
+-static char selfurl[PATH_MAX];
++SBUF_DEFINE(selfurl);
+ static time_t req_endtime = 0;
+ static char *displayname = NULL;
+ static int wantserviceid = 1;
+@@ -605,8 +605,10 @@
+ 		 */
+ 
+ 		if (strcasecmp(cwalk->name, "HISTFILE") == 0) {
+-			char *p = strrchr(cwalk->value, '.');
++			char *p = cwalk->value + strspn(cwalk->value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.,");
++			*p = '\0';
+ 
++			p = strrchr(cwalk->value, '.');
+ 			if (p) { *p = '\0'; service = strdup(p+1); }
+ 			hostname = strdup(basename(cwalk->value));
+ 			while ((p = strchr(hostname, ','))) *p = '.';
+@@ -644,7 +646,6 @@
+ int main(int argc, char *argv[])
+ {
+ 	char histlogfn[PATH_MAX];
+-	char tailcmd[PATH_MAX];
+ 	FILE *fd;
+ 	time_t start1d, start1w, start4w, start1y;
+ 	reportinfo_t repinfo1d, repinfo1w, repinfo4w, repinfo1y, dummyrep;
+@@ -673,22 +674,25 @@
+ 	cgidata = cgi_request();
+ 	parse_query();
+ 
++	SBUF_MALLOC(selfurl, 4096);
++
+ 	/* Build our own URL */
+-	sprintf(selfurl, "%s", histcgiurl(hostname, service));
++	snprintf(selfurl, selfurl_buflen, "%s", histcgiurl(hostname, service));
+ 
+ 	p = selfurl + strlen(selfurl);
+-	sprintf(p, "&amp;BARSUMS=%d", barsums);
++	snprintf(p, selfurl_buflen - (p - selfurl), "&amp;BARSUMS=%d", barsums);
+ 
+ 	if (strlen(ip)) {
++		SBUF_REALLOC(selfurl, selfurl_buflen + 6*strlen(ip));
+ 		p = selfurl + strlen(selfurl);
+-		sprintf(p, "&amp;IP=%s", htmlquoted(ip));
++		snprintf(p, selfurl_buflen - (p - selfurl), "&amp;IP=%s", htmlquoted(ip));
+ 	}
+ 
+ 	if (entrycount) {
+ 		p = selfurl + strlen(selfurl);
+-		sprintf(p, "&amp;ENTRIES=%d", entrycount);
++		snprintf(p, selfurl_buflen - (p - selfurl), "&amp;ENTRIES=%d", entrycount);
+ 	}
+-	else strcat(selfurl, "&amp;ENTRIES=ALL");
++	else strncat(selfurl, "&amp;ENTRIES=ALL", selfurl_buflen - strlen(selfurl));
+ 
+ 	if (usepct) {
+ 		/* Must modify 4-week charts to be 5-weeks, or the last day is 19% of the bar */
+@@ -704,7 +708,7 @@
+ 		len1y = 10; bartitle1y = "10 month summary";
+ 	}
+ 
+-	sprintf(histlogfn, "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service);
++	snprintf(histlogfn, sizeof(histlogfn), "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service);
+ 	fd = fopen(histlogfn, "r");
+ 	if (fd == NULL) {
+ 		errormsg("Cannot open history file");
+@@ -752,9 +756,13 @@
+ 		fclose(fd);
+ 	}
+ 	else {
++		SBUF_DEFINE(tailcmd);
++
+ 		/* Last 50 entries - we cheat and use "tail" in a pipe to pick the entries */
+ 		fclose(fd);
+-		sprintf(tailcmd, "tail -%d %s", entrycount, histlogfn);
++		SBUF_MALLOC(tailcmd, 1024 + strlen(histlogfn));
++
++		snprintf(tailcmd, tailcmd_buflen, "tail -%d %s", entrycount, histlogfn);
+ 		fd = popen(tailcmd, "r");
+ 		if (fd == NULL) errormsg("Cannot run tail on the histfile");
+ 		parse_historyfile(fd, &dummyrep, NULL, NULL, 0, getcurrenttime(NULL), 1, reportwarnlevel, reportgreenlevel, reportwarnstops, NULL);
+Index: xymon/web/acknowledge.c
+===================================================================
+--- xymon/web/acknowledge.c	(revision 8059)
++++ xymon/web/acknowledge.c	(working copy)
+@@ -158,14 +158,14 @@
+ void generate_ackline(FILE *output, char *hname, char *tname, char *ackcode)
+ {
+ 	static int num = 0;
+-	char numstr[10];
++	char numstr[15];
+ 
+ 	num++;
+ 	if (ackcode) {
+-		sprintf(numstr, "%d", num); 
++		snprintf(numstr, sizeof(numstr), "%d", num); 
+ 	}
+ 	else {
+-		strcpy(numstr, "all");
++		strncpy(numstr, "all", sizeof(numstr));
+ 	}
+ 
+ 	fprintf(output, "<tr>\n");
+@@ -242,7 +242,7 @@
+ 				 NULL, NULL);
+ 		}
+ 		else {
+-			char *cmd;
++			SBUF_DEFINE(cmd);
+ 			char *respbuf = NULL;
+ 			char *hostname, *pagename;
+ 			int gotfilter = 0, filtererror = 0;
+@@ -251,12 +251,12 @@
+ 
+ 			headfoot(stdout, "acknowledge", "", "header", COL_RED);
+ 
+-			cmd = (char *)malloc(1024);
+-			strcpy(cmd, "xymondboard fields=hostname,testname,cookie color=");
++			SBUF_MALLOC(cmd, 1024);
++			strncpy(cmd, "xymondboard fields=hostname,testname,cookie color=", cmd_buflen);
+ 			for (col = 0; (col < COL_COUNT); col++) {
+ 				if ((1 << col) & alertcolors) {
+-					if (!firstcolor) strcat(cmd, ",");
+-					strcat(cmd, colorname(col));
++					if (!firstcolor) strncat(cmd, ",", cmd_buflen - strlen(cmd));
++					strncat(cmd, colorname(col), cmd_buflen - strlen(cmd));
+ 					firstcolor = 0;
+ 				}
+ 			}
+@@ -265,16 +265,16 @@
+ 			if (obeycookies && !gotfilter && ((hostname = get_cookie("host")) != NULL)) {
+ 				if (*hostname) {
+ 					pcre *dummy;
+-					char *re;
+-					
+-					re = (char *)malloc(3+strlen(hostname));
+-					sprintf(re, "^%s$", hostname);
++					SBUF_DEFINE(re);
++
++					SBUF_MALLOC(re, 3+strlen(hostname));
++					snprintf(re, re_buflen, "^%s$", hostname);
+ 					dummy = compileregex(re);
+ 					if (dummy) {
+ 						/* Valid expression */
+ 						freeregex(dummy);
+-						cmd = (char *)realloc(cmd, 1024 + strlen(cmd) + strlen(re));
+-						sprintf(cmd + strlen(cmd), " host=%s", re);
++						SBUF_REALLOC(cmd, 1024 + strlen(cmd) + strlen(re));
++						snprintf(cmd + strlen(cmd), cmd_buflen - strlen(cmd), " host=%s", re);
+ 						gotfilter = 1;
+ 					}
+ 					else {
+@@ -287,16 +287,16 @@
+ 			if (obeycookies && !gotfilter && ((pagename = get_cookie("pagepath")) != NULL)) {
+ 				if (*pagename) {
+ 					pcre *dummy;
+-					char *re;
++					SBUF_DEFINE(re);
+ 
+-					re = (char *)malloc(8 + strlen(pagename)*2);
+-					sprintf(re, "%s$|^%s/.+", pagename, pagename);
++					SBUF_MALLOC(re, 8 + strlen(pagename)*2);
++					snprintf(re, re_buflen, "%s$|^%s/.+", pagename, pagename);
+ 					dummy = compileregex(re);
+ 					if (dummy) {
+ 						/* Valid expression */
+ 						freeregex(dummy);
+-						cmd = (char *)realloc(cmd, 1024 + strlen(cmd) + strlen(re));
+-						sprintf(cmd + strlen(cmd), " page=%s", re);
++						SBUF_REALLOC(cmd, 1024 + strlen(cmd) + strlen(re));
++						snprintf(cmd + strlen(cmd), cmd_buflen - strlen(cmd), " page=%s", re);
+ 						gotfilter = 1;
+ 					}
+ 					else {
+@@ -353,12 +353,13 @@
+ 		}
+ 	}
+ 	else if ( (nopin && (cgi_method == CGI_POST)) || (!nopin && (cgidata != NULL)) ) {
+-		char *xymonmsg;
+-		char *acking_user = "";
++		SBUF_DEFINE(xymonmsg);
++		SBUF_DEFINE(acking_user);
+ 		acklist_t *awalk;
+ 		strbuffer_t *response = newstrbuffer(0);
+ 		int count = 0;
+ 
++		acking_user = "";
+ 
+ 		/* We only want to accept posts from certain pages */
+ 		{ 
+@@ -375,9 +376,9 @@
+ 		if (getenv("REMOTE_USER")) {
+ 			char *remaddr = getenv("REMOTE_ADDR");
+ 
+-			acking_user = (char *)malloc(1024 + strlen(getenv("REMOTE_USER")) + (remaddr ? strlen(remaddr) : 0));
+-			sprintf(acking_user, "\nAcked by: %s", getenv("REMOTE_USER"));
+-			if (remaddr) sprintf(acking_user + strlen(acking_user), " (%s)", remaddr);
++			SBUF_MALLOC(acking_user, 1024 + strlen(getenv("REMOTE_USER")) + (remaddr ? strlen(remaddr) : 0));
++			snprintf(acking_user, acking_user_buflen, "\nAcked by: %s", getenv("REMOTE_USER"));
++			if (remaddr) snprintf(acking_user + strlen(acking_user), acking_user_buflen - strlen(acking_user), " (%s)", remaddr);
+ 		}
+ 
+ 		/* Load the host data (for access control) */
+@@ -388,8 +389,10 @@
+ 
+ 		addtobuffer(response, "<center>\n");
+ 		for (awalk = ackhead; (awalk); awalk = awalk->next) {
+-			char *msgline = (char *)malloc(1024 + (awalk->hostname ? strlen(awalk->hostname) : 0) + (awalk->testname ? strlen(awalk->testname) : 0));
++			SBUF_DEFINE(msgline);
+ 
++			SBUF_MALLOC(msgline, 1024 + (awalk->hostname ? MAX_HTMLQUOTE_FACTOR*strlen(awalk->hostname) : 0) + (awalk->testname ? MAX_HTMLQUOTE_FACTOR*strlen(awalk->testname) : 0));
++
+ 			if (!awalk->checked) continue;
+ 			if (accessfn && (!web_access_allowed(getenv("REMOTE_USER"), awalk->hostname, awalk->testname, WEB_ACCESS_CONTROL))) continue;
+ 
+@@ -407,35 +410,35 @@
+ 			count++;
+ 			if (!awalk->ackmsg || !awalk->validity || !awalk->acknum) {
+ 				if (awalk->hostname && awalk->testname) {
+-					sprintf(msgline, "<b>NO ACK</b> sent for host %s / test %s",
++					snprintf(msgline, msgline_buflen, "<b>NO ACK</b> sent for host %s / test %s",
+ 						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
+ 				}
+ 				else {
+-					sprintf(msgline, "<b>NO ACK</b> sent for item %d", awalk->id);
++					snprintf(msgline, msgline_buflen, "<b>NO ACK</b> sent for item %d", awalk->id);
+ 				}
+ 				addtobuffer(response, msgline);
+ 				addtobuffer(response, ": Duration or message not set<br>\n");
+ 				continue;
+ 			}
+ 
+-			xymonmsg = (char *)malloc(1024 + strlen(awalk->ackmsg) + strlen(acking_user));
+-			sprintf(xymonmsg, "xymondack %d %d %s %s", awalk->acknum, awalk->validity, awalk->ackmsg, acking_user);
++			SBUF_MALLOC(xymonmsg, 1024 + strlen(awalk->ackmsg) + strlen(acking_user));
++			snprintf(xymonmsg, xymonmsg_buflen, "xymondack %d %d %s %s", awalk->acknum, awalk->validity, awalk->ackmsg, acking_user);
+ 			if (sendmessage(xymonmsg, NULL, XYMON_TIMEOUT, NULL) == XYMONSEND_OK) {
+ 				if (awalk->hostname && awalk->testname) {
+-					sprintf(msgline, "Acknowledge sent for host %s / test %s<br>\n", 
++					snprintf(msgline, msgline_buflen, "Acknowledge sent for host %s / test %s<br>\n", 
+ 						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
+ 				}
+ 				else {
+-					sprintf(msgline, "Acknowledge sent for code %d<br>\n", awalk->acknum);
++					snprintf(msgline, msgline_buflen, "Acknowledge sent for code %d<br>\n", awalk->acknum);
+ 				}
+ 			}
+ 			else {
+ 				if (awalk->hostname && awalk->testname) {
+-					sprintf(msgline, "Failed to send acknowledge for host %s / test %s<br>\n", 
++					snprintf(msgline, msgline_buflen, "Failed to send acknowledge for host %s / test %s<br>\n", 
+ 						htmlquoted(awalk->hostname), htmlquoted(awalk->testname));
+ 				}
+ 				else {
+-					sprintf(msgline, "Failed to send acknowledge for code %d<br>\n", awalk->acknum);
++					snprintf(msgline, msgline_buflen, "Failed to send acknowledge for code %d<br>\n", awalk->acknum);
+ 				}
+ 			}
+ 
+Index: xymon/web/appfeed.c
+===================================================================
+--- xymon/web/appfeed.c	(revision 8059)
++++ xymon/web/appfeed.c	(working copy)
+@@ -85,7 +85,7 @@
+ 
+ 	FILE *output = stdout;
+ 
+-	char *xymondreq;
++	SBUF_DEFINE(xymondreq);
+ 	sendreturn_t *sres;
+ 	int xymondresult;
+ 	char *log, *bol, *eoln, *endkey;
+@@ -117,15 +117,17 @@
+ 
+ 	/* Setup the query for xymond */
+ 	parse_query();
+-	xymondreq = (char *)malloc(strlen(boardcmd) + strlen(fieldlist) + strlen(colorlist) + strlen(queryfilter) + 5);
+-	sprintf(xymondreq, "%s %s %s %s", boardcmd, fieldlist, colorlist, queryfilter);
++	SBUF_MALLOC(xymondreq, strlen(boardcmd) + strlen(fieldlist) + strlen(colorlist) + strlen(queryfilter) + 5);
++	snprintf(xymondreq, xymondreq_buflen, "%s %s %s %s", boardcmd, fieldlist, colorlist, queryfilter);
+ 
+ 	/* Get the current status */
+ 	sres = newsendreturnbuf(1, NULL);
+ 	xymondresult = sendmessage(xymondreq, NULL, XYMON_TIMEOUT, sres);
+ 	if (xymondresult != XYMONSEND_OK) {
+-		char *errtxt = (char *)malloc(1024 + strlen(xymondreq));
+-		sprintf(errtxt, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult);
++		SBUF_DEFINE(errtxt);
++
++		SBUF_MALLOC(errtxt, 1024 + MAX_HTMLQUOTE_FACTOR*strlen(xymondreq));
++		snprintf(errtxt, errtxt_buflen, "Status not available: Req=%s, result=%d\n", htmlquoted(xymondreq), xymondresult);
+ 		errormsg(errtxt);
+ 		return 1;
+ 	}
+Index: xymon/web/reportlog.c
+===================================================================
+--- xymon/web/reportlog.c	(revision 8059)
++++ xymon/web/reportlog.c	(working copy)
+@@ -25,7 +25,7 @@
+ char *hostname = NULL;
+ char *displayname = NULL;
+ char *ip = NULL;
+-char *reporttime = NULL;
++SBUF_DEFINE(reporttime);
+ char *service = NULL;
+ time_t st, end;
+ int style;
+@@ -55,21 +55,27 @@
+ 		 */
+ 
+ 		if (strcasecmp(cwalk->name, "HOSTSVC") == 0) {
+-			char *p = strrchr(cwalk->value, '.');
++			char *p = cwalk->value + strspn(cwalk->value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.,");
++			*p = '\0';
+ 
++			p = strrchr(cwalk->value, '.');
+ 			if (p) { *p = '\0'; service = strdup(p+1); }
+ 			hostname = strdup(basename(cwalk->value));
+ 			while ((p = strchr(hostname, ','))) *p = '.';
+ 		}
+ 		else if (strcasecmp(cwalk->name, "HOST") == 0) {
++			char *p = cwalk->value + strspn(cwalk->value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.,");
++			*p = '\0';
+ 			hostname = strdup(basename(cwalk->value));
+ 		}
+ 		else if (strcasecmp(cwalk->name, "SERVICE") == 0) {
++			char *p = cwalk->value + strspn(cwalk->value, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.,");
++			*p = '\0';
+ 			service = strdup(basename(cwalk->value));
+ 		}
+ 		else if (strcasecmp(cwalk->name, "REPORTTIME") == 0) {
+-			reporttime = (char *) malloc(strlen(cwalk->value)+strlen("REPORTTIME=")+1);
+-			sprintf(reporttime, "REPORTTIME=%s", cwalk->value);
++			SBUF_MALLOC(reporttime, strlen(cwalk->value)+strlen("REPORTTIME=")+1);
++			snprintf(reporttime, reporttime_buflen, "REPORTTIME=%s", cwalk->value);
+ 		}
+ 		else if (strcasecmp(cwalk->name, "WARNPCT") == 0) {
+ 			reportwarnlevel = atof(cwalk->value);
+@@ -87,8 +93,10 @@
+ 			end = atol(cwalk->value);
+ 		}
+ 		else if (strcasecmp(cwalk->name, "COLOR") == 0) {
+-			char *colstr = (char *) malloc(strlen(cwalk->value)+2);
+-			sprintf(colstr, "%s ", cwalk->value);
++			SBUF_DEFINE(colstr);
++
++			SBUF_MALLOC(colstr, strlen(cwalk->value)+2);
++			snprintf(colstr, colstr_buflen, "%s ", cwalk->value);
+ 			color = parse_color(colstr);
+ 			xfree(colstr);
+ 		}
+@@ -102,15 +110,19 @@
+ 
+ int main(int argc, char *argv[])
+ {
+-	char histlogfn[PATH_MAX];
++	SBUF_DEFINE(histlogfn);
+ 	FILE *fd;
+-	char *textrepfn = NULL, *textrepfullfn = NULL, *textrepurl = NULL;
++	SBUF_DEFINE(textrepfn);
++	SBUF_DEFINE(textrepfullfn);
++	SBUF_DEFINE(textrepurl);
+ 	FILE *textrep;
+ 	reportinfo_t repinfo;
+ 	int argi;
+ 	char *envarea = NULL;
+ 	void *hinfo;
+ 
++	SBUF_MALLOC(histlogfn, PATH_MAX);
++
+ 	for (argi=1; (argi < argc); argi++) {
+ 		if (argnmatch(argv[argi], "--env=")) {
+ 			char *p = strchr(argv[argi], '=');
+@@ -135,7 +147,7 @@
+ 	displayname = xmh_item(hinfo, XMH_DISPLAYNAME);
+ 	if (!displayname) displayname = hostname;
+ 
+-	sprintf(histlogfn, "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service);
++	snprintf(histlogfn, histlogfn_buflen, "%s/%s.%s", xgetenv("XYMONHISTDIR"), commafy(hostname), service);
+ 	fd = fopen(histlogfn, "r");
+ 	if (fd == NULL) {
+ 		errormsg("Cannot open history file");
+@@ -144,12 +156,12 @@
+ 	color = parse_historyfile(fd, &repinfo, hostname, service, st, end, 0, reportwarnlevel, reportgreenlevel, reportwarnstops, reporttime);
+ 	fclose(fd);
+ 
+-	textrepfn = (char *)malloc(1024 + strlen(hostname) + strlen(service));
+-	sprintf(textrepfn, "avail-%s-%s-%u-%lu.txt", hostname, service, (unsigned int)getcurrenttime(NULL), (unsigned long)getpid());
+-	textrepfullfn = (char *)malloc(1024 + strlen(xgetenv("XYMONREPDIR")) + strlen(textrepfn));
+-	sprintf(textrepfullfn, "%s/%s", xgetenv("XYMONREPDIR"), textrepfn);
+-	textrepurl = (char *)malloc(1024 + strlen(xgetenv("XYMONREPURL")) + strlen(textrepfn));
+-	sprintf(textrepurl, "%s/%s", xgetenv("XYMONREPURL"), textrepfn);
++	SBUF_MALLOC(textrepfn, 1024 + strlen(hostname) + strlen(service));
++	snprintf(textrepfn, textrepfn_buflen, "avail-%s-%s-%u-%lu.txt", hostname, service, (unsigned int)getcurrenttime(NULL), (unsigned long)getpid());
++	SBUF_MALLOC(textrepfullfn, 1024 + strlen(xgetenv("XYMONREPDIR")) + strlen(textrepfn));
++	snprintf(textrepfullfn, textrepfullfn_buflen, "%s/%s", xgetenv("XYMONREPDIR"), textrepfn);
++	SBUF_MALLOC(textrepurl, 1024 + strlen(xgetenv("XYMONREPURL")) + strlen(textrepfn));
++	snprintf(textrepurl, textrepurl_buflen, "%s/%s", xgetenv("XYMONREPURL"), textrepfn);
+ 	textrep = fopen(textrepfullfn, "w");
+ 
+ 	/* Now generate the webpage */
diff -Nru xymon-4.3.28/debian/patches/series xymon-4.3.28/debian/patches/series
--- xymon-4.3.28/debian/patches/series	2019-02-19 14:12:14.000000000 +0100
+++ xymon-4.3.28/debian/patches/series	2019-08-23 01:07:47.000000000 +0200
@@ -20,3 +20,4 @@
 84_fix_compilation_on_GNU_Hurd.patch
 87_fix_logfetch_FTBFS_with_glibc_2.26.patch
 90_fix-spelling-errors.patch
+91_4.3.29-CVEs.patch

-- System Information:
Debian Release: bullseye/sid
  APT prefers unstable
  APT policy: (990, 'unstable'), (980, 'unstable-debug'), (600, 'testing'), (111, 'buildd-unstable'), (111, 'buildd-experimental'), (110, 'experimental'), (105, 'experimental-debug')
Architecture: amd64 (x86_64)

Kernel: Linux 4.19.0-5-amd64 (SMP w/2 CPU cores)
Locale: LANG=C.UTF-8, LC_CTYPE=C.UTF-8 (charmap=UTF-8), LANGUAGE=C.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

--- End Message ---
--- Begin Message ---
Version: 10.1

Hi,

The fixes referenced by each of these bugs were included in today's
buster point release.

Regards,

Adam

--- End Message ---

Reply to: