mirror of
https://github.com/chromium/crashpad.git
synced 2025-03-20 10:43:46 +00: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 <vector>
|
||||||
|
|
||||||
#include "base/logging.h"
|
#include "base/logging.h"
|
||||||
|
#include "base/numerics/safe_math.h"
|
||||||
#include "build/build_config.h"
|
#include "build/build_config.h"
|
||||||
#include "util/numeric/checked_vm_address_range.h"
|
#include "util/numeric/checked_vm_address_range.h"
|
||||||
|
|
||||||
@ -277,10 +278,24 @@ ElfImageReader::NoteReader::Result ElfImageReader::NoteReader::ReadNote(
|
|||||||
current_address_ += sizeof(note_info);
|
current_address_ += sizeof(note_info);
|
||||||
|
|
||||||
constexpr size_t align = sizeof(note_info.n_namesz);
|
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);
|
#define CHECKED_PAD(x, into) \
|
||||||
size_t padded_descsz = PAD(note_info.n_descsz);
|
base::CheckAnd(base::CheckAdd(x, align - 1), ~(align - 1)) \
|
||||||
size_t note_size = padded_namesz + padded_descsz;
|
.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
|
// Notes typically have 4-byte alignment. However, .note.android.ident may
|
||||||
// inadvertently use 2-byte alignment.
|
// 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
|
// 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
|
// aligned at less than 4-bytes, expect that the next note will be aligned at
|
||||||
// 4-bytes and add extra padding, if necessary.
|
// 4-bytes and add extra padding, if necessary.
|
||||||
VMAddress end_of_note =
|
|
||||||
std::min(PAD(current_address_ + note_size), segment_end_address_);
|
VMAddress end_of_note_candidate;
|
||||||
#undef PAD
|
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_) {
|
if (note_size > max_note_size_) {
|
||||||
current_address_ = end_of_note;
|
current_address_ = end_of_note;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user