Merge "NetlinkEvent: use isKernel64Bit in KernelUtils.h"
This commit is contained in:
commit
97055b7ee9
2 changed files with 6 additions and 54 deletions
|
@ -29,6 +29,10 @@ cc_library {
|
|||
"liblog",
|
||||
],
|
||||
|
||||
header_libs: [
|
||||
"bpf_headers",
|
||||
],
|
||||
|
||||
export_include_dirs: ["include"],
|
||||
|
||||
tidy: true,
|
||||
|
|
|
@ -37,10 +37,12 @@
|
|||
#include <sys/utsname.h>
|
||||
|
||||
#include <android-base/parseint.h>
|
||||
#include <bpf/KernelUtils.h>
|
||||
#include <log/log.h>
|
||||
#include <sysutils/NetlinkEvent.h>
|
||||
|
||||
using android::base::ParseInt;
|
||||
using android::bpf::isKernel64Bit;
|
||||
|
||||
/* From kernel's net/netfilter/xt_quota2.c */
|
||||
const int LOCAL_QLOG_NL_EVENT = 112;
|
||||
|
@ -138,60 +140,6 @@ static_assert(sizeof(ulog_packet_msg_t) == sizeof(ulog_packet_msg32_t) ||
|
|||
static_assert(sizeof(ulog_packet_msg32_t) == 168);
|
||||
static_assert(sizeof(ulog_packet_msg64_t) == 192);
|
||||
|
||||
// Figure out the bitness of userspace.
|
||||
// Trivial and known at compile time.
|
||||
static bool isUserspace64bit(void) {
|
||||
return sizeof(long) == 8;
|
||||
}
|
||||
|
||||
// Figure out the bitness of the kernel.
|
||||
static bool isKernel64Bit(void) {
|
||||
// a 64-bit userspace requires a 64-bit kernel
|
||||
if (isUserspace64bit()) return true;
|
||||
|
||||
static bool init = false;
|
||||
static bool cache = false;
|
||||
if (init) return cache;
|
||||
|
||||
// Retrieve current personality - on Linux this system call *cannot* fail.
|
||||
int p = personality(0xffffffff);
|
||||
// But if it does just assume kernel and userspace (which is 32-bit) match...
|
||||
if (p == -1) return false;
|
||||
|
||||
// This will effectively mask out the bottom 8 bits, and switch to 'native'
|
||||
// personality, and then return the previous personality of this thread
|
||||
// (likely PER_LINUX or PER_LINUX32) with any extra options unmodified.
|
||||
int q = personality((p & ~PER_MASK) | PER_LINUX);
|
||||
// Per man page this theoretically could error out with EINVAL,
|
||||
// but kernel code analysis suggests setting PER_LINUX cannot fail.
|
||||
// Either way, assume kernel and userspace (which is 32-bit) match...
|
||||
if (q != p) return false;
|
||||
|
||||
struct utsname u;
|
||||
(void)uname(&u); // only possible failure is EFAULT, but u is on stack.
|
||||
|
||||
// Switch back to previous personality.
|
||||
// Theoretically could fail with EINVAL on arm64 with no 32-bit support,
|
||||
// but then we wouldn't have fetched 'p' from the kernel in the first place.
|
||||
// Either way there's nothing meaningul we can do in case of error.
|
||||
// Since PER_LINUX32 vs PER_LINUX only affects uname.machine it doesn't
|
||||
// really hurt us either. We're really just switching back to be 'clean'.
|
||||
(void)personality(p);
|
||||
|
||||
// Possible values of utsname.machine observed on x86_64 desktop (arm via qemu):
|
||||
// x86_64 i686 aarch64 armv7l
|
||||
// additionally observed on arm device:
|
||||
// armv8l
|
||||
// presumably also might just be possible:
|
||||
// i386 i486 i586
|
||||
// and there might be other weird arm32 cases.
|
||||
// We note that the 64 is present in both 64-bit archs,
|
||||
// and in general is likely to be present in only 64-bit archs.
|
||||
cache = !!strstr(u.machine, "64");
|
||||
init = true;
|
||||
return cache;
|
||||
}
|
||||
|
||||
/******************************************************************************/
|
||||
|
||||
NetlinkEvent::NetlinkEvent() {
|
||||
|
|
Loading…
Reference in a new issue