mirror of
https://github.com/chromium/crashpad.git
synced 2024-12-28 15:50:26 +08:00
linux: Fix interpretation of device numbers in /proc/pid/maps
While the kernel formats device major and minor numbers as %02x:%02x, they are not restricted to 8 bits apiece. Crashpad was requiring that the hexadecimal representations be exactly two characters, rather than at least two characters. The proper way to reconstruct a dev_t from major and minor numbers in user space is to use makedev() from <sys/sysmacros.h>. MKDEV() from <linux/kdev_t.h> interfaces with an older (pre-Linux 2.6) format which actually did use 8-bit major and minor numbers. makedev() places the major number at bits 8-19, and splits the minor number into two groups at bits 0-7 and 20-31. This is the correct user space view of device numbers. (Note that this is distinct from the kernel’s view: the kernel uses MKDEV() from a distinct internal <linux/kdev_t.h> which places the minor number at bits 0-19 and the major number at bits 20-31.) Bionic for 32-bit platforms uses a 32-bit user space dev_t while a 64-bit version is used elsewhere, and a comment in Bionic’s <sys/types.h> calls this a “historical accident”. However, due to the kernel’s use of only 32 bits for device numbers, this accident does not have any ill effect. Bug: crashpad:30 Test: crashpad_util_test, crashpad_snapshot_test Change-Id: Ic343454393d7399f598f9eba169a9e5f5630e601 Reviewed-on: https://chromium-review.googlesource.com/733863 Reviewed-by: Joshua Peraza <jperaza@chromium.org>
This commit is contained in:
parent
2f4516f938
commit
aff8d906b6
@ -14,9 +14,9 @@
|
||||
|
||||
#include "util/linux/memory_map.h"
|
||||
|
||||
#include <linux/kdev_t.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/sysmacros.h>
|
||||
|
||||
#include "base/files/file_path.h"
|
||||
#include "base/logging.h"
|
||||
@ -147,16 +147,25 @@ ParseResult ParseMapsLine(DelimitedFileReader* maps_file_reader,
|
||||
return ParseResult::kError;
|
||||
}
|
||||
|
||||
int major, minor;
|
||||
if (maps_file_reader->GetDelim(' ', &field) !=
|
||||
uint32_t major;
|
||||
if (maps_file_reader->GetDelim(':', &field) !=
|
||||
DelimitedFileReader::Result::kSuccess ||
|
||||
(field.pop_back(), field.size() != 5) ||
|
||||
!HexStringToNumber(field.substr(0, 2), &major) ||
|
||||
!HexStringToNumber(field.substr(3, 2), &minor)) {
|
||||
(field.pop_back(), field.size()) < 2 ||
|
||||
!HexStringToNumber(field, &major)) {
|
||||
LOG(ERROR) << "format error";
|
||||
return ParseResult::kError;
|
||||
}
|
||||
mapping.device = MKDEV(major, minor);
|
||||
|
||||
uint32_t minor;
|
||||
if (maps_file_reader->GetDelim(' ', &field) !=
|
||||
DelimitedFileReader::Result::kSuccess ||
|
||||
(field.pop_back(), field.size()) < 2 ||
|
||||
!HexStringToNumber(field, &minor)) {
|
||||
LOG(ERROR) << "format error";
|
||||
return ParseResult::kError;
|
||||
}
|
||||
|
||||
mapping.device = makedev(major, minor);
|
||||
|
||||
if (maps_file_reader->GetDelim(' ', &field) !=
|
||||
DelimitedFileReader::Result::kSuccess ||
|
||||
|
Loading…
x
Reference in New Issue
Block a user