mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-26 23:01:05 +08:00
Fix incorrect range checks in elf image note reader
Overflows before and after padding could cause the max note size check to be evaded. Bug: chromium:967228, chromium: 967257, chromium:967223 Change-Id: I499a273e76e78529fc59ddcb74055be6d01fa2cb Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/1631635 Reviewed-by: Joshua Peraza <jperaza@chromium.org> Commit-Queue: Scott Graham <scottmg@chromium.org>
This commit is contained in:
parent
daf9f5669e
commit
ee1d5124a2
@ -22,6 +22,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "base/logging.h"
|
||||
#include "base/numerics/safe_math.h"
|
||||
#include "build/build_config.h"
|
||||
#include "util/numeric/checked_vm_address_range.h"
|
||||
|
||||
@ -277,10 +278,24 @@ ElfImageReader::NoteReader::Result ElfImageReader::NoteReader::ReadNote(
|
||||
current_address_ += sizeof(note_info);
|
||||
|
||||
constexpr size_t align = sizeof(note_info.n_namesz);
|
||||
#define PAD(x) (((x) + align - 1) & ~(align - 1))
|
||||
size_t padded_namesz = PAD(note_info.n_namesz);
|
||||
size_t padded_descsz = PAD(note_info.n_descsz);
|
||||
size_t note_size = padded_namesz + padded_descsz;
|
||||
|
||||
#define CHECKED_PAD(x, into) \
|
||||
base::CheckAnd(base::CheckAdd(x, align - 1), ~(align - 1)) \
|
||||
.AssignIfValid(&into)
|
||||
|
||||
size_t padded_namesz;
|
||||
if (!CHECKED_PAD(note_info.n_namesz, padded_namesz)) {
|
||||
return Result::kError;
|
||||
}
|
||||
size_t padded_descsz;
|
||||
if (!CHECKED_PAD(note_info.n_descsz, padded_descsz)) {
|
||||
return Result::kError;
|
||||
}
|
||||
|
||||
size_t note_size;
|
||||
if (!base::CheckAdd(padded_namesz, padded_descsz).AssignIfValid(¬e_size)) {
|
||||
return Result::kError;
|
||||
}
|
||||
|
||||
// Notes typically have 4-byte alignment. However, .note.android.ident may
|
||||
// inadvertently use 2-byte alignment.
|
||||
@ -289,9 +304,19 @@ ElfImageReader::NoteReader::Result ElfImageReader::NoteReader::ReadNote(
|
||||
// but there may be 4-byte aligned notes following it. If this note was
|
||||
// aligned at less than 4-bytes, expect that the next note will be aligned at
|
||||
// 4-bytes and add extra padding, if necessary.
|
||||
VMAddress end_of_note =
|
||||
std::min(PAD(current_address_ + note_size), segment_end_address_);
|
||||
#undef PAD
|
||||
|
||||
VMAddress end_of_note_candidate;
|
||||
if (!base::CheckAdd(current_address_, note_size)
|
||||
.AssignIfValid(&end_of_note_candidate)) {
|
||||
return Result::kError;
|
||||
}
|
||||
VMAddress end_of_note;
|
||||
if (!CHECKED_PAD(end_of_note_candidate, end_of_note)) {
|
||||
return Result::kError;
|
||||
}
|
||||
end_of_note = std::min(end_of_note, segment_end_address_);
|
||||
|
||||
#undef CHECKED_PAD
|
||||
|
||||
if (note_size > max_note_size_) {
|
||||
current_address_ = end_of_note;
|
||||
|
Loading…
x
Reference in New Issue
Block a user