Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6a024715 authored by Maciej Żenczykowski's avatar Maciej Żenczykowski Committed by Automerger Merge Worker
Browse files

Merge "NetlinkEvent: use isKernel64Bit in KernelUtils.h" am: 97055b7e am:...

Merge "NetlinkEvent: use isKernel64Bit in KernelUtils.h" am: 97055b7e am: 90bd7182 am: d9870fc6

Original change: https://android-review.googlesource.com/c/platform/system/core/+/2597156



Change-Id: Ide01cf00bd7d42a606ff3299d1977640bf80ff96
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 38cd1f8b d9870fc6
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -29,6 +29,10 @@ cc_library {
        "liblog",
    ],

    header_libs: [
        "bpf_headers",
    ],

    export_include_dirs: ["include"],

    tidy: true,
+2 −54
Original line number Diff line number Diff line
@@ -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() {