Loading libsysutils/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ cc_library { "liblog", ], header_libs: [ "bpf_headers", ], export_include_dirs: ["include"], tidy: true, Loading libsysutils/src/NetlinkEvent.cpp +2 −54 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
libsysutils/Android.bp +4 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,10 @@ cc_library { "liblog", ], header_libs: [ "bpf_headers", ], export_include_dirs: ["include"], tidy: true, Loading
libsysutils/src/NetlinkEvent.cpp +2 −54 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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