[coreutils] fix stack smashing, buffer overflow and invalid output of pr (#772172)

Kamil Dudka kdudka at fedoraproject.org
Mon Jan 16 14:51:05 UTC 2012


commit ad3d42ec4fb8bae5af44e238473e4b2a3a3ad7ca
Author: Kamil Dudka <kdudka at redhat.com>
Date:   Mon Jan 16 15:38:16 2012 +0100

    fix stack smashing, buffer overflow and invalid output of pr (#772172)

 coreutils-i18n.patch |   94 ++++++++++++++++++++++++++++++-------------------
 coreutils.spec       |    5 ++-
 2 files changed, 61 insertions(+), 38 deletions(-)
---
diff --git a/coreutils-i18n.patch b/coreutils-i18n.patch
index e2f9f21..ec79964 100644
--- a/coreutils-i18n.patch
+++ b/coreutils-i18n.patch
@@ -1786,7 +1786,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
                         int *number);
  static void print_files (int number_of_files, char **av);
  static void init_parameters (int number_of_files);
-@@ -439,7 +491,6 @@ static void store_char (char c);
+@@ -438,7 +490,6 @@ static void store_char (char c);
  static void pad_down (int lines);
  static void read_rest_of_line (COLUMN *p);
  static void skip_read (COLUMN *p, int column_number);
@@ -1794,7 +1794,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  static void cleanup (void);
  static void print_sep_string (void);
  static void separator_string (const char *optarg_S);
-@@ -451,7 +502,7 @@ static COLUMN *column_vector;
+@@ -450,7 +501,7 @@ static COLUMN *column_vector;
     we store the leftmost columns contiguously in buff.
     To print a line from buff, get the index of the first character
     from line_vector[i], and print up to line_vector[i + 1]. */
@@ -1803,7 +1803,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
  /* Index of the position in buff where the next character
     will be stored. */
-@@ -555,7 +606,7 @@ static int chars_per_column;
+@@ -554,7 +605,7 @@ static int chars_per_column;
  static bool untabify_input = false;
  
  /* (-e) The input tab character. */
@@ -1812,7 +1812,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
  /* (-e) Tabstops are at chars_per_tab, 2*chars_per_tab, 3*chars_per_tab, ...
     where the leftmost column is 1. */
-@@ -565,7 +616,10 @@ static int chars_per_input_tab = 8;
+@@ -564,7 +615,10 @@ static int chars_per_input_tab = 8;
  static bool tabify_output = false;
  
  /* (-i) The output tab character. */
@@ -1824,7 +1824,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
  /* (-i) The width of the output tab. */
  static int chars_per_output_tab = 8;
-@@ -639,7 +693,13 @@ static int power_10;
+@@ -638,7 +692,13 @@ static int power_10;
  static bool numbered_lines = false;
  
  /* (-n) Character which follows each line number. */
@@ -1839,7 +1839,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
  /* (-n) line counting starts with 1st line of input file (not with 1st
     line of 1st page printed). */
-@@ -692,6 +752,7 @@ static bool use_col_separator = false;
+@@ -691,6 +751,7 @@ static bool use_col_separator = false;
     -a|COLUMN|-m is a `space' and with the -J option a `tab'. */
  static char *col_sep_string = (char *) "";
  static int col_sep_length = 0;
@@ -1847,7 +1847,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  static char *column_separator = (char *) " ";
  static char *line_separator = (char *) "\t";
  
-@@ -848,6 +909,13 @@ separator_string (const char *optarg_S)
+@@ -847,6 +908,13 @@ separator_string (const char *optarg_S)
    col_sep_length = (int) strlen (optarg_S);
    col_sep_string = xmalloc (col_sep_length + 1);
    strcpy (col_sep_string, optarg_S);
@@ -1861,7 +1861,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  }
  
  int
-@@ -872,6 +940,21 @@ main (int argc, char **argv)
+@@ -871,6 +939,21 @@ main (int argc, char **argv)
  
    atexit (close_stdout);
  
