diff -u pscan-1.2/debian/changelog pscan-1.2/debian/changelog --- pscan-1.2/debian/changelog +++ pscan-1.2/debian/changelog @@ -1,3 +1,18 @@ +pscan (1.2-9) unstable; urgency=low + + * Standards-Version: 3.8.0. + + debian/control: Add Homepage field. + * debian/copyright: + + Convert to machine-readable format. + + Update author's email address. + + Fix broken upstream website URL (Closes: #454404). + * Fix "push_stack: Assertion `stack_index < 8192'" (Closes: #436794). + Thanks Elliott Hughes for the patch. + * Rework manpage a bit to fix cosmetics and prevent lintian errors. + * debian/watch: Add dummy file to silence lintian. + + -- Uwe Hermann Sat, 26 Jul 2008 01:10:01 +0200 + pscan (1.2-8) unstable; urgency=low * New maintainer (Closes: #390221). reverted: --- pscan-1.2/debian/patches/scanner.patch +++ pscan-1.2.orig/debian/patches/scanner.patch @@ -1,111 +0,0 @@ ---- pscan-1.2.orig/scanner.l -+++ pscan-1.2/scanner.l -@@ -1,21 +1,31 @@ --%option yylineno - - %{ - #include "pscan.h" - static void skip_strings(char literal); -+extern int cur_lineno; - %} - - %x comment - %x strings - --reserved "default"|"struct"|"void"|"for"|"if"|"else"|"while"|"do"|"return"|"case"|"switch"|"break"|"auto"|"continue"|"goto"|"sizeof"|"static"|"typedef"|"union"|"volatile" -+reserved "default"|"struct"|"void"|"for"|"if"|"else"|"while"|"do"|"return"|"case"|"switch"|"break"|"auto"|"continue"|"goto"|"sizeof"|"static"|"typedef"|"union"|"volatile"|"asm" - - vartype "char"|"double"|"enum"|"extern"|"float"|"int"|"long"|"register"|"short"|"signed"|"unsigned"|"const" - --cprep "include"|"define"|"if"|"else"|"endif"|"ifdef"|"ifndef" -+cprep "include"|"define"|"undef"|"if"|"else"|"elif"|"endif"|"ifdef"|"ifndef"|"error"|"line"|"pragma" -+ - - %% --{reserved} state->last_token = NOT_PROBLEMATIC; -+{reserved} {// Ignore reserved words because issue arises -+ // if reserved sizeof used as argument to a defined -+ // problematic function such as snprintf -+ // but we also do not want to attempt to check these -+ // for defined issues in setup_checks function as we know -+ // they are undefined -+ // Default last_token state is NOT_PROBLEMATIC -+ -+ // state->last_token = NOT_PROBLEMATIC; -+ } - - {vartype} state->last_token = NOT_PROBLEMATIC; - -@@ -39,7 +49,8 @@ - - \' skip_strings('\''); - --\/\/.*$ /* skip C++ style comments */ -+ -+\/\/[^\n]* /* skip C++ style comments */ - - [a-zA-Z_][_a-zA-Z0-9]* state = setup_checks(yytext, state); - -@@ -81,17 +92,15 @@ - } - } - -- --"\n"|"\r" /* ignore LF's and CR's */ -- -- - "/*" BEGIN(comment); - - [^*\n]* /* eat anything that's not a '*' */ - "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ --\n /* do nothing */ -+\n {cur_lineno++;} - "*"+"/" BEGIN(INITIAL); - -+"\n" { cur_lineno++;} -+ - %% - /********************************************************************** - * pscan: http://www.striker.ottawa.on.ca/~aland/pscan/ -@@ -118,24 +127,22 @@ - /* static */ - void skip_strings(char literal) - { -- int c; -+ int c,last_c=0,done=0; -+ -+ while (!done) -+ { -+ c=input(); -+ -+ if (c==EOF) -+ return; -+ -+ if ((last_c!='\\') && (c==literal)) // non escaped literal found -+ done=1; -+ else if ((last_c=='\\') && (c=='\\')) // avoid \\ issue -+ last_c=0; -+ else -+ last_c=c; -+ } - -- while ((c = input()) != literal) -- { -- switch (c) { -- -- case '\\': -- c = input(); -- if (c == '\\') continue; -- if (c == EOF) return; -- if (c != literal) -- unput(c); -- break; -- case EOF: -- return; -- -- default: -- break; -- } -- } -+ return; - } reverted: --- pscan-1.2/debian/patches/pscan.patch +++ pscan-1.2.orig/debian/patches/pscan.patch @@ -1,177 +0,0 @@ ---- pscan-1.2.orig/pscan.c -+++ pscan-1.2/pscan.c -@@ -31,8 +31,8 @@ - #include "pscan.h" - - extern int yylex(); --extern int yylineno; - extern FILE *yyout, *yyin; -+int cur_lineno=1; - - /* - * This function does nothing useful. -@@ -100,7 +100,7 @@ - { - fprintf(stderr, "Usage: pscan [-vw] [-p problem_file] \n"); - fprintf(stderr, "Attempts to discover a number of common security abuses in C source files.\n\n"); -- fprintf(stderr, " -v Verbose mode. Can be use multiple times for more output.\n"); -+ fprintf(stderr, " -v Verbose mode. \n"); - fprintf(stderr, " -w Show warnings when a variable is used as the format argument.\n"); - fprintf(stderr, " -p file Read additional problem definitions from .\n"); - exit(1); -@@ -206,7 +206,7 @@ - break; - - case 'v': -- verbose++; -+ verbose= TRUE; - break; - - case 'w': -@@ -261,7 +261,7 @@ - /* - * Initialize our variables. - */ -- yylineno = 1; -+ cur_lineno = 1; - - if (verbose) { - printf("Scanning %s ...\n", filename); -@@ -280,18 +280,22 @@ - /* - * And finally, print out a summary of the total problems. - */ -- if (total_errors != 0) { -- if (verbose) { -- if (warnings) { -- printf("Warnings: %d\n", total_warnings); -- } -+ if (verbose) { -+ if (total_errors != 0 ) { - printf("Total problems identified: %d\n", total_errors); -+ } - -+ if (warnings) { -+ if (total_warnings != 0 ) { -+ printf("Warnings: %d\n",total_warnings); -+ } - } -- exit(1); - } -- -- exit(0); -+ -+ if (total_errors!=0) -+ exit(1); -+ else -+ exit(0); - } - - /* -@@ -300,8 +304,9 @@ - */ - void check_function(parser_state_t *state) - { -- assert(state != NULL); -+ int erroneous=0; - -+ assert(state != NULL); - /* - * This was a reference to a function WITHOUT an opening brace, - * so it's not a function call. Ignore it. -@@ -310,7 +315,6 @@ - return; - } - -- if (verbose == 0) { - /* - * The problem function has the SAME number of arguments as the - * placement of the format argument. i.e. The LAST argument of the -@@ -329,9 +333,11 @@ - state->line, - state->problem->function, - state->problem->fmt_arg); -- total_errors++; -+ erroneous=1; -+ -+ } - -- } else if (warnings && -+ if (warnings && - (state->constant_string != state->problem->fmt_arg)) { - printf("%s:%d Warning: %s uses non-constant string for format argument %d.\n", - filename, -@@ -341,25 +347,28 @@ - total_warnings++; - } - -- } else { -+ if (verbose) { - /* -- * verbose = 1, print out more stuff. -+ * verbose =TRUE, print out more stuff. - */ - printf("%s:%d FUNC %s ", filename, state->line, - state->problem->function); - if (state->problem->fmt_arg == state->args) { - printf("Last argument is "); -- if (state->constant_string) { -+ if (state->constant_string==state->args) { - printf("constant string: OK\n"); - } else { - printf("variable or reference: BAD\n"); -- total_errors++; -+ erroneous=1; - } - } else { - printf("format string with %d parameters: OK\n", - state->args - state->problem->fmt_arg); - } - } -+ -+ if (erroneous) total_errors++; -+ - } - - /* -@@ -401,7 +410,7 @@ - } - - state->problem = problem; -- state->line = yylineno; -+ state->line = cur_lineno; - state->braces = 0; - state->args = -1; - state->constant_string = -1; -@@ -425,7 +434,7 @@ - } - - state->problem = problem; -- state->line = yylineno; -+ state->line = cur_lineno; - state->braces = 0; - state->args = -1; - state->constant_string = -1; ---- pscan-1.2.orig/pscan.h -+++ pscan-1.2/pscan.h -@@ -31,6 +31,8 @@ - #define PROBLEMATIC TRUE - #define NOT_PROBLEMATIC FALSE - -+#define YY_NO_UNPUT -+ - /* - * The maximum number of user-defined problem functions which may be - * read from a .pscan problem definition file. ---- pscan-1.2.orig/test.c -+++ pscan-1.2/test.c -@@ -149,3 +149,9 @@ - * NetBSD allows err(1,NULL). We should, too. - */ - err(1, NULL); -+ -+/* -+ * A reserved function sizeof() as argument should not affect result when testing snprintf -+ * expected that this is an error -+ */ -+snprintf(b,sizeof(b),argv[1]); reverted: --- pscan-1.2/debian/patches/manpage.patch +++ pscan-1.2.orig/debian/patches/manpage.patch @@ -1,54 +0,0 @@ ---- pscan-1.2.orig/pscan.1 -+++ pscan-1.2/pscan.1 -@@ -0,0 +1,51 @@ -+.\" pscan man page -+.\" -+.\" -+.\" .de Id -+.\" .ds Dt \\$4 -+.\" .. -+.\" .Id 1.0 -+.\" .ds = \-\^\- -+.\" .de Sp -+.\" .if t .sp .3 -+.\" .if n .sp -+.\" .. -+.\" .ta 3n -+.TH "pscan" "1" "\*(Dt" "GNU" "" -+.SH "NAME" -+pscan \- Format string security checker for C source code -+.SH "SYNOPSIS" -+.B pscan -+.RI [ options ] -+.Sp -+.B pscan -+is a source code analysis tool which is designed to highlight potentially dangerous uses of variadic functions such as "printf", "syslog", etc. -+ -+ -+ -+.SH "DETAILS" -+.Sp -+ The scan works by looking for a one of a list of problem functions, and applying the following rule: -+.Sp -+ IF the last parameter of the function is the format string, -+ AND the format string is NOT a static string, -+ THEN complain. -+.Sp -+ -+.SH "LIMITATIONS" -+.Sp -+ The code will not report on some potention buffer overflows, because that is not its goal. For example the following code is potential dangerous: -+.Sp -+ sprintf( static_buffer, "%s/.foorc", getenv("HOME") ); -+.Sp -+ This code could cause an issue as there is no immediately obvious bounds checking. However this is a safe usages with regards to format strings. -+ -+ -+.SH "RETURN VALUES" -+.Sp -+ If there are any errors found, pscan exits with status 1. -+ -+ -+.SH "AUTHOR Alan DeKok " -+ -+ diff -u pscan-1.2/debian/copyright pscan-1.2/debian/copyright --- pscan-1.2/debian/copyright +++ pscan-1.2/debian/copyright @@ -3,39 +3,29 @@ It is currently maintained by Uwe Hermann . -It was downloaded from: http://www.striker.ottawa.on.ca/%7Ealand/pscan/ +It was downloaded from: -Upstream Author: Alan DeKok + http://www.striker.ottawa.on.ca/%7Ealand/pscan/ (no longer available) + Author's new blog: http://deployingradius.com/blog/ -Copyright: 2000 Alan DeKok +Upstream Author: -License: + Alan DeKok - This package 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 package 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 package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +Files: * +Copyright: © 2000 Alan DeKok +License: GPL-2+ On Debian systems, the complete text of the GNU General Public License can be found in `/usr/share/common-licenses/GPL'. ------------------------------------------------------------------------------ -Makefile: - -Copyright: 2000 Alan DeKok - -License: - +Files: Makefile +Copyright: © 2000 Alan DeKok +License: other This Makefile is free software; Alan DeKok gives unlimited permission to copy and/or distribute it, with or without modifications, as long as this notice is preserved. @@ -49,6 +39,8 @@ -Debian packaging copyright: - +Files: debian/* +Copyright: © 2006 - 2008 Uwe Hermann +License: PD The packaging done by Uwe Hermann is hereby - released as public domain. + released as public domain. The packaging was completely redone by me, + pretty much nothing left from the previous maintainers. diff -u pscan-1.2/debian/control pscan-1.2/debian/control --- pscan-1.2/debian/control +++ pscan-1.2/debian/control @@ -3,7 +3,8 @@ Priority: optional Maintainer: Uwe Hermann Build-Depends: cdbs, debhelper (>= 5), flex -Standards-Version: 3.7.2.2 +Standards-Version: 3.8.0 +Homepage: http://deployingradius.com/blog/ Package: pscan Architecture: any diff -u pscan-1.2/debian/rules pscan-1.2/debian/rules --- pscan-1.2/debian/rules +++ pscan-1.2/debian/rules @@ -1,7 +1,7 @@ #!/usr/bin/make -f DEB_INSTALL_DOCS_ALL := README -DEB_INSTALL_MANPAGES_pscan := pscan.1 +DEB_INSTALL_MANPAGES_pscan := debian/pscan.1 DEB_INSTALL_EXAMPLES_pscan := test.c wu-ftpd.pscan binary-install/pscan:: only in patch2: unchanged: --- pscan-1.2.orig/debian/pscan.1 +++ pscan-1.2/debian/pscan.1 @@ -0,0 +1,30 @@ +.TH PSCAN 1 +.SH "NAME" +pscan \- Format string security checker for C source code +.SH "SYNOPSIS" +.B pscan +.RI [ options ] +.SH DESCRIPTION +.B pscan +is a source code analysis tool which is designed to highlight potentially +dangerous uses of variadic functions such as "printf", "syslog", etc. +The scan works by looking for a one of a list of problem functions, and +applying the following rule: +.PP +IF the last parameter of the function is the format string, +AND the format string is NOT a static string, +THEN complain. +.SH LIMITATIONS +The code will not report on some potention buffer overflows, because that +is not its goal. For example the following code is potential dangerous: +.PP +.B " sprintf(static_buffer, "%s/.foorc", getenv("HOME"));" +.PP +This code could cause an issue as there is no immediately obvious bounds +checking. However this is a safe usages with regards to format strings. +.SH "RETURN VALUES" +If there are any errors found, +.B pscan +exits with status 1. +.SH AUTHOR +Alan DeKok only in patch2: unchanged: --- pscan-1.2.orig/debian/watch +++ pscan-1.2/debian/watch @@ -0,0 +1 @@ +# Not used, there's no upstream URL anymore, upstream is inactive. only in patch2: unchanged: --- pscan-1.2.orig/debian/patches/20_pscan.patch +++ pscan-1.2/debian/patches/20_pscan.patch @@ -0,0 +1,177 @@ +--- pscan-1.2.orig/pscan.c ++++ pscan-1.2/pscan.c +@@ -31,8 +31,8 @@ + #include "pscan.h" + + extern int yylex(); +-extern int yylineno; + extern FILE *yyout, *yyin; ++int cur_lineno=1; + + /* + * This function does nothing useful. +@@ -100,7 +100,7 @@ + { + fprintf(stderr, "Usage: pscan [-vw] [-p problem_file] \n"); + fprintf(stderr, "Attempts to discover a number of common security abuses in C source files.\n\n"); +- fprintf(stderr, " -v Verbose mode. Can be use multiple times for more output.\n"); ++ fprintf(stderr, " -v Verbose mode. \n"); + fprintf(stderr, " -w Show warnings when a variable is used as the format argument.\n"); + fprintf(stderr, " -p file Read additional problem definitions from .\n"); + exit(1); +@@ -206,7 +206,7 @@ + break; + + case 'v': +- verbose++; ++ verbose= TRUE; + break; + + case 'w': +@@ -261,7 +261,7 @@ + /* + * Initialize our variables. + */ +- yylineno = 1; ++ cur_lineno = 1; + + if (verbose) { + printf("Scanning %s ...\n", filename); +@@ -280,18 +280,22 @@ + /* + * And finally, print out a summary of the total problems. + */ +- if (total_errors != 0) { +- if (verbose) { +- if (warnings) { +- printf("Warnings: %d\n", total_warnings); +- } ++ if (verbose) { ++ if (total_errors != 0 ) { + printf("Total problems identified: %d\n", total_errors); ++ } + ++ if (warnings) { ++ if (total_warnings != 0 ) { ++ printf("Warnings: %d\n",total_warnings); ++ } + } +- exit(1); + } +- +- exit(0); ++ ++ if (total_errors!=0) ++ exit(1); ++ else ++ exit(0); + } + + /* +@@ -300,8 +304,9 @@ + */ + void check_function(parser_state_t *state) + { +- assert(state != NULL); ++ int erroneous=0; + ++ assert(state != NULL); + /* + * This was a reference to a function WITHOUT an opening brace, + * so it's not a function call. Ignore it. +@@ -310,7 +315,6 @@ + return; + } + +- if (verbose == 0) { + /* + * The problem function has the SAME number of arguments as the + * placement of the format argument. i.e. The LAST argument of the +@@ -329,9 +333,11 @@ + state->line, + state->problem->function, + state->problem->fmt_arg); +- total_errors++; ++ erroneous=1; ++ ++ } + +- } else if (warnings && ++ if (warnings && + (state->constant_string != state->problem->fmt_arg)) { + printf("%s:%d Warning: %s uses non-constant string for format argument %d.\n", + filename, +@@ -341,25 +347,28 @@ + total_warnings++; + } + +- } else { ++ if (verbose) { + /* +- * verbose = 1, print out more stuff. ++ * verbose =TRUE, print out more stuff. + */ + printf("%s:%d FUNC %s ", filename, state->line, + state->problem->function); + if (state->problem->fmt_arg == state->args) { + printf("Last argument is "); +- if (state->constant_string) { ++ if (state->constant_string==state->args) { + printf("constant string: OK\n"); + } else { + printf("variable or reference: BAD\n"); +- total_errors++; ++ erroneous=1; + } + } else { + printf("format string with %d parameters: OK\n", + state->args - state->problem->fmt_arg); + } + } ++ ++ if (erroneous) total_errors++; ++ + } + + /* +@@ -401,7 +410,7 @@ + } + + state->problem = problem; +- state->line = yylineno; ++ state->line = cur_lineno; + state->braces = 0; + state->args = -1; + state->constant_string = -1; +@@ -425,7 +434,7 @@ + } + + state->problem = problem; +- state->line = yylineno; ++ state->line = cur_lineno; + state->braces = 0; + state->args = -1; + state->constant_string = -1; +--- pscan-1.2.orig/pscan.h ++++ pscan-1.2/pscan.h +@@ -31,6 +31,8 @@ + #define PROBLEMATIC TRUE + #define NOT_PROBLEMATIC FALSE + ++#define YY_NO_UNPUT ++ + /* + * The maximum number of user-defined problem functions which may be + * read from a .pscan problem definition file. +--- pscan-1.2.orig/test.c ++++ pscan-1.2/test.c +@@ -149,3 +149,9 @@ + * NetBSD allows err(1,NULL). We should, too. + */ + err(1, NULL); ++ ++/* ++ * A reserved function sizeof() as argument should not affect result when testing snprintf ++ * expected that this is an error ++ */ ++snprintf(b,sizeof(b),argv[1]); only in patch2: unchanged: --- pscan-1.2.orig/debian/patches/40_max_stack.patch +++ pscan-1.2/debian/patches/40_max_stack.patch @@ -0,0 +1,11 @@ +--- pscan.c.orig 2008-07-26 00:59:02.000000000 +0200 ++++ pscan.c 2008-07-26 00:59:20.000000000 +0200 +@@ -46,7 +46,7 @@ + static int warnings = FALSE; + static char *filename; + +-#define FSM_MAX_STACK 8192 ++#define FSM_MAX_STACK 32768 + static parser_state_t fsm_stack[FSM_MAX_STACK]; + static int stack_index = 0; + parser_state_t *state = NULL; only in patch2: unchanged: --- pscan-1.2.orig/debian/patches/30_scanner.patch +++ pscan-1.2/debian/patches/30_scanner.patch @@ -0,0 +1,111 @@ +--- pscan-1.2.orig/scanner.l ++++ pscan-1.2/scanner.l +@@ -1,21 +1,31 @@ +-%option yylineno + + %{ + #include "pscan.h" + static void skip_strings(char literal); ++extern int cur_lineno; + %} + + %x comment + %x strings + +-reserved "default"|"struct"|"void"|"for"|"if"|"else"|"while"|"do"|"return"|"case"|"switch"|"break"|"auto"|"continue"|"goto"|"sizeof"|"static"|"typedef"|"union"|"volatile" ++reserved "default"|"struct"|"void"|"for"|"if"|"else"|"while"|"do"|"return"|"case"|"switch"|"break"|"auto"|"continue"|"goto"|"sizeof"|"static"|"typedef"|"union"|"volatile"|"asm" + + vartype "char"|"double"|"enum"|"extern"|"float"|"int"|"long"|"register"|"short"|"signed"|"unsigned"|"const" + +-cprep "include"|"define"|"if"|"else"|"endif"|"ifdef"|"ifndef" ++cprep "include"|"define"|"undef"|"if"|"else"|"elif"|"endif"|"ifdef"|"ifndef"|"error"|"line"|"pragma" ++ + + %% +-{reserved} state->last_token = NOT_PROBLEMATIC; ++{reserved} {// Ignore reserved words because issue arises ++ // if reserved sizeof used as argument to a defined ++ // problematic function such as snprintf ++ // but we also do not want to attempt to check these ++ // for defined issues in setup_checks function as we know ++ // they are undefined ++ // Default last_token state is NOT_PROBLEMATIC ++ ++ // state->last_token = NOT_PROBLEMATIC; ++ } + + {vartype} state->last_token = NOT_PROBLEMATIC; + +@@ -39,7 +49,8 @@ + + \' skip_strings('\''); + +-\/\/.*$ /* skip C++ style comments */ ++ ++\/\/[^\n]* /* skip C++ style comments */ + + [a-zA-Z_][_a-zA-Z0-9]* state = setup_checks(yytext, state); + +@@ -81,17 +92,15 @@ + } + } + +- +-"\n"|"\r" /* ignore LF's and CR's */ +- +- + "/*" BEGIN(comment); + + [^*\n]* /* eat anything that's not a '*' */ + "*"+[^*/\n]* /* eat up '*'s not followed by '/'s */ +-\n /* do nothing */ ++\n {cur_lineno++;} + "*"+"/" BEGIN(INITIAL); + ++"\n" { cur_lineno++;} ++ + %% + /********************************************************************** + * pscan: http://www.striker.ottawa.on.ca/~aland/pscan/ +@@ -118,24 +127,22 @@ + /* static */ + void skip_strings(char literal) + { +- int c; ++ int c,last_c=0,done=0; ++ ++ while (!done) ++ { ++ c=input(); ++ ++ if (c==EOF) ++ return; ++ ++ if ((last_c!='\\') && (c==literal)) // non escaped literal found ++ done=1; ++ else if ((last_c=='\\') && (c=='\\')) // avoid \\ issue ++ last_c=0; ++ else ++ last_c=c; ++ } + +- while ((c = input()) != literal) +- { +- switch (c) { +- +- case '\\': +- c = input(); +- if (c == '\\') continue; +- if (c == EOF) return; +- if (c != literal) +- unput(c); +- break; +- case EOF: +- return; +- +- default: +- break; +- } +- } ++ return; + }