Skip to content

Commit

Permalink
reiserfs: prepare_error_buf wrongly consumes va_arg
Browse files Browse the repository at this point in the history
vsprintf will consume varargs on its own. Skipping them manually
results in garbage in the error buffer, or Oopses in the case of
pointers.

This patch removes the advancement and fixes a number of bugs where
crashes were observed as side effects of a regular error report.

Signed-off-by: Jeff Mahoney <jeffm@suse.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
  • Loading branch information
Jeff Mahoney authored and Linus Torvalds committed Mar 30, 2009
1 parent 45b03d5 commit cacbe3d
Showing 1 changed file with 3 additions and 9 deletions.
12 changes: 3 additions & 9 deletions fs/reiserfs/prints.c
Original file line number Diff line number Diff line change
Expand Up @@ -157,19 +157,16 @@ static void sprintf_disk_child(char *buf, struct disk_child *dc)
dc_size(dc));
}

static char *is_there_reiserfs_struct(char *fmt, int *what, int *skip)
static char *is_there_reiserfs_struct(char *fmt, int *what)
{
char *k = fmt;

*skip = 0;

while ((k = strchr(k, '%')) != NULL) {
if (k[1] == 'k' || k[1] == 'K' || k[1] == 'h' || k[1] == 't' ||
k[1] == 'z' || k[1] == 'b' || k[1] == 'y' || k[1] == 'a') {
*what = k[1];
break;
}
(*skip)++;
k++;
}
return k;
Expand All @@ -193,18 +190,15 @@ static void prepare_error_buf(const char *fmt, va_list args)
char *fmt1 = fmt_buf;
char *k;
char *p = error_buf;
int i, j, what, skip;
int what;

strcpy(fmt1, fmt);

while ((k = is_there_reiserfs_struct(fmt1, &what, &skip)) != NULL) {
while ((k = is_there_reiserfs_struct(fmt1, &what)) != NULL) {
*k = 0;

p += vsprintf(p, fmt1, args);

for (i = 0; i < skip; i++)
j = va_arg(args, int);

switch (what) {
case 'k':
sprintf_le_key(p, va_arg(args, struct reiserfs_key *));
Expand Down

0 comments on commit cacbe3d

Please sign in to comment.