Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package picocom A recently discovered vulnerability (CVE-2015-9059) is fixed with this version. Vcs fields and Uploader change are in line with version 2.2-1, which is already in experimental. diff -Nru picocom-1.7/debian/changelog picocom-1.7/debian/changelog --- picocom-1.7/debian/changelog 2012-04-21 10:49:20.000000000 +0200 +++ picocom-1.7/debian/changelog 2017-06-03 00:21:14.000000000 +0200 @@ -1,3 +1,11 @@ +picocom (1.7-2) unstable; urgency=high + + * Fix CVE-2015-9059 (Closes: #863671). + * Add myself to Uploaders. + * Add Vcs fields. + + -- W. Martin Borgert <deba...@debian.org> Fri, 02 Jun 2017 22:21:14 +0000 + picocom (1.7-1) unstable; urgency=low * New upstream release. Closes: #659590. diff -Nru picocom-1.7/debian/control picocom-1.7/debian/control --- picocom-1.7/debian/control 2012-04-21 10:48:42.000000000 +0200 +++ picocom-1.7/debian/control 2017-05-30 11:57:04.000000000 +0200 @@ -2,9 +2,12 @@ Section: comm Priority: optional Maintainer: Matt Palmer <mpal...@debian.org> +Uploaders: W. Martin Borgert <deba...@debian.org> Build-Depends: debhelper (>= 8.0.0) Standards-Version: 3.9.3 Homepage: http://code.google.com/p/picocom/ +Vcs-Browser: https://anonscm.debian.org/cgit/collab-maint/picocom.git +Vcs-Git: https://anonscm.debian.org/git/collab-maint/picocom.git Package: picocom Architecture: any diff -Nru picocom-1.7/debian/patches/CVE-2015-9059.patch picocom-1.7/debian/patches/CVE-2015-9059.patch --- picocom-1.7/debian/patches/CVE-2015-9059.patch 1970-01-01 01:00:00.000000000 +0100 +++ picocom-1.7/debian/patches/CVE-2015-9059.patch 2017-06-03 00:17:23.000000000 +0200 @@ -0,0 +1,500 @@ +Description: fix CVE-2015-9059 (command injection vulnerability) +Origin: upstream +Bug-Vendor: https://bugs.debian.org/863671 +Applied-Upstream: https://github.com/npat-efault/picocom/commit/1ebc60b20fbe9a02436d5cbbf8951714e749ddb1 +Last-Update: 2017-06-02 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +--- a/picocom.c ++++ b/picocom.c +@@ -41,6 +41,7 @@ + #define _GNU_SOURCE + #include <getopt.h> + ++#include "split.h" + #include "term.h" + + /**********************************************************************/ +@@ -544,6 +545,9 @@ + + /**********************************************************************/ + ++#define RUNCMD_ARGS_MAX 32 ++#define RUNCMD_EXEC_FAIL 126 ++ + void + child_empty_handler (int signum) + { +@@ -564,7 +568,7 @@ + } + + int +-run_cmd(int fd, ...) ++run_cmd(int fd, const char *cmd, const char *args_extra) + { + pid_t pid; + sigset_t sigm, sigm_old; +@@ -600,9 +604,10 @@ + } + } else { + /* child: external program */ +- int r; + long fl; +- char cmd[512]; ++ int argc; ++ char *argv[RUNCMD_ARGS_MAX + 1]; ++ int r; + + establish_child_signal_handlers(); + sigprocmask(SIG_SETMASK, &sigm_old, NULL); +@@ -619,30 +624,29 @@ + close(STO); + dup2(fd, STI); + dup2(fd, STO); +- { +- /* build command-line */ +- char *c, *ce; +- const char *s; +- int n; +- va_list vls; +- +- c = cmd; +- ce = cmd + sizeof(cmd) - 1; +- va_start(vls, fd); +- while ( (s = va_arg(vls, const char *)) ) { +- n = strlen(s); +- if ( c + n + 1 >= ce ) break; +- memcpy(c, s, n); c += n; +- *c++ = ' '; +- } +- va_end(vls); +- *c = '\0'; ++ /* build command arguments vector */ ++ argc = 0; ++ r = split_quoted(cmd, &argc, argv, RUNCMD_ARGS_MAX); ++ if ( r < 0 ) { ++ fd_printf(STDERR_FILENO, "Cannot parse command\n"); ++ exit(RUNCMD_EXEC_FAIL); ++ } ++ r = split_quoted(args_extra, &argc, argv, RUNCMD_ARGS_MAX); ++ if ( r < 0 ) { ++ fd_printf(STDERR_FILENO, "Cannot parse extra args\n"); ++ exit(RUNCMD_EXEC_FAIL); ++ } ++ if ( argc < 1 ) { ++ fd_printf(STDERR_FILENO, "No command given\n"); ++ exit(RUNCMD_EXEC_FAIL); + } ++ argv[argc] = NULL; ++ + /* run extenral command */ +- fd_printf(STDERR_FILENO, "%s\n", cmd); +- r = system(cmd); +- if ( WIFEXITED(r) ) exit(WEXITSTATUS(r)); +- else exit(128); ++ fd_printf(STDERR_FILENO, "$ %s %s\n", cmd, args_extra); ++ execvp(argv[0], argv); ++ fd_printf(STDERR_FILENO, "exec: %s\n", strerror(errno)); ++ exit(RUNCMD_EXEC_FAIL); + } + } + +@@ -807,7 +811,7 @@ + if ( r < -1 && errno == EINTR ) break; + if ( r <= -1 ) + fatal("cannot read filename: %s", strerror(errno)); +- run_cmd(tty_fd, opts.send_cmd, fname, NULL); ++ run_cmd(tty_fd, opts.send_cmd, fname); + break; + case KEY_RECEIVE: + fd_printf(STO, "*** file: "); +@@ -817,7 +821,7 @@ + if ( r <= -1 ) + fatal("cannot read filename: %s", strerror(errno)); + if ( fname[0] ) +- run_cmd(tty_fd, opts.receive_cmd, fname, NULL); ++ run_cmd(tty_fd, opts.receive_cmd, fname); + else + run_cmd(tty_fd, opts.receive_cmd, NULL); + break; +--- a/Makefile ++++ b/Makefile +@@ -13,11 +13,12 @@ + LDFLAGS = -g + LDLIBS = + +-picocom : picocom.o term.o ++picocom : picocom.o term.o split.o + # $(LD) $(LDFLAGS) -o $@ $+ $(LDLIBS) + + picocom.o : picocom.c term.h + term.o : term.c term.h ++split.o : split.c split.h + + doc : picocom.8 picocom.8.html picocom.8.ps + +--- /dev/null ++++ b/split.c +@@ -0,0 +1,236 @@ ++/* vi: set sw=4 ts=4: ++ * ++ * split.c ++ * ++ * Function that splits a string intro arguments with quoting. ++ * ++ * by Nick Patavalis (n...@efault.net) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ * USA ++ */ ++ ++#include <stdlib.h> ++#include <string.h> ++#include <assert.h> ++ ++#include "split.h" ++ ++/* Lexer error end-codes */ ++enum err_codes { ++ ERR_OK = 0, /* no error, string lexed ok */ ++ ERR_BS_AT_EOS, /* backslash at the end of string */ ++ ERR_SQ_OPEN_AT_EOS, /* single-quote left open */ ++ ERR_DQ_OPEN_AT_EOS /* double-quote left open */ ++}; ++ ++/* Lexer states */ ++enum states { ++ ST_DELIM, ++ ST_QUOTE, ++ ST_ARG, ++ ST_END ++}; ++ ++/* Special characters */ ++#define BS '\\' ++#define SQ '\'' ++#define DQ '\"' ++#define NL '\n' ++#define EOS '\0' ++ ++#define is_delim(c) \ ++ ( (c) == ' ' || (c) == '\t' || (c) == '\n' ) ++ ++#define is_dq_escapable(c) \ ++ ( (c) == '\\' || (c) == '\"' || (c) == '`' || (c) == '$' ) ++ ++/* Short-hands used in split_quoted() */ ++#define push() \ ++ do { \ ++ char *arg; \ ++ if ( *argc < argv_sz ) { \ ++ *ap = '\0'; \ ++ arg = strdup(arg_buff); \ ++ /* !! out of mem !! */ \ ++ if ( ! arg ) return -1; \ ++ argv[*argc] = arg; \ ++ (*argc)++; \ ++ } else { \ ++ flags |= SPLIT_DROP; \ ++ } \ ++ ap = &arg_buff[0]; \ ++ } while(0) ++ ++#define save() \ ++ do { \ ++ if (ap != ae) { \ ++ *ap++ = *c; \ ++ } else { \ ++ flags |= SPLIT_TRUNC; \ ++ } \ ++ } while (0) ++ ++int ++split_quoted (const char *s, int *argc, char *argv[], int argv_sz) ++{ ++ char arg_buff[MAX_ARG_LEN]; /* current argument buffer */ ++ char *ap, *ae; /* arg_buff current ptr & end-guard */ ++ const char *c; /* current input charcter ptr */ ++ char qc; /* current quote character */ ++ enum states state; /* current state */ ++ enum err_codes err; /* error end-code */ ++ int flags; /* warning flags */ ++ ++ ap = &arg_buff[0]; ++ ae = &arg_buff[MAX_ARG_LEN - 1]; ++ c = &s[0]; ++ state = ST_DELIM; ++ err = ERR_OK; ++ flags = 0; ++ qc = SQ; /* silence compiler waring */ ++ ++ while ( state != ST_END ) { ++ switch (state) { ++ case ST_DELIM: ++ while ( is_delim(*c) ) c++; ++ if ( *c == SQ || *c == DQ ) { ++ qc = *c; c++; state = ST_QUOTE; ++ break; ++ } ++ if ( *c == EOS ) { ++ state = ST_END; ++ break; ++ } ++ if ( *c == BS ) { ++ c++; ++ if ( *c == NL ) { ++ c++; ++ break; ++ } ++ if ( *c == EOS ) { ++ state = ST_END; err = ERR_BS_AT_EOS; ++ break; ++ } ++ } ++ /* All other cases incl. character after BS */ ++ save(); c++; state = ST_ARG; ++ break; ++ case ST_QUOTE: ++ while ( *c != qc && ( *c != BS || qc == SQ ) && *c != EOS ) { ++ save(); c++; ++ } ++ if ( *c == qc ) { ++ c++; state = ST_ARG; ++ break; ++ } ++ if ( *c == BS ) { ++ assert (qc == DQ); ++ c++; ++ if ( *c == NL) { ++ c++; ++ break; ++ } ++ if (*c == EOS) { ++ state = ST_END; err = ERR_BS_AT_EOS; ++ break; ++ } ++ if ( ! is_dq_escapable(*c) ) { ++ c--; save(); c++; ++ } ++ save(); c++; ++ break; ++ } ++ if ( *c == EOS ) { ++ state = ST_END; err = ERR_SQ_OPEN_AT_EOS; ++ break; ++ } ++ assert(0); ++ case ST_ARG: ++ if ( *c == SQ || *c == DQ ) { ++ qc = *c; c++; state = ST_QUOTE; ++ break; ++ } ++ if ( is_delim(*c) || *c == EOS ) { ++ push(); ++ state = (*c == EOS) ? ST_END : ST_DELIM; ++ c++; ++ break; ++ } ++ if ( *c == BS ) { ++ c++; ++ if ( *c == NL ) { ++ c++; ++ break; ++ } ++ if ( *c == EOS ) { ++ state = ST_END; err = ERR_BS_AT_EOS; ++ break; ++ } ++ } ++ /* All other cases, incl. character after BS */ ++ save(); c++; ++ break; ++ default: ++ assert(0); ++ } ++ } ++ ++ return ( err != ERR_OK ) ? -1 : flags; ++} ++ ++/**********************************************************************/ ++ ++#if 0 ++ ++int ++main (int argc, char *argv[]) ++{ ++ char *my_argv[12]; ++ int my_argc, i, r; ++ ++ if ( argc != 2 ) { ++ printf("Usage is: %s: <string to split>\n", argv[0]); ++ exit(EXIT_FAILURE); ++ } ++ ++ printf("String to split is: [%s]\n", argv[1]); ++ r = split_quoted(argv[1], &my_argc, my_argv, 12); ++ if ( r < 0 ) { ++ printf("Spliting failed!\n"); ++ exit(EXIT_FAILURE); ++ } ++ printf("Split ok. SPLIT_DROP is %s, SPLIT_TRUNC is %s\n", ++ (r & SPLIT_DROP) ? "ON" : "off", ++ (r & SPLIT_TRUNC) ? "ON" : "off"); ++ ++ for (i = 0; i < my_argc; i++) ++ printf("%02d : [%s]\n", i, my_argv[i]); ++ ++ return EXIT_SUCCESS; ++} ++ ++#endif ++ ++/**********************************************************************/ ++ ++/* ++ * Local Variables: ++ * mode:c ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ +--- /dev/null ++++ b/split.h +@@ -0,0 +1,123 @@ ++/* vi: set sw=4 ts=4: ++ * ++ * split.h ++ * ++ * Function that splits a string intro arguments with quoting. ++ * ++ * by Nick Patavalis (n...@efault.net) ++ * ++ * This program is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU General Public License as ++ * published by the Free Software Foundation; either version 2 of the ++ * License, or (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, but ++ * WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 ++ * USA ++ */ ++ ++#ifndef SPLIT_H ++#define SPLIT_H ++ ++/* Maximum single-argument length that can be dealt-with by function ++ * split_quoted(). Longer arguments are truncated. See below. ++ */ ++#define MAX_ARG_LEN 512 ++ ++/* Warning flags, set by split_quoted() to its return value. */ ++#define SPLIT_DROP (1 << 0) /* argument had to be dropped */ ++#define SPLIT_TRUNC (1 << 1) /* argument had to be truncated */ ++ ++ ++/* F split_quoted ++ * ++ * Splits string "s" into arguments and places them in "argv". Every ++ * argument is a heap-allocated null-terminated string that must be ++ * freed with free(3) when no longer needed. The first argument is ++ * placed in "argv[*argc]", the following at subsequent "argv" slots, ++ * and "*argc" is incremented accordingly. As a result, this function ++ * can be called multiple times to add arguments to the same argument ++ * vector. The argument "argv_sz" is the allocated size (in number of ++ * slots) of the supplied argument vector ("argv"). The function takes ++ * care not to overrun it. If more arguments are present in the ++ * input string "s", they are dropped. ++ * ++ * When spliting the input string intro arguments, quoting rules ++ * very similar to the ones used by the Unix shell are used. ++ * ++ * The following caracters are considered special: ' ' (space), '\t' ++ * (tab), '\n' (newline), '\' (backslash), ''' (single quote), and '"' ++ * (double quote). All other caracters are considered normal and can ++ * become part of an argument without escaping. ++ * ++ * Arguments are separated by runs of the characters: ' ' (space), ++ * '\t', and '\n', which are considered delimiters. ++ * ++ * All characters beetween single quotes (')---without ++ * exceptions---are considered normal and become part of the current ++ * argument (but not the single quotes themselves). ++ * ++ * All characters between double quotes (") are considered normal and ++ * become part of the current argument (but not the double quotes ++ * themselves). Exception to this is the backslash character, when ++ * followed by one of the characters '"', '\', '$', and '`'. In this ++ * case, the backslash is removed, and the next caracter is considered ++ * normal and becomes part of the current argument. When the backslash ++ * is followed by newline, both the backslash and the newline are ++ * removed. In all other cases a backslash, within double quotes, is ++ * considered a normal character (and becomes part of the current ++ * argument). We treat the sequences '\$' and '\`' specially (while ++ * there is no real reason), for better unix-shell compatibility. ++ * ++ * Outside of single or double quotes, every backslash caracter is ++ * removed, and the following character (with the exception of ++ * <newline>, see below) is considered normal and becomes part of the ++ * current argument. If, outside of quotes, a backslash precedes a ++ * <newline>, then both the backslash and the newline are removed. ++ * ++ * Examples: ++ * ++ * a b c d --> [a] [b] [c] [d] ++ * 'a b' c d --> [a b] [c] [d] ++ * 'a "b"' c d --> [a "b"] [c] [d] ++ * "a 'b'" c d --> [a 'b'] [c] [d] ++ * a"b c" d --> [ab c] [d] ++ * a\ b c d --> [a b] [c] [d] ++ * \a\b c d --> [ab] [c] [d] ++ * \a\\b \\ c d --> [a\b] [\] [c] [d] ++ * "a\$\b" c d --> [a$\b] [c] [d] ++ * "\a\`\"\b" c d --> [\a`"\b] [c] [d] ++ * ++ * Limitation: This function cannot deal with individual arguments ++ * longer than MAX_ARG_LEN. If such an argument is encountered, it is ++ * truncated accordingly. ++ * ++ * This function returns a non-negative on success, and a negative on ++ * failure. The only causes for failure is a malformed command string ++ * (e.g. un-balanced quotes), or the inability to allocate an argument ++ * string. On success the value returned can be checked against the ++ * warning flags SPLIT_DROP, and SPLIT_TRUNC. If SPLIT_DROP is set, ++ * then a least one argument was dropped as there was no available ++ * slot in "argv" to store it in. If SPLIT_TRUNC is set, then at least ++ * one argument was truncated (see limitation, above). ++ */ ++int split_quoted(const char *s, int *argc, char *argv[], int argv_sz); ++ ++#endif /* of SPLIT_H */ ++ ++/**********************************************************************/ ++ ++/* ++ * Local Variables: ++ * mode:c ++ * tab-width: 4 ++ * c-basic-offset: 4 ++ * indent-tabs-mode: nil ++ * End: ++ */ diff -Nru picocom-1.7/debian/patches/series picocom-1.7/debian/patches/series --- picocom-1.7/debian/patches/series 1970-01-01 01:00:00.000000000 +0100 +++ picocom-1.7/debian/patches/series 2017-06-03 00:16:50.000000000 +0200 @@ -0,0 +1 @@ +CVE-2015-9059.patch unblock picocom/1.7-2