Merge "Extend to receive NFLOG packets."
This commit is contained in:
commit
9f72ef8944
8 changed files with 86 additions and 19 deletions
|
|
@ -54,3 +54,4 @@ $(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/bin/reboot)
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/root/default.prop)
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/recovery/root/default.prop)
|
||||||
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/lmkd_intermediates/import_includes)
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/EXECUTABLES/lmkd_intermediates/import_includes)
|
||||||
|
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/SHARED_LIBRARIES/libsysutils_intermediates/import_includes)
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ extern "C" {
|
||||||
int uevent_open_socket(int buf_sz, bool passcred);
|
int uevent_open_socket(int buf_sz, bool passcred);
|
||||||
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length);
|
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length);
|
||||||
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid);
|
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid);
|
||||||
|
ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,7 @@ public:
|
||||||
bool parseIfInfoMessage(const struct nlmsghdr *nh);
|
bool parseIfInfoMessage(const struct nlmsghdr *nh);
|
||||||
bool parseIfAddrMessage(const struct nlmsghdr *nh);
|
bool parseIfAddrMessage(const struct nlmsghdr *nh);
|
||||||
bool parseUlogPacketMessage(const struct nlmsghdr *nh);
|
bool parseUlogPacketMessage(const struct nlmsghdr *nh);
|
||||||
|
bool parseNfPacketMessage(struct nlmsghdr *nh);
|
||||||
bool parseRtMessage(const struct nlmsghdr *nh);
|
bool parseRtMessage(const struct nlmsghdr *nh);
|
||||||
bool parseNdUserOptMessage(const struct nlmsghdr *nh);
|
bool parseNdUserOptMessage(const struct nlmsghdr *nh);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@ class NetlinkListener : public SocketListener {
|
||||||
public:
|
public:
|
||||||
static const int NETLINK_FORMAT_ASCII = 0;
|
static const int NETLINK_FORMAT_ASCII = 0;
|
||||||
static const int NETLINK_FORMAT_BINARY = 1;
|
static const int NETLINK_FORMAT_BINARY = 1;
|
||||||
|
static const int NETLINK_FORMAT_BINARY_UNICAST = 2;
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
/* temporary version until we can get Motorola to update their
|
/* temporary version until we can get Motorola to update their
|
||||||
|
|
|
||||||
|
|
@ -31,12 +31,12 @@
|
||||||
*/
|
*/
|
||||||
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
|
ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
|
||||||
{
|
{
|
||||||
uid_t user = -1;
|
uid_t uid = -1;
|
||||||
return uevent_kernel_multicast_uid_recv(socket, buffer, length, &user);
|
return uevent_kernel_multicast_uid_recv(socket, buffer, length, &uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Like the above, but passes a uid_t in by reference. In the event that this
|
* Like the above, but passes a uid_t in by pointer. In the event that this
|
||||||
* fails due to a bad uid check, the uid_t will be set to the uid of the
|
* fails due to a bad uid check, the uid_t will be set to the uid of the
|
||||||
* socket's peer.
|
* socket's peer.
|
||||||
*
|
*
|
||||||
|
|
@ -44,8 +44,12 @@ ssize_t uevent_kernel_multicast_recv(int socket, void *buffer, size_t length)
|
||||||
* returns -1, sets errno to EIO, and sets "user" to the UID associated with the
|
* returns -1, sets errno to EIO, and sets "user" to the UID associated with the
|
||||||
* message. If the peer UID cannot be determined, "user" is set to -1."
|
* message. If the peer UID cannot be determined, "user" is set to -1."
|
||||||
*/
|
*/
|
||||||
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer,
|
ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer, size_t length, uid_t *uid)
|
||||||
size_t length, uid_t *user)
|
{
|
||||||
|
return uevent_kernel_recv(socket, buffer, length, true, uid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ssize_t uevent_kernel_recv(int socket, void *buffer, size_t length, bool require_group, uid_t *uid)
|
||||||
{
|
{
|
||||||
struct iovec iov = { buffer, length };
|
struct iovec iov = { buffer, length };
|
||||||
struct sockaddr_nl addr;
|
struct sockaddr_nl addr;
|
||||||
|
|
@ -60,7 +64,7 @@ ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer,
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
*user = -1;
|
*uid = -1;
|
||||||
ssize_t n = recvmsg(socket, &hdr, 0);
|
ssize_t n = recvmsg(socket, &hdr, 0);
|
||||||
if (n <= 0) {
|
if (n <= 0) {
|
||||||
return n;
|
return n;
|
||||||
|
|
@ -73,14 +77,18 @@ ssize_t uevent_kernel_multicast_uid_recv(int socket, void *buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg);
|
struct ucred *cred = (struct ucred *)CMSG_DATA(cmsg);
|
||||||
*user = cred->uid;
|
*uid = cred->uid;
|
||||||
if (cred->uid != 0) {
|
if (cred->uid != 0) {
|
||||||
/* ignoring netlink message from non-root user */
|
/* ignoring netlink message from non-root user */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (addr.nl_groups == 0 || addr.nl_pid != 0) {
|
if (addr.nl_pid != 0) {
|
||||||
/* ignoring non-kernel or unicast netlink message */
|
/* ignore non-kernel */
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (require_group && addr.nl_groups == 0) {
|
||||||
|
/* ignore unicast messages when requested */
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,11 +16,12 @@ LOCAL_SRC_FILES:= \
|
||||||
|
|
||||||
LOCAL_MODULE:= libsysutils
|
LOCAL_MODULE:= libsysutils
|
||||||
|
|
||||||
LOCAL_C_INCLUDES :=
|
|
||||||
|
|
||||||
LOCAL_CFLAGS := -Werror
|
LOCAL_CFLAGS := -Werror
|
||||||
|
|
||||||
LOCAL_SHARED_LIBRARIES := libcutils liblog
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
|
libcutils \
|
||||||
|
liblog \
|
||||||
|
libnl
|
||||||
|
|
||||||
include $(BUILD_SHARED_LIBRARY)
|
include $(BUILD_SHARED_LIBRARY)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -32,13 +32,21 @@
|
||||||
#include <linux/if_addr.h>
|
#include <linux/if_addr.h>
|
||||||
#include <linux/if_link.h>
|
#include <linux/if_link.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
|
#include <linux/netfilter/nfnetlink_log.h>
|
||||||
#include <linux/netfilter_ipv4/ipt_ULOG.h>
|
#include <linux/netfilter_ipv4/ipt_ULOG.h>
|
||||||
|
|
||||||
/* From kernel's net/netfilter/xt_quota2.c */
|
/* From kernel's net/netfilter/xt_quota2.c */
|
||||||
const int QLOG_NL_EVENT = 112;
|
const int LOCAL_QLOG_NL_EVENT = 112;
|
||||||
|
const int LOCAL_NFLOG_PACKET = NFNL_SUBSYS_ULOG << 8 | NFULNL_MSG_PACKET;
|
||||||
|
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
|
||||||
|
#include <netlink/attr.h>
|
||||||
|
#include <netlink/genl/genl.h>
|
||||||
|
#include <netlink/handlers.h>
|
||||||
|
#include <netlink/msg.h>
|
||||||
|
|
||||||
const int NetlinkEvent::NlActionUnknown = 0;
|
const int NetlinkEvent::NlActionUnknown = 0;
|
||||||
const int NetlinkEvent::NlActionAdd = 1;
|
const int NetlinkEvent::NlActionAdd = 1;
|
||||||
const int NetlinkEvent::NlActionRemove = 2;
|
const int NetlinkEvent::NlActionRemove = 2;
|
||||||
|
|
@ -95,7 +103,8 @@ static const char *rtMessageName(int type) {
|
||||||
NL_EVENT_RTM_NAME(RTM_NEWROUTE);
|
NL_EVENT_RTM_NAME(RTM_NEWROUTE);
|
||||||
NL_EVENT_RTM_NAME(RTM_DELROUTE);
|
NL_EVENT_RTM_NAME(RTM_DELROUTE);
|
||||||
NL_EVENT_RTM_NAME(RTM_NEWNDUSEROPT);
|
NL_EVENT_RTM_NAME(RTM_NEWNDUSEROPT);
|
||||||
NL_EVENT_RTM_NAME(QLOG_NL_EVENT);
|
NL_EVENT_RTM_NAME(LOCAL_QLOG_NL_EVENT);
|
||||||
|
NL_EVENT_RTM_NAME(LOCAL_NFLOG_PACKET);
|
||||||
default:
|
default:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -271,6 +280,41 @@ bool NetlinkEvent::parseUlogPacketMessage(const struct nlmsghdr *nh) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse a LOCAL_NFLOG_PACKET message.
|
||||||
|
*/
|
||||||
|
bool NetlinkEvent::parseNfPacketMessage(struct nlmsghdr *nh) {
|
||||||
|
int uid = -1;
|
||||||
|
int len = 0;
|
||||||
|
char* raw = NULL;
|
||||||
|
|
||||||
|
struct nlattr *uid_attr = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_UID);
|
||||||
|
if (uid_attr) {
|
||||||
|
uid = ntohl(nla_get_u32(uid_attr));
|
||||||
|
}
|
||||||
|
|
||||||
|
struct nlattr *payload = nlmsg_find_attr(nh, sizeof(struct genlmsghdr), NFULA_PAYLOAD);
|
||||||
|
if (payload) {
|
||||||
|
/* First 256 bytes is plenty */
|
||||||
|
len = nla_len(payload);
|
||||||
|
if (len > 256) len = 256;
|
||||||
|
raw = (char*) nla_data(payload);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* hex = (char*) calloc(1, 5 + (len * 2));
|
||||||
|
strcpy(hex, "HEX=");
|
||||||
|
for (int i = 0; i < len; i++) {
|
||||||
|
hex[4 + (i * 2)] = "0123456789abcdef"[(raw[i] >> 4) & 0xf];
|
||||||
|
hex[5 + (i * 2)] = "0123456789abcdef"[raw[i] & 0xf];
|
||||||
|
}
|
||||||
|
|
||||||
|
asprintf(&mParams[0], "UID=%d", uid);
|
||||||
|
mParams[1] = hex;
|
||||||
|
mSubsystem = strdup("strict");
|
||||||
|
mAction = NlActionChange;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parse a RTM_NEWROUTE or RTM_DELROUTE message.
|
* Parse a RTM_NEWROUTE or RTM_DELROUTE message.
|
||||||
*/
|
*/
|
||||||
|
|
@ -478,7 +522,7 @@ bool NetlinkEvent::parseNdUserOptMessage(const struct nlmsghdr *nh) {
|
||||||
* TODO: consider only ever looking at the first message.
|
* TODO: consider only ever looking at the first message.
|
||||||
*/
|
*/
|
||||||
bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
|
bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
|
||||||
const struct nlmsghdr *nh;
|
struct nlmsghdr *nh;
|
||||||
|
|
||||||
for (nh = (struct nlmsghdr *) buffer;
|
for (nh = (struct nlmsghdr *) buffer;
|
||||||
NLMSG_OK(nh, (unsigned) size) && (nh->nlmsg_type != NLMSG_DONE);
|
NLMSG_OK(nh, (unsigned) size) && (nh->nlmsg_type != NLMSG_DONE);
|
||||||
|
|
@ -493,7 +537,7 @@ bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
|
||||||
if (parseIfInfoMessage(nh))
|
if (parseIfInfoMessage(nh))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (nh->nlmsg_type == QLOG_NL_EVENT) {
|
} else if (nh->nlmsg_type == LOCAL_QLOG_NL_EVENT) {
|
||||||
if (parseUlogPacketMessage(nh))
|
if (parseUlogPacketMessage(nh))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|
@ -511,6 +555,10 @@ bool NetlinkEvent::parseBinaryNetlinkMessage(char *buffer, int size) {
|
||||||
if (parseNdUserOptMessage(nh))
|
if (parseNdUserOptMessage(nh))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
} else if (nh->nlmsg_type == LOCAL_NFLOG_PACKET) {
|
||||||
|
if (parseNfPacketMessage(nh))
|
||||||
|
return true;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -588,7 +636,8 @@ bool NetlinkEvent::parseAsciiNetlinkMessage(char *buffer, int size) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NetlinkEvent::decode(char *buffer, int size, int format) {
|
bool NetlinkEvent::decode(char *buffer, int size, int format) {
|
||||||
if (format == NetlinkListener::NETLINK_FORMAT_BINARY) {
|
if (format == NetlinkListener::NETLINK_FORMAT_BINARY
|
||||||
|
|| format == NetlinkListener::NETLINK_FORMAT_BINARY_UNICAST) {
|
||||||
return parseBinaryNetlinkMessage(buffer, size);
|
return parseBinaryNetlinkMessage(buffer, size);
|
||||||
} else {
|
} else {
|
||||||
return parseAsciiNetlinkMessage(buffer, size);
|
return parseAsciiNetlinkMessage(buffer, size);
|
||||||
|
|
|
||||||
|
|
@ -47,8 +47,13 @@ bool NetlinkListener::onDataAvailable(SocketClient *cli)
|
||||||
ssize_t count;
|
ssize_t count;
|
||||||
uid_t uid = -1;
|
uid_t uid = -1;
|
||||||
|
|
||||||
count = TEMP_FAILURE_RETRY(uevent_kernel_multicast_uid_recv(
|
bool require_group = true;
|
||||||
socket, mBuffer, sizeof(mBuffer), &uid));
|
if (mFormat == NETLINK_FORMAT_BINARY_UNICAST) {
|
||||||
|
require_group = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
count = TEMP_FAILURE_RETRY(uevent_kernel_recv(socket,
|
||||||
|
mBuffer, sizeof(mBuffer), require_group, &uid));
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
if (uid > 0)
|
if (uid > 0)
|
||||||
LOG_EVENT_INT(65537, uid);
|
LOG_EVENT_INT(65537, uid);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue