Subject: Speeding up the vulnerabilities check
To: None <tech-pkg@netbsd.org>
From: Roland Illig <roland.illig@gmx.de>
List: tech-pkg
Date: 02/27/2005 03:25:50
This is a multi-part message in MIME format.
--------------000304090403020708010807
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi all,

I was bored by waiting 5 (NetBSD) to 15 (Solaris) seconds on the 
check-vulnerable target to finish, so I wrote a replacement for it. May 
  I integrate it into pkgsrc if I document it properly?

Before the patch, one pkg_admin(8) process is spawned for every line in
pkg-vulnerabilities. There are almost 1000 lines now, and the number is 
monotonically increasing. After the patch, pkg_admin(8) is just called once.

I built this function into the pkg_admin utility because the function 
pmatch is defined there and libnbcompat is included, too. So it was just 
laziness. ;)

One intended use is:

pkg_admin checkvuln perl-5.8.6nb2 \
     /var/cache/distfiles/pkg-vulnerabilities

Another is:

vulndb=/var/cache/distfiles/pkg-vulnerabilities
if pkg_admin checkvuln $installed_version $vulndb; then
   : "the installed version is not listed as vulnerable"
else
   if pkg_admin checkvuln $current_version $vulndb; then
     : "install the current version"
   else
     : "both are vulnerable"
   fi
fi

Roland


--------------000304090403020708010807
Content-Type: text/plain;
 name="check-vulnerable.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="check-vulnerable.patch"

Index: pkgtools/pkg_install/files/admin/main.c
===================================================================
RCS file: /cvsroot/pkgsrc/pkgtools/pkg_install/files/admin/main.c,v
retrieving revision 1.17
diff -u -p -r1.17 main.c
--- pkgtools/pkg_install/files/admin/main.c	29 Dec 2004 12:16:56 -0000	1.17
+++ pkgtools/pkg_install/files/admin/main.c	27 Feb 2005 02:08:14 -0000
@@ -441,6 +441,61 @@ lsbasepattern_fn(const char *pkg, void *
 	return 0;
 }
 
+/* returns 1 if the package is vulnerable according to the list of
+ * vulnerabilities in vulnfile, 0 if it is not. If the vulnerabilites
+ * file cannot be read, the function terminates the process. */
+static int
+checkvuln(const char *pkg, const char *vulnfile)
+{
+	int		 retval = 0;
+	FILE		*f;
+	char		 line[1024];
+	size_t		 len, lineno;
+	char		*v_pattern, *v_type, *v_url, *p;
+
+	f = fopen(vulnfile, "r");
+	if (f == NULL)
+		err(EXIT_FAILURE, "%s", vulnfile);
+
+	lineno = 0;
+	while (fgets(line, sizeof(line), f)) {
+		lineno++;
+
+		len = strlen(line);
+		if (len == sizeof(line) - 1 && line[len - 1] != '\n')
+			errx(EXIT_FAILURE, "%s, line %d: Line too long", vulnfile, lineno);
+
+		if (line[0] == '#' || line[0] == '\n')
+			continue;
+
+		v_pattern = line;
+		p = v_pattern + strcspn(v_pattern, " \t");
+		if (*p == '\0')
+			errx(EXIT_FAILURE, "%s, line %d: Line too short", vulnfile, lineno);
+		*p++ = '\0';
+
+		v_type = p + strspn(p, " \t");
+		p = v_type + strcspn(v_type, " \t");
+		if (*p == '\0')
+			errx(EXIT_FAILURE, "%s, line %d: Line too short", vulnfile, lineno);
+		*p++ = '\0';
+
+		v_url = p + strspn(p, " \t");
+		p = v_url + strcspn(v_url, " \t\n");
+		if (*p != '\n')
+			errx(EXIT_FAILURE, "%s, line %d: Garbage at end of line", vulnfile, lineno);
+		*p++ = '\0';
+
+		if (pmatch(v_pattern, pkg)) {
+			(void) printf("*** WARNING - %s vulnerability in %s -- see %s for more information ***\n",
+				v_type, pkg, v_url);
+			retval = 1;
+		}
+	}
+	(void) fclose(f);
+	return retval;
+}
+
 int 
 main(int argc, char *argv[])
 {
@@ -524,6 +579,23 @@ main(int argc, char *argv[])
 			return 1;
 		}
 	  
+	} else if (strcasecmp(argv[0], "checkvuln") == 0) {
+
+		char *pkg, *vulnfile;
+
+		if (argv[1] == NULL || argv[2] == NULL) {
+			usage(prog);
+		}
+
+		pkg = argv[1];
+		vulnfile = argv[2];
+
+		if (checkvuln(pkg, vulnfile)) {
+			return 1;
+		} else {
+			return 0;
+		}
+
 	} else if (strcasecmp(argv[0], "rebuild") == 0) {
 
 		rebuild();
Index: mk/bsd.pkg.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/bsd.pkg.mk,v
retrieving revision 1.1595
diff -u -p -r1.1595 bsd.pkg.mk
--- mk/bsd.pkg.mk	25 Feb 2005 13:05:52 -0000	1.1595
+++ mk/bsd.pkg.mk	27 Feb 2005 02:08:17 -0000
@@ -1386,11 +1386,7 @@ batch-check-distfiles:
 .PHONY: check-vulnerable
 check-vulnerable:
 	@if [ -f ${PKGVULNDIR}/pkg-vulnerabilities ]; then		\
-		${SETENV} PKGNAME="${PKGNAME}"				\
-			  PKGBASE="${PKGBASE}"				\
-			${AWK} '/^$$/ { next }				\
-				/^#.*/ { next }				\
-				{ s = sprintf("${PKG_ADMIN} pmatch \"%s\" %s && ${ECHO} \"*** WARNING - %s vulnerability in %s - see %s for more information ***\"", $$1, ENVIRON["PKGNAME"], $$2, ENVIRON["PKGNAME"], $$3); system(s); }' < ${PKGVULNDIR}/pkg-vulnerabilities || ${FALSE}; \
+		${PKG_ADMIN} checkvuln ${PKGNAME} ${PKGVULNDIR}/pkg-vulnerabilities || ${TRUE}; \
 	fi
 
 .PHONY: do-fetch

--------------000304090403020708010807--