Commit 42e85210 authored by Egor Pasko's avatar Egor Pasko Committed by Commit Bot

Reland: PR_SET_DUMPABLE 1 briefly if opening pagemap fails

This is often necessary on Android to read /proc/self/pagemap. Without
prctl(PR_SET_DUMPABLE) opening this file fails in 94% of cases on
Canary. This potentially leads to bias in reporting
MappedAndResidentMemoryFootprint2.

What happened since it last landed as http://crrev.com/809373
* Facepalm and negate the condition in PCHECK, prctl returns zero on
  success
* Actually tested the change on a local non-rooted Pixel 2 device with a
  release official build with android_channel = canary

Bug: 1070618
Change-Id: I99b1a4c8bf820fb22e50b49e72522f8ece1e251d
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2429763
Commit-Queue: ssid <ssid@chromium.org>
Reviewed-by: default avatarssid <ssid@chromium.org>
Cr-Commit-Position: refs/heads/master@{#810780}
parent e1d4a808
......@@ -5,6 +5,8 @@
#include <dlfcn.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/prctl.h>
#include <memory>
#include "base/android/library_loader/anchor_functions.h"
......@@ -228,6 +230,44 @@ uint32_t ReadLinuxProcSmapsFile(FILE* smaps_file,
return num_valid_regions;
}
// RAII class making the current process dumpable via prctl(PR_SET_DUMPABLE, 1),
// in case it is not currently dumpable as described in proc(5) and prctl(2).
// Noop if the original dumpable state could not be determined.
class ScopedProcessSetDumpable {
public:
ScopedProcessSetDumpable() {
int result = prctl(PR_GET_DUMPABLE, 0, 0, 0, 0);
if (result < 0) {
PLOG(ERROR) << "prctl";
AvoidPrctlOnDestruction();
return;
}
was_dumpable_ = result > 0;
if (!was_dumpable_) {
if (prctl(PR_SET_DUMPABLE, 1, 0, 0, 0) != 0) {
PLOG(ERROR) << "prctl";
// PR_SET_DUMPABLE is often disallowed, avoid crashing in this case.
AvoidPrctlOnDestruction();
}
}
}
ScopedProcessSetDumpable(const ScopedProcessSetDumpable&) = delete;
ScopedProcessSetDumpable& operator=(const ScopedProcessSetDumpable&) = delete;
~ScopedProcessSetDumpable() {
if (!was_dumpable_) {
PCHECK(prctl(PR_SET_DUMPABLE, 0, 0, 0, 0) == 0) << "prctl";
}
}
private:
void AvoidPrctlOnDestruction() { was_dumpable_ = true; }
bool was_dumpable_;
};
} // namespace
FILE* g_proc_smaps_for_testing = nullptr;
......@@ -328,8 +368,14 @@ OSMetrics::MappedAndResidentPagesDumpState OSMetrics::GetMappedAndResidentPages(
base::ScopedFILE pagemap_file(fopen(kPagemap, "r"));
if (!pagemap_file.get()) {
DLOG(WARNING) << "Could not open " << kPagemap;
return OSMetrics::MappedAndResidentPagesDumpState::kAccessPagemapDenied;
{
ScopedProcessSetDumpable set_dumpable;
pagemap_file.reset(fopen(kPagemap, "r"));
}
if (!pagemap_file.get()) {
DLOG(WARNING) << "Could not open " << kPagemap;
return OSMetrics::MappedAndResidentPagesDumpState::kAccessPagemapDenied;
}
}
const size_t kPageSize = base::GetPageSize();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment