crashpad/util/linux/auxiliary_vector_test.cc
Mark Mentovai 50ed179e9a Use BUILDFLAG for OS checking
Use BUILDFLAG(IS_*) instead of defined(OS_*).

This was generated mostly mechnically by performing the following steps:
 - sed -i '' -E -e 's/defined\(OS_/BUILDFLAG(IS_/g' \
                -e 's%([ !])OS_([A-Z]+)%\1BUILDFLAG(IS_\2)%g' \
       $(git grep -l 'OS_'
         '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm')
 - sed -i '' -e 's/#ifdef BUILDFLAG(/#if BUILDFLAG(/' \
       $(git grep -l '#ifdef BUILDFLAG('
         '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm')
 - gsed -i -z -E -e \
       's%(.*)#include "%\1#include "build/buildflag.h"\n#include "%' \
       $(git grep -l 'BUILDFLAG(IS_'
         '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm')
 - Spot checks to move #include "build/buildflag.h" to the correct parts
   of files.
 - sed -i '' -E -e \
       's%^(#include "build/buildflag.h")$%#include "build/build_config.h"\n\1%' \
       $(grep -L '^#include "build/build_config.h"$'
         $(git grep -l 'BUILDFLAG(IS_'
           '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm'))
 - Add “clang-format off” around tool usage messages.
 - git cl format
 - Update mini_chromium to 85ba51f98278 (intermediate step).
   TESTING ONLY).
 - for f in $(git grep -l '^#include "build/buildflag.h"$'
              '**/*.c' '**/*.cc' '**/*.h' '**/*.m' '**/*.mm'); do \
       grep -v '^#include "build/buildflag.h"$' "${f}" > /tmp/z; \
       cp /tmp/z "${f}"; done
 - git cl format
 - Update mini_chromium to 735143774c5f (intermediate step).
 - Update mini_chromium to f41420eb45fa (as checked in).
 - Update mini_chromium to 6e2f204b4ae1 (as checked in).

For ease of review and inspection, each of these steps is uploaded as a
new patch set in a review series.

This includes an update of mini_chromium to 6e2f204b4ae1:

f41420eb45fa Use BUILDFLAG for OS checking
6e2f204b4ae1 Include what you use: string_util.h uses build_config.h

Bug: chromium:1234043
Change-Id: Ieef86186f094c64e59b853729737e36982f8cf69
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3400258
Reviewed-by: Joshua Peraza <jperaza@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
2022-01-19 20:21:19 +00:00

222 lines
6.3 KiB
C++

// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/linux/auxiliary_vector.h"
#include <linux/auxvec.h>
#include <sys/utsname.h>
#include <unistd.h>
#include <limits>
#include "base/bit_cast.h"
#include "build/build_config.h"
#include "gtest/gtest.h"
#include "test/errors.h"
#include "test/linux/fake_ptrace_connection.h"
#include "test/main_arguments.h"
#include "test/multiprocess.h"
#include "util/linux/address_types.h"
#include "util/linux/memory_map.h"
#include "util/misc/from_pointer_cast.h"
#include "util/numeric/int128.h"
#include "util/process/process_memory_linux.h"
#if !BUILDFLAG(IS_ANDROID)
// TODO(jperaza): This symbol isn't defined when building in chromium for
// Android. There may be another symbol to use.
extern "C" {
#if defined(ARCH_CPU_MIPS_FAMILY)
#define START_SYMBOL __start
#else
#define START_SYMBOL _start
#endif
extern void START_SYMBOL();
} // extern "C"
#endif
namespace crashpad {
namespace test {
namespace {
void TestAgainstCloneOrSelf(pid_t pid) {
FakePtraceConnection connection;
ASSERT_TRUE(connection.Initialize(pid));
AuxiliaryVector aux;
ASSERT_TRUE(aux.Initialize(&connection));
MemoryMap mappings;
ASSERT_TRUE(mappings.Initialize(&connection));
LinuxVMAddress phdrs;
ASSERT_TRUE(aux.GetValue(AT_PHDR, &phdrs));
EXPECT_TRUE(mappings.FindMapping(phdrs));
int pagesize;
ASSERT_TRUE(aux.GetValue(AT_PAGESZ, &pagesize));
EXPECT_EQ(pagesize, getpagesize());
LinuxVMAddress interp_base;
ASSERT_TRUE(aux.GetValue(AT_BASE, &interp_base));
EXPECT_TRUE(mappings.FindMapping(interp_base));
#if !BUILDFLAG(IS_ANDROID)
LinuxVMAddress entry_addr;
ASSERT_TRUE(aux.GetValue(AT_ENTRY, &entry_addr));
EXPECT_EQ(entry_addr, FromPointerCast<LinuxVMAddress>(START_SYMBOL));
#endif
uid_t uid;
ASSERT_TRUE(aux.GetValue(AT_UID, &uid));
EXPECT_EQ(uid, getuid());
uid_t euid;
ASSERT_TRUE(aux.GetValue(AT_EUID, &euid));
EXPECT_EQ(euid, geteuid());
gid_t gid;
ASSERT_TRUE(aux.GetValue(AT_GID, &gid));
EXPECT_EQ(gid, getgid());
gid_t egid;
ASSERT_TRUE(aux.GetValue(AT_EGID, &egid));
EXPECT_EQ(egid, getegid());
ProcessMemoryLinux memory(&connection);
LinuxVMAddress platform_addr;
ASSERT_TRUE(aux.GetValue(AT_PLATFORM, &platform_addr));
std::string platform;
ASSERT_TRUE(memory.ReadCStringSizeLimited(platform_addr, 10, &platform));
#if defined(ARCH_CPU_X86)
EXPECT_STREQ(platform.c_str(), "i686");
#elif defined(ARCH_CPU_X86_64)
EXPECT_STREQ(platform.c_str(), "x86_64");
#elif defined(ARCH_CPU_ARMEL)
// Machine name and platform are set in Linux:/arch/arm/kernel/setup.c
// Machine typically looks like "armv7l".
// Platform typically looks like "v7l".
utsname sys_names;
ASSERT_EQ(uname(&sys_names), 0);
std::string machine_name(sys_names.machine);
EXPECT_NE(machine_name.find(platform), std::string::npos);
#elif defined(ARCH_CPU_ARM64)
EXPECT_STREQ(platform.c_str(), "aarch64");
#endif // ARCH_CPU_X86
#if defined(AT_SYSINFO_EHDR)
LinuxVMAddress vdso_addr;
if (aux.GetValue(AT_SYSINFO_EHDR, &vdso_addr)) {
EXPECT_TRUE(mappings.FindMapping(vdso_addr));
}
#endif // AT_SYSINFO_EHDR
#if defined(AT_EXECFN)
LinuxVMAddress filename_addr;
ASSERT_TRUE(aux.GetValue(AT_EXECFN, &filename_addr));
std::string filename;
ASSERT_TRUE(memory.ReadCStringSizeLimited(filename_addr, 4096, &filename));
EXPECT_TRUE(filename.find(GetMainArguments()[0]) != std::string::npos);
#endif // AT_EXECFN
int ignore;
EXPECT_FALSE(aux.GetValue(AT_NULL, &ignore));
char too_small;
EXPECT_FALSE(aux.GetValue(AT_PAGESZ, &too_small));
uint128_struct big_dest;
memset(&big_dest, 0xf, sizeof(big_dest));
ASSERT_TRUE(aux.GetValue(AT_PHDR, &big_dest));
EXPECT_EQ(big_dest.lo, phdrs);
}
TEST(AuxiliaryVector, ReadSelf) {
TestAgainstCloneOrSelf(getpid());
}
class ReadChildTest : public Multiprocess {
public:
ReadChildTest() : Multiprocess() {}
ReadChildTest(const ReadChildTest&) = delete;
ReadChildTest& operator=(const ReadChildTest&) = delete;
~ReadChildTest() {}
private:
void MultiprocessParent() override { TestAgainstCloneOrSelf(ChildPID()); }
void MultiprocessChild() override { CheckedReadFileAtEOF(ReadPipeHandle()); }
};
TEST(AuxiliaryVector, ReadChild) {
ReadChildTest test;
test.Run();
}
class AuxVecTester : public AuxiliaryVector {
public:
AuxVecTester() : AuxiliaryVector() {}
void Insert(uint64_t type, uint64_t value) { values_[type] = value; }
};
TEST(AuxiliaryVector, SignedBit) {
FakePtraceConnection connection;
ASSERT_TRUE(connection.Initialize(getpid()));
AuxVecTester aux;
ASSERT_TRUE(&connection);
constexpr uint64_t type = 0x0000000012345678;
constexpr int32_t neg1_32 = -1;
aux.Insert(type, bit_cast<uint32_t>(neg1_32));
int32_t outval32s;
ASSERT_TRUE(aux.GetValue(type, &outval32s));
EXPECT_EQ(outval32s, neg1_32);
constexpr int32_t int32_max = std::numeric_limits<int32_t>::max();
aux.Insert(type, bit_cast<uint32_t>(int32_max));
ASSERT_TRUE(aux.GetValue(type, &outval32s));
EXPECT_EQ(outval32s, int32_max);
constexpr uint32_t uint32_max = std::numeric_limits<uint32_t>::max();
aux.Insert(type, uint32_max);
uint32_t outval32u;
ASSERT_TRUE(aux.GetValue(type, &outval32u));
EXPECT_EQ(outval32u, uint32_max);
constexpr int64_t neg1_64 = -1;
aux.Insert(type, bit_cast<uint64_t>(neg1_64));
int64_t outval64s;
ASSERT_TRUE(aux.GetValue(type, &outval64s));
EXPECT_EQ(outval64s, neg1_64);
constexpr int64_t int64_max = std::numeric_limits<int64_t>::max();
aux.Insert(type, bit_cast<uint64_t>(int64_max));
ASSERT_TRUE(aux.GetValue(type, &outval64s));
EXPECT_EQ(outval64s, int64_max);
constexpr uint64_t uint64_max = std::numeric_limits<uint64_t>::max();
aux.Insert(type, uint64_max);
uint64_t outval64u;
ASSERT_TRUE(aux.GetValue(type, &outval64u));
EXPECT_EQ(outval64u, uint64_max);
}
} // namespace
} // namespace test
} // namespace crashpad