debian/0000775000000000000000000000000013115364430007170 5ustar debian/copyright0000664000000000000000000000132113113236152011115 0ustar This package was debianized by Oliver Kurth on Tue, 20 Jan 2004 11:49:29 +0100. It was adopted by Matt Palmer in August 2008, after a brief stint under the control of the QA team. It was downloaded from http://efault.net/npat/hacks/picocom/ Upstream Author: Nick Patavalis (npat@efault.net) Copyright: Copyright (C) 2004 Nick Patavalis (npat@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. On Debian systems, the text of the GPL can be found in /usr/share/common-licenses/GPL. debian/patches/0000775000000000000000000000000013114361763010624 5ustar debian/patches/CVE-2015-9059.patch0000664000000000000000000003661113114361763013262 0ustar 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 +#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 (npat@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 +#include +#include + +#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: \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 (npat@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 + * , see below) is considered normal and becomes part of the + * current argument. If, outside of quotes, a backslash precedes a + * , 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: + */ debian/patches/series0000664000000000000000000000002413114361722012030 0ustar CVE-2015-9059.patch debian/dirs0000664000000000000000000000001013113236152010040 0ustar usr/bin debian/changelog0000664000000000000000000000332613115364430011046 0ustar picocom (1.7-2build0.14.04.1) trusty-security; urgency=medium * fake sync from Debian -- Emily Ratliff Mon, 05 Jun 2017 18:28:24 -0500 picocom (1.7-2) unstable; urgency=high * Fix CVE-2015-9059 (Closes: #863671). * Add myself to Uploaders. * Add Vcs fields. -- W. Martin Borgert Fri, 02 Jun 2017 22:21:14 +0000 picocom (1.7-1) unstable; urgency=low * New upstream release. Closes: #659590. * Switch to dpkg-source 3.0 (quilt) format. * Bump debhelper compat to 8, switch to minimal dh-based debian/rules. * Update Homepage: field. * Update Standards-Version to 3.9.3; no changes required. -- Matt Palmer Sat, 21 Apr 2012 18:48:46 +1000 picocom (1.4-3) unstable; urgency=low * Adopted. Closes: #452192. * Dump the debian-native packaging. * Fix odd parity problems. Closes: #492695. Thanks to Freddy Spierenburg for the patch. -- Matt Palmer Sun, 03 Aug 2008 22:52:39 +1000 picocom (1.4-2) unstable; urgency=low * QA upload. * Set Maintainer to QA Group. The previous Maintainer email is bouncing. -- Lucas Nussbaum Thu, 10 Jan 2008 09:04:17 +0100 picocom (1.4-1) unstable; urgency=low * new upstream version: - Changed the behavior of the C-a command. Now pressing C-a twice sends C-a to the serial port - Added the C-\ command that generates a break sequence - Added (optional) UUCP-lockfiles support -- Oliver Kurth Tue, 14 Sep 2004 11:25:07 -0700 picocom (1.3-1) unstable; urgency=low * Initial Release (closes: #236044) * upstream included my man page -- Oliver Kurth Sun, 07 Mar 2004 19:43:34 -0800 debian/source/0000775000000000000000000000000013113236152010465 5ustar debian/source/format0000664000000000000000000000001413113236152011673 0ustar 3.0 (quilt) debian/rules0000775000000000000000000000003513113236152010243 0ustar #!/usr/bin/make -f %: dh $@ debian/compat0000664000000000000000000000000213113236152010363 0ustar 8 debian/docs0000664000000000000000000000003113113236152010032 0ustar README TODO CONTRIBUTORS debian/install0000664000000000000000000000002013113236152010546 0ustar picocom usr/bin debian/manpages0000664000000000000000000000001213113236152010674 0ustar picocom.8 debian/examples0000664000000000000000000000002513113236152010723 0ustar pcasc pcxm pcym pczm debian/control0000664000000000000000000000170113113240760010567 0ustar Source: picocom Section: comm Priority: optional Maintainer: Matt Palmer Uploaders: W. Martin Borgert 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 Depends: ${shlibs:Depends}, ${misc:Depends} Description: minimal dumb-terminal emulation program picocom was designed to serve as a simple, manual, modem configuration, testing, and debugging tool. It has also served (quite well) as a low-tech "terminal-window" to allow operator intervention in PPP connection scripts (something like the ms-windows "open terminal window before / after dialing" feature). It could also prove useful in many other similar tasks. It is ideal for embedded systems since its memory footprint is minimal.