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

This commit is contained in:
Kamil Dudka 2012-01-16 15:38:16 +01:00
parent 33b6b75afa
commit ad3d42ec4f
2 changed files with 61 additions and 38 deletions

View File

@ -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];
+ }

View File

@ -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@redhat.com> - 8.15-2
- fix stack smashing, buffer overflow, and invalid output of pr (#772172)
* Sat Jan 07 2012 Ondrej Vasik <ovasik@redhat.com> - 8.15-1
- new upstream release 8.15