diff options
| author | Naveed Khan <naveed@digiscrypt.com> | 2026-06-26 21:58:00 +0530 |
|---|---|---|
| committer | Mark Wielaard <mark@klomp.org> | 2026-06-30 11:48:14 +0200 |
| commit | af35561761f36e2ce27484ca6d376326a80ebd1d (patch) | |
| tree | 5caec82444c8a351fb2caac3d311803859dd53d9 | |
| parent | f153ef257a8e8901d8f8ed96fd1a2467806e8755 (diff) | |
| download | bzip2-master.tar.gz bzip2-master.tar.bz2 bzip2-master.zip | |
The per-block output file name is built in outFileName[BZ_MAX_FILENAME]
with sprintf(split, "rec%5d", wrBlock+1). split is an interior pointer
into outFileName, past any leading directory component of the input file
name, so the bytes written here come right after attacker-influenced
path data.
The write is currently safe only by way of two non-local invariants: the
input file name is rejected up front once strlen(argv[1]) reaches
BZ_MAX_FILENAME-20, and the number of blocks is limited by
BZ_MAX_HANDLED_BLOCKS so the formatted value stays at five digits. The
comment on BZ_MAX_HANDLED_BLOCKS explicitly invites raising it, which
would silently eat into that 20 byte margin.
Bound the write with snprintf() using the space left after the directory
prefix (BZ_MAX_FILENAME - ofs) so it can no longer overrun outFileName
regardless of those invariants. This also removes the deprecated
sprintf(), which recent compilers flag under -Wdeprecated-declarations.
For valid input the result is unchanged: the "rec%5d" prefix always fits,
so snprintf() writes exactly the same bytes.
https://sourceware.org/bugzilla/show_bug.cgi?id=29280
| -rw-r--r-- | bzip2recover.c | 2 |
1 files changed, 1 insertions, 1 deletions
diff --git a/bzip2recover.c b/bzip2recover.c index 8c79a90..e6c0a99 100644 --- a/bzip2recover.c +++ b/bzip2recover.c | |||
| @@ -490,7 +490,7 @@ Int32 main ( Int32 argc, Char** argv ) | |||
| 490 | } | 490 | } |
| 491 | /* Now split points to the start of the basename. */ | 491 | /* Now split points to the start of the basename. */ |
| 492 | ofs = split - outFileName; | 492 | ofs = split - outFileName; |
| 493 | sprintf (split, "rec%5d", wrBlock+1); | 493 | snprintf (split, BZ_MAX_FILENAME - ofs, "rec%5d", wrBlock+1); |
| 494 | for (p = split; *p != 0; p++) if (*p == ' ') *p = '0'; | 494 | for (p = split; *p != 0; p++) if (*p == ' ') *p = '0'; |
| 495 | strcat (outFileName, inFileName + ofs); | 495 | strcat (outFileName, inFileName + ofs); |
| 496 | 496 | ||
