[Pkg-electronics-commits] [pcb-rnd] 01/01: security patch from upstream
Bdale Garbee
bdale at moszumanska.debian.org
Mon Sep 18 00:56:51 UTC 2017
This is an automated email from the git hooks/post-receive script.
bdale pushed a commit to tag debian/1.2.5-2
in repository pcb-rnd.
commit 84c208a5c9eab2eda03431516d2e452383410ae4
Author: Bdale Garbee <bdale at gag.com>
Date: Sun Sep 17 18:23:45 2017 -0600
security patch from upstream
---
debian/changelog | 7 ++
debian/patches/exec-bug.diff | 253 +++++++++++++++++++++++++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 261 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index c9c3f16..f7afe89 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,10 @@
+pcb-rnd (1.2.5-2) unstable; 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:23:29 -0600
+
pcb-rnd (1.2.5-1) unstable; urgency=medium
* New upstream version
diff --git a/debian/patches/exec-bug.diff b/debian/patches/exec-bug.diff
new file mode 100644
index 0000000..406b018
--- /dev/null
+++ b/debian/patches/exec-bug.diff
@@ -0,0 +1,253 @@
+diff --git a/src/conf.c b/src/conf.c
+index 17bfb41..92449d4 100644
+--- a/src/conf.c
++++ b/src/conf.c
+@@ -1869,3 +1869,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)
++ pcb_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)
++ pcb_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)
++ pcb_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 e1b62ec..8e2a143 100644
+--- a/src/conf.h
++++ b/src/conf.h
+@@ -366,4 +366,10 @@ const char *conf_get_user_conf_name();
+ /* 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 b51a284..9251b49 100644
+--- a/src/plug_io.c
++++ b/src/plug_io.c
+@@ -48,6 +48,7 @@
+ #include <string.h>
+
+ #include "change.h"
++#include "conf.h"
+ #include "data.h"
+ #include "error.h"
+ #include "plug_io.h"
+@@ -896,13 +897,17 @@ int pcb_write_pipe(const char *Filename, pcb_bool thePcb, const char *fmt, pcb_b
+ int result;
+ const char *p;
+ static gds_t command;
++ const char *save_cmd;
+
+ if (PCB_EMPTY_STRING_P(conf_core.rc.save_command))
+ return pcb_write_pcb_file(Filename, thePcb, fmt, pcb_false, elem_only);
+
++ 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 4d6d153..d592f55 100644
+--- a/src_plugins/fp_fs/fp_fs.c
++++ b/src_plugins/fp_fs/fp_fs.c
+@@ -464,7 +464,9 @@ static FILE *fp_fs_fopen(pcb_plug_fp_t *ctx, const char *path, const char *name,
+ {
+ 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 = pcb_fp_dupname(name, &basename, ¶ms);
+ if (basename == NULL)
+diff --git a/src_plugins/import_netlist/import_netlist.c b/src_plugins/import_netlist/import_netlist.c
+index 27c3af3..60f5a9e 100644
+--- a/src_plugins/import_netlist/import_netlist.c
++++ b/src_plugins/import_netlist/import_netlist.c
+@@ -58,13 +58,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 */
+
+ pcb_message(PCB_MSG_INFO, _("Importing PCB netlist %s\n"), filename);
+
+- if (PCB_EMPTY_STRING_P(conf_core.rc.rat_command)) {
++ pcb_conf_cmd_is_safe(rc.rat_command, &ratcmd, 1);
++
++ if (PCB_EMPTY_STRING_P(ratcmd)) {
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pcb_message(PCB_MSG_ERROR, "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 b8bf493..7d46b23 100644
+--- a/src_plugins/io_pcb/parse_l.c
++++ b/src_plugins/io_pcb/parse_l.c
+@@ -2516,6 +2516,7 @@ do { \
+ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, conf_role_t settings_dest)
+ {
+ int retval;
++ const char *fcmd;
+ yy_parse_tags = 0;
+ yyPCB = Ptr;
+ yyData = NULL;
+@@ -2524,10 +2525,15 @@ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename,
+ yyFontkitValid = 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);
+ pcb_setlocale(LC_ALL, "C"); /* make sure numerics are read predictably */
+- retval = Parse(NULL, conf_core.rc.file_command, conf_core.rc.file_path, Filename);
++
++ retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename);
+ pcb_setlocale(LC_ALL, "");
+ if ((settings_dest != CFR_invalid) && (retval == 0)) {
+ /* overwrite settings from the flags, mark them not-to-save */
+@@ -2593,6 +2599,7 @@ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename,
+ int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename)
+ {
+ int r = 0, valid;
++ const char *fcmd;
+ yy_parse_tags = 1;
+ yyPCB = NULL;
+ yyFont = Ptr;
+@@ -2600,8 +2607,11 @@ int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename)
+ yyElement = NULL;
+ yyFontReset = pcb_false;
+
++ 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);
++ r = Parse(NULL, fcmd, NULL, Filename);
+ if (r == 0) {
+ #ifdef DEBUG
+ pcb_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 66bc301..76174be 100644
+--- a/src_plugins/io_pcb/parse_l.l
++++ b/src_plugins/io_pcb/parse_l.l
+@@ -375,6 +375,7 @@ do { \
+ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename, conf_role_t settings_dest)
+ {
+ int retval;
++ const char *fcmd;
+ yy_parse_tags = 0;
+ yyPCB = Ptr;
+ yyData = NULL;
+@@ -383,10 +384,15 @@ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename,
+ yyFontkitValid = 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);
+ pcb_setlocale(LC_ALL, "C"); /* make sure numerics are read predictably */
+- retval = Parse(NULL, conf_core.rc.file_command, conf_core.rc.file_path, Filename);
++
++ retval = Parse(NULL, fcmd, conf_core.rc.file_path, Filename);
+ pcb_setlocale(LC_ALL, "");
+ if ((settings_dest != CFR_invalid) && (retval == 0)) {
+ /* overwrite settings from the flags, mark them not-to-save */
+@@ -452,6 +458,7 @@ int io_pcb_ParsePCB(pcb_plug_io_t *ctx, pcb_board_t *Ptr, const char *Filename,
+ int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename)
+ {
+ int r = 0, valid;
++ const char *fcmd;
+ yy_parse_tags = 1;
+ yyPCB = NULL;
+ yyFont = Ptr;
+@@ -459,8 +466,11 @@ int io_pcb_ParseFont(pcb_plug_io_t *ctx, pcb_font_t *Ptr, const char *Filename)
+ yyElement = NULL;
+ yyFontReset = pcb_false;
+
++ 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);
++ r = Parse(NULL, fcmd, NULL, Filename);
+ if (r == 0) {
+ #ifdef DEBUG
+ pcb_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 e69de29..b477798 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -0,0 +1 @@
+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