From ad3d42ec4fb8bae5af44e238473e4b2a3a3ad7ca Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Mon, 16 Jan 2012 15:38:16 +0100 Subject: [PATCH] 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 - 8.15-2 +- fix stack smashing, buffer overflow, and invalid output of pr (#772172) + * Sat Jan 07 2012 Ondrej Vasik - 8.15-1 - new upstream release 8.15