@@ -1883,7 +1883,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
    n_files = 0;
    file_names = (argc > 1
                  ? xmalloc ((argc - 1) * sizeof (char *))
-@@ -948,8 +1031,12 @@ main (int argc, char **argv)
+@@ -947,8 +1030,12 @@ main (int argc, char **argv)
            break;
          case 'e':
            if (optarg)
@@ -1898,7 +1898,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            /* Could check tab width > 0. */
            untabify_input = true;
            break;
-@@ -962,8 +1049,12 @@ main (int argc, char **argv)
+@@ -961,8 +1048,12 @@ main (int argc, char **argv)
            break;
          case 'i':
            if (optarg)
@@ -1913,7 +1913,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            /* Could check tab width > 0. */
            tabify_output = true;
            break;
-@@ -990,8 +1081,8 @@ main (int argc, char **argv)
+@@ -989,8 +1080,8 @@ main (int argc, char **argv)
          case 'n':
            numbered_lines = true;
            if (optarg)
@@ -1924,7 +1924,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            break;
          case 'N':
            skip_count = false;
-@@ -1030,7 +1121,7 @@ main (int argc, char **argv)
+@@ -1029,7 +1120,7 @@ main (int argc, char **argv)
            old_s = false;
            /* Reset an additional input of -s, -S dominates -s */
            col_sep_string = bad_cast ("");
@@ -1933,7 +1933,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            use_col_separator = true;
            if (optarg)
              separator_string (optarg);
-@@ -1187,10 +1278,45 @@ main (int argc, char **argv)
+@@ -1186,10 +1277,45 @@ main (int argc, char **argv)
     a number. */
  
  static void
@@ -1981,7 +1981,19 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
    if (*arg)
      {
        long int tmp_long;
-@@ -1249,7 +1375,7 @@ init_parameters (int number_of_files)
+@@ -1211,6 +1337,11 @@ static void
+ init_parameters (int number_of_files)
+ {
+   int chars_used_by_number = 0;
++  int mb_len = 1;
++#if HAVE_MBRTOWC
++  if (MB_CUR_MAX > 1)
++    mb_len = MB_LEN_MAX;
++#endif
+ 
+   lines_per_body = lines_per_page - lines_per_header - lines_per_footer;
+   if (lines_per_body <= 0)
+@@ -1248,7 +1379,7 @@ init_parameters (int number_of_files)
            else
              col_sep_string = column_separator;
  
@@ -1990,7 +2002,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            use_col_separator = true;
          }
        /* It's rather pointless to define a TAB separator with column
-@@ -1280,11 +1406,11 @@ init_parameters (int number_of_files)
+@@ -1279,11 +1410,11 @@ init_parameters (int number_of_files)
               TAB_WIDTH (chars_per_input_tab, chars_per_number);   */
  
        /* Estimate chars_per_text without any margin and keep it constant. */
@@ -2004,7 +2016,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
        /* The number is part of the column width unless we are
           printing files in parallel. */
-@@ -1299,7 +1425,7 @@ init_parameters (int number_of_files)
+@@ -1298,7 +1429,7 @@ init_parameters (int number_of_files)
      }
  
    chars_per_column = (chars_per_line - chars_used_by_number -
@@ -2013,7 +2025,16 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
    if (chars_per_column < 1)
      error (EXIT_FAILURE, 0, _("page width too narrow"));
-@@ -1424,7 +1550,7 @@ init_funcs (void)
+@@ -1315,7 +1446,7 @@ init_parameters (int number_of_files)
+      We've to use 8 as the lower limit, if we use chars_per_default_tab = 8
+      to expand a tab which is not an input_tab-char. */
+   free (clump_buff);
+-  clump_buff = xmalloc (MAX (8, chars_per_input_tab));
++  clump_buff = xmalloc (mb_len * MAX (8, chars_per_input_tab));
+ }
+ 
+ /* Open the necessary files,
+@@ -1423,7 +1554,7 @@ init_funcs (void)
  
    /* Enlarge p->start_position of first column to use the same form of
       padding_not_printed with all columns. */
@@ -2022,7 +2043,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
    /* This loop takes care of all but the rightmost column. */
  
-@@ -1458,7 +1584,7 @@ init_funcs (void)
+@@ -1457,7 +1588,7 @@ init_funcs (void)
          }
        else
          {
@@ -2031,7 +2052,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            h_next = h + chars_per_column;
          }
      }
