[Pkg-electronics-commits] [pcb-rnd] 02/02: security patch from upstream

Bdale Garbee bdale at moszumanska.debian.org
Tue Sep 19 02:26:11 UTC 2017


This is an automated email from the git hooks/post-receive script.

bdale pushed a commit to branch stretch
in repository pcb-rnd.

commit 4c69d4b8aff368916ddce4c129467ff50f3f1acd
Author: Bdale Garbee <bdale at gag.com>
Date:   Sun Sep 17 18:54:21 2017 -0600

    security patch from upstream
---
 debian/changelog                  |   7 ++
 debian/patches/0006-exec-bug.diff | 255 ++++++++++++++++++++++++++++++++++++++
 debian/patches/series             |   1 +
 3 files changed, 263 insertions(+)

diff --git a/debian/changelog b/debian/changelog
index 75986bf..7def87f 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+pcb-rnd (1.1.4-2) stable; urgency=high
+
+  * security patch from upstream to eliminate execution of code from a 
+    maliciously formed design file
+
+ -- Bdale Garbee <bdale at gag.com>  Sun, 17 Sep 2017 18:53:45 -0600
+
 pcb-rnd (1.1.4-1) unstable; urgency=low
 
   * New upstream release (Closes: #843839)
diff --git a/debian/patches/0006-exec-bug.diff b/debian/patches/0006-exec-bug.diff
new file mode 100644
index 0000000..1e192f8
--- /dev/null
+++ b/debian/patches/0006-exec-bug.diff
@@ -0,0 +1,255 @@
+diff --git a/src/conf.c b/src/conf.c
+index 1bd67bf..78381e3 100644
+--- a/src/conf.c
++++ b/src/conf.c
+@@ -1808,3 +1808,65 @@ void conf_setf(conf_role_t role, const char *path, int idx, const char *fmt, ...
+ 
+ 	free(tmp);
+ }
++
++int pcb_conf_cmd_is_safe_(const char *path_, const char *value, const char **val_out, int msg)
++{
++	const char *reason;
++	conf_native_t *nd;
++	char *path, *s;
++
++	if (val_out != NULL)
++		*val_out = NULL;
++
++	if (value == NULL)
++		goto accept;
++
++	path = pcb_strdup(path_);
++	for(s = path; *s != '\0'; s++)
++		if (*s == '.')
++			*s = '/';
++	nd = conf_get_field(path);
++	free(path);
++
++	if (nd == NULL) {
++		if (msg)
++			Message(PCB_MSG_ERROR, "pcb_conf_cmd_is_safe(): invalid node path '%s' (looks like an internal error)\n", path_);
++		return 0;
++	}
++
++	if (nd->array_size > 1) {
++		if (msg)
++			Message(PCB_MSG_ERROR, "pcb_conf_cmd_is_safe(): invalid node path '%s' (it is an array)\n", path_);
++		return 0;
++	}
++
++	switch(conf_lookup_role(nd->prop[0].src)) {
++		/* these are considered safe, because: */
++		case CFR_INTERNAL: /* the attacker would have access to the source code and compilation, could place system() anyway */
++		case CFR_SYSTEM:   /* system admin - lets trust them */
++		case CFR_USER:     /* user config is written by the user, attackers have no better chance to overwrite that than overwriting the the shell's rc */
++		case CFR_CLI:      /* command line arguments: the user specified those; who has access to that potentially has access to the shell anyway */
++			goto accept;
++
++		/* these are considered unsafe, because: */
++		case CFR_DEFAULTPCB: /* the default pcb path may be manipulated; the user has the chance to specify the command path setting from safe config files */
++			reason = "default pcb"; break;
++		case CFR_ENV: /* env vars may be inherited from who-knows-where */
++			reason = "env var"; break;
++		case CFR_PROJECT: /* malicous file prepared by the attacker */
++			reason = "project file"; break;
++		case CFR_DESIGN: /* malicous file prepared by the attacker */
++			reason = "board file"; break;
++		default:
++			reason = "unknown source";
++	}
++
++	if (msg)
++		Message(PCB_MSG_ERROR, "pcb_conf_cmd_is_safe(): refusing to use the value of '%s' because it is from unsafe source %s\n", path_, reason);
++	return 0;
++
++	accept:;
++	if (val_out != NULL)
++		*val_out = value;
++	return 1;
++}
+diff --git a/src/conf.h b/src/conf.h
+index 9a33545..9b2c808 100644
+--- a/src/conf.h
++++ b/src/conf.h
+@@ -355,4 +355,10 @@ int conf_parse_text(confitem_t *dst, int idx, conf_native_type_t type, const cha
+ /* Determine the file name of the project file - project_fn and pcb_fn can be NULL */
+ const char *conf_get_project_conf_name(const char *project_fn, const char *pcb_fn, const char **out_project_fn);
+ 
++/* Return 1 if the config node named in path is considered safe enough
++   to specify a command to execute - e.g. an attacker shouldn't be able to
++   inject commands in design files sent */
++int pcb_conf_cmd_is_safe_(const char *path, const char *value, const char **val_out, int msg);
++#define pcb_conf_cmd_is_safe(path, val_out, msg) pcb_conf_cmd_is_safe_(#path, conf_core.path, val_out, msg)
++
+ #endif
+diff --git a/src/plug_io.c b/src/plug_io.c
+index 352356c..cd3d679 100644
+--- a/src/plug_io.c
++++ b/src/plug_io.c
+@@ -54,6 +54,7 @@
+ #include "buffer.h"
+ #include "change.h"
+ #include "create.h"
++#include "conf.h"
+ #include "data.h"
+ #include "error.h"
+ #include "plug_io.h"
+@@ -871,13 +872,17 @@ int WritePipe(const char *Filename, pcb_bool thePcb, const char *fmt)
+ 	int result;
+ 	const char *p;
+ 	static gds_t command;
++	const char *save_cmd;
+ 
+ 	if (EMPTY_STRING_P(conf_core.rc.save_command))
+ 		return WritePCBFile(Filename, thePcb, fmt, pcb_false);
+ 
++	if (!pcb_conf_cmd_is_safe(rc.save_command, &save_cmd, 1))
++		return -1;
++
+ 	/* setup commandline */
+ 	gds_truncate(&command,0);
+-	for (p = conf_core.rc.save_command; *p; p++) {
++	for (p = save_cmd; *p; p++) {
+ 		/* copy character if not special or add string to command */
+ 		if (!(p[0] == '%' && p[1] == 'f'))
+ 			gds_append(&command, *p);
+diff --git a/src_plugins/fp_fs/fp_fs.c b/src_plugins/fp_fs/fp_fs.c
+index 52f7dd1..144a8ac 100644
+--- a/src_plugins/fp_fs/fp_fs.c
++++ b/src_plugins/fp_fs/fp_fs.c
+@@ -449,9 +449,11 @@ static FILE *fp_fs_fopen(plug_fp_t *ctx, const char *path, const char *name, fp_
+ {
+ 	char *basename, *params, *fullname;
+ 	FILE *f = NULL;
+-	const char *libshell = conf_core.rc.library_shell;
++	const char *libshell;
+ 
++	pcb_conf_cmd_is_safe(rc.library_shell, &libshell, 1);
+ 	fctx->field[F_IS_PARAMETRIC].i = fp_dupname(name, &basename, &params);
++
+ 	if (basename == NULL)
+ 		return NULL;
+ 
+diff --git a/src_plugins/import_netlist/import_netlist.c b/src_plugins/import_netlist/import_netlist.c
+index e567a91..04b4015 100644
+--- a/src_plugins/import_netlist/import_netlist.c
++++ b/src_plugins/import_netlist/import_netlist.c
+@@ -57,13 +57,16 @@ static int ReadNetlist(const char *filename)
+ 	int i, j, lines, kind;
+ 	pcb_bool continued;
+ 	int used_popen = 0;
++	const char *ratcmd;
+ 
+ 	if (!filename)
+ 		return (1);									/* nothing to do */
+ 
+ 	Message(PCB_MSG_DEFAULT, _("Importing PCB netlist %s\n"), filename);
+ 
+-	if (EMPTY_STRING_P(conf_core.rc.rat_command)) {
++	pcb_conf_cmd_is_safe(rc.rat_command, &ratcmd, 1);
++
++	if (EMPTY_STRING_P(ratcmd)) {
+ 		fp = fopen(filename, "r");
+ 		if (!fp) {
+ 			Message(PCB_MSG_DEFAULT, "Cannot open %s for reading", filename);
+diff --git a/src_plugins/io_pcb/parse_l.c b/src_plugins/io_pcb/parse_l.c
+index 34993df..3114dc3 100644
+--- a/src_plugins/io_pcb/parse_l.c
++++ b/src_plugins/io_pcb/parse_l.c
+@@ -2505,16 +2505,23 @@ do { \
+ int io_pcb_ParsePCB(plug_io_t *ctx, PCBTypePtr Ptr, const char *Filename, conf_role_t settings_dest)
+ {
+ 	int retval;
++	const char *fcmd;
+ 	yyPCB = Ptr;
+ 	yyData = NULL;
+ 	yyFont = NULL;
+ 	yyElement = NULL;
+ 	yy_settings_dest = settings_dest;
++
++	if (!pcb_conf_cmd_is_safe(rc.file_command, &fcmd, 1))
++		return -1;
++
+ 	if (settings_dest != CFR_invalid)
+ 		conf_reset(settings_dest, Filename);
++
+ 	setlocale(LC_ALL, "C"); /* make sure numerics are read predictably */
+-	retval = Parse(NULL, conf_core.rc.file_command, conf_core.rc.file_path, Filename, NULL);
++	retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename, NULL);
+ 	setlocale(LC_ALL, "");
++
+ 	if ((settings_dest != CFR_invalid) && (retval == 0)) {
+ 		/* overwrite settings from the flags, mark them not-to-save */
+ 		CONF_SET(settings_dest, "plugins/mincut/enable", -1, CONF_BOOL_FLAG(ENABLEPCB_FLAG_MINCUT, yy_pcb_flags), POL_OVERWRITE);
+@@ -2578,13 +2585,18 @@ int io_pcb_ParsePCB(plug_io_t *ctx, PCBTypePtr Ptr, const char *Filename, conf_r
+  */
+ int io_pcb_ParseFont(plug_io_t *ctx, FontTypePtr Ptr, const char *Filename)
+ {
+-	int r = 0;
++	int r = 0, valid;
++	const char *fcmd;
+ 	yyPCB = NULL;
+ 	yyFont = Ptr;
+ 	yyElement = NULL;
+ 
++	if (!pcb_conf_cmd_is_safe(rc.font_command, &fcmd, 1))
++		return -1;
++
+ 	yy_settings_dest = CFR_invalid;
+-	r = Parse(NULL, conf_core.rc.font_command, NULL, Filename, NULL);
++	r = Parse(NULL, fcmd, NULL, Filename, NULL);
++
+ 	if (r == 0) {
+ #ifdef DEBUG
+ 		Message (PCB_MSG_DEBUG, "Found %s in %s\n", Filename, conf_core.rc.font_command);
+diff --git a/src_plugins/io_pcb/parse_l.l b/src_plugins/io_pcb/parse_l.l
+index 4623223..109a57c 100644
+--- a/src_plugins/io_pcb/parse_l.l
++++ b/src_plugins/io_pcb/parse_l.l
+@@ -370,16 +370,23 @@ do { \
+ int io_pcb_ParsePCB(plug_io_t *ctx, PCBTypePtr Ptr, const char *Filename, conf_role_t settings_dest)
+ {
+ 	int retval;
++	const char *fcmd;
+ 	yyPCB = Ptr;
+ 	yyData = NULL;
+ 	yyFont = NULL;
+ 	yyElement = NULL;
+ 	yy_settings_dest = settings_dest;
++
++	if (!pcb_conf_cmd_is_safe(rc.file_command, &fcmd, 1))
++		return -1;
++
+ 	if (settings_dest != CFR_invalid)
+ 		conf_reset(settings_dest, Filename);
++
+ 	setlocale(LC_ALL, "C"); /* make sure numerics are read predictably */
+-	retval = Parse(NULL, conf_core.rc.file_command, conf_core.rc.file_path, Filename, NULL);
++	retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename, NULL);
+ 	setlocale(LC_ALL, "");
++
+ 	if ((settings_dest != CFR_invalid) && (retval == 0)) {
+ 		/* overwrite settings from the flags, mark them not-to-save */
+ 		CONF_SET(settings_dest, "plugins/mincut/enable", -1, CONF_BOOL_FLAG(ENABLEPCB_FLAG_MINCUT, yy_pcb_flags), POL_OVERWRITE);
+@@ -443,13 +450,18 @@ int io_pcb_ParsePCB(plug_io_t *ctx, PCBTypePtr Ptr, const char *Filename, conf_r
+  */
+ int io_pcb_ParseFont(plug_io_t *ctx, FontTypePtr Ptr, const char *Filename)
+ {
+-	int r = 0;
++	int r = 0, valid;
++	const char *fcmd;
+ 	yyPCB = NULL;
+ 	yyFont = Ptr;
+ 	yyElement = NULL;
+ 
++	if (!pcb_conf_cmd_is_safe(rc.font_command, &fcmd, 1))
++		return -1;
++
+ 	yy_settings_dest = CFR_invalid;
+-	r = Parse(NULL, conf_core.rc.font_command, NULL, Filename, NULL);
++	r = Parse(NULL, fcmd, NULL, Filename, NULL);
++
+ 	if (r == 0) {
+ #ifdef DEBUG
+ 		Message (PCB_MSG_DEBUG, "Found %s in %s\n", Filename, conf_core.rc.font_command);
diff --git a/debian/patches/series b/debian/patches/series
index 5be0e44..2d20a46 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,4 @@
 0003-I-use-the-CFLAGS-from-.-configure-CFLAGS.patch
 0004-gsch2pcb-uses-the-CFLAGS-LDFLAGS-from-.-configure.patch
 0005-docs-no-longer-load-images-from-the-internet.patch
+0006-exec-bug.diff

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-electronics/pcb-rnd.git



More information about the Pkg-electronics-commits mailing list