-@@ -1749,9 +1875,9 @@ static void
+@@ -1748,9 +1879,9 @@ static void
  align_column (COLUMN *p)
  {
    padding_not_printed = p->start_position;
@@ -2043,7 +2064,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
        padding_not_printed = ANYWHERE;
      }
  
-@@ -2022,13 +2148,13 @@ store_char (char c)
+@@ -2021,13 +2152,13 @@ store_char (char c)
        /* May be too generous. */
        buff = X2REALLOC (buff, &buff_allocated);
      }
@@ -2059,7 +2080,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
    char *s;
    int left_cut;
  
-@@ -2051,22 +2177,24 @@ add_line_number (COLUMN *p)
+@@ -2050,22 +2181,24 @@ add_line_number (COLUMN *p)
        /* Tabification is assumed for multiple columns, also for n-separators,
           but `default n-separator = TAB' hasn't been given priority over
           equal column_width also specified by POSIX. */
@@ -2088,7 +2109,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
          output_position = POS_AFTER_TAB (chars_per_output_tab,
                            output_position);
      }
-@@ -2227,7 +2355,7 @@ print_white_space (void)
+@@ -2226,7 +2359,7 @@ print_white_space (void)
    while (goal - h_old > 1
           && (h_new = POS_AFTER_TAB (chars_per_output_tab, h_old)) <= goal)
      {
@@ -2097,7 +2118,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
        h_old = h_new;
      }
    while (++h_old <= goal)
-@@ -2247,6 +2375,7 @@ print_sep_string (void)
+@@ -2246,6 +2379,7 @@ print_sep_string (void)
  {
    char *s;
    int l = col_sep_length;
@@ -2105,7 +2126,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  
    s = col_sep_string;
  
-@@ -2260,6 +2389,7 @@ print_sep_string (void)
+@@ -2259,6 +2393,7 @@ print_sep_string (void)
      {
        for (; separators_not_printed > 0; --separators_not_printed)
          {
@@ -2113,7 +2134,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            while (l-- > 0)
              {
                /* 3 types of sep_strings: spaces only, spaces and chars,
-@@ -2273,12 +2403,15 @@ print_sep_string (void)
+@@ -2272,12 +2407,15 @@ print_sep_string (void)
                  }
                else
                  {
@@ -2130,7 +2151,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            /* sep_string ends with some spaces */
            if (spaces_not_printed > 0)
              print_white_space ();
-@@ -2306,7 +2439,7 @@ print_clump (COLUMN *p, int n, char *clu
+@@ -2305,7 +2443,7 @@ print_clump (COLUMN *p, int n, char *clump)
     required number of tabs and spaces. */
  
  static void
@@ -2139,7 +2160,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  {
    if (tabify_output)
      {
-@@ -2330,6 +2463,74 @@ print_char (char c)
+@@ -2329,6 +2467,74 @@ print_char (char c)
    putchar (c);
  }
  
@@ -2214,7 +2235,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  /* Skip to page PAGE before printing.
     PAGE may be larger than total number of pages. */
  
-@@ -2509,9 +2710,9 @@ read_line (COLUMN *p)
+@@ -2508,9 +2714,9 @@ read_line (COLUMN *p)
            align_empty_cols = false;
          }
  
@@ -2226,7 +2247,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
            padding_not_printed = ANYWHERE;
          }
  
-@@ -2612,9 +2813,9 @@ print_stored (COLUMN *p)
+@@ -2611,9 +2817,9 @@ print_stored (COLUMN *p)
          }
      }
  
@@ -2238,7 +2259,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
        padding_not_printed = ANYWHERE;
      }
  
-@@ -2627,8 +2828,8 @@ print_stored (COLUMN *p)
+@@ -2626,8 +2832,8 @@ print_stored (COLUMN *p)
    if (spaces_not_printed == 0)
      {
        output_position = p->start_position + end_vector[line];
@@ -2249,7 +2270,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
      }
  
    return true;
-@@ -2647,7 +2848,7 @@ print_stored (COLUMN *p)
+@@ -2646,7 +2852,7 @@ print_stored (COLUMN *p)
     number of characters is 1.) */
  
  static int
@@ -2258,7 +2279,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
  {
    unsigned char uc = c;
    char *s = clump_buff;
-@@ -2657,10 +2858,10 @@ char_to_clump (char c)
+@@ -2656,10 +2862,10 @@ char_to_clump (char c)
    int chars;
    int chars_per_c = 8;
  
@@ -2271,7 +2292,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
      {
        width = TAB_WIDTH (chars_per_c, input_position);
  
-@@ -2741,6 +2942,155 @@ char_to_clump (char c)
+@@ -2740,6 +2946,154 @@ char_to_clump (char c)
    return chars;
  }
  
@@ -2279,7 +2300,6 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
 +static int
 +char_to_clump_multi (char c)
 +{
-+  unsigned char uc = c;
 +  static size_t mbc_pos = 0;
 +  static char mbc[MB_LEN_MAX] = {'\0'};
 +  static mbstate_t state = {'\0'};
@@ -2317,7 +2337,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
 +              width = +4;
 +              chars = +4;
 +              *s++ = '\\';
-+              sprintf (esc_buff, "%03o", mbc[0]);
++              sprintf (esc_buff, "%03o", (unsigned char) mbc[0]);
 +              for (i = 0; i <= 2; ++i)
 +                *s++ = (int) esc_buff[i];
 +            }
@@ -2366,7 +2386,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
 +                      width += 4;
 +                      chars += 4;
 +                      *s++ = '\\';
-+                      sprintf (esc_buff, "%03o", uc);
++                      sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 +                      for (j = 0; j <= 2; ++j)
 +                        *s++ = (int) esc_buff[j];
 +                    }
@@ -2387,7 +2407,7 @@ diff -urNp coreutils-8.13-orig/src/pr.c coreutils-8.13/src/pr.c
 +                          width += 4;
 +                          chars += 4;
 +                          *s++ = '\\';
-+                          sprintf (esc_buff, "%03o", uc);
++                          sprintf (esc_buff, "%03o", (unsigned char) mbc[i]);
 +                          for (j = 0; j <= 2; ++j)
 +                            *s++ = (int) esc_buff[j];
 +                        }
diff --git a/coreutils.spec b/coreutils.spec
index e7dec7a..63528e7 100644
--- a/coreutils.spec
+++ b/coreutils.spec
@@ -1,7 +1,7 @@
 Summary: A set of basic GNU tools commonly used in shell scripts
 Name:    coreutils
 Version: 8.15
-Release: 1%{?dist}
+Release: 2%{?dist}
 License: GPLv3+
 Group:   System Environment/Base
 Url:     http://www.gnu.org/software/coreutils/
@@ -322,6 +322,9 @@ fi
 %{?!norunuser:/sbin/runuser}
 
 %changelog
+* Mon Jan 16 2012 Kamil Dudka <kdudka at redhat.com> - 8.15-2
+- fix stack smashing, buffer overflow, and invalid output of pr (#772172)
+
 * Sat Jan 07 2012 Ondrej Vasik <ovasik at redhat.com> - 8.15-1
 - new upstream release 8.15
 


More information about the scm-commits mailing list