Listening to Netlink broadcasts in the kernel module

The SELinux module broadcasts over the network to any listening sockets. I'm wondering if it is possible to listen to Netlink transmission from another kernel module?

From Netinux network code:

netlink_broadcast(selnl, skb, 0, SELNLGRP_AVC, GFP_USER);

      

+3


source to share


1 answer


I found that you can listen to netlink data using regular sockets. And, yes, it is possible in core-space.

You basically need to create and bind to the socket:

struct sock *sock = NULL;
struct sockaddr_nl addr = { 0 };

/* Create a netlink socket for SELinux traffic */
int rc = sock_create_kern(AF_NETLINK, SOCK_RAW, NETLINK_SELINUX,
              &ctx.sock);

if (rc)
    return rc;

addr.nl_family  = AF_NETLINK;
addr.nl_pid     = 0;
addr.nl_groups  = SELNLGRP_AVC;

rc = kernel_bind(ctx.sock, (struct sockaddr *) &addr, sizeof(addr));
if (rc)
    return rc;

/* Setup socket callback */
sock = ctx.sock->sk;
sock->sk_data_ready = netlink_data_ready;
sock->sk_allocation = GFP_KERNEL;

      



To get data:

static void netlink_data_ready(struct sock *sk, int bytes)
{
    struct sk_buff *skb = NULL;
    struct nlmsghdr *nlh = NULL;
    int rc = 0;

    /* Receive the data packet (blocking) */
    skb = skb_recv_datagram(sk, 0, 0, &rc);
    if (rc) {
        printk(KERN_ERROR "Failed on skb_recv_datagram(). rc=%d.", -rc);
        return;
    }

    nlh = (struct nlmsghdr *) skb->data;
    if (!nlh || !NLMSG_OK(nlh, bytes)) {
        printk(KERN_ERROR "Invalid netlink header data.");
        return;
    }

    if (nlh->nlmsg_type == SELNL_MSG_POLICYLOAD ||
        nlh->nlmsg_type == SELNL_MSG_SETENFORCE) {

        /* Insert code here */
    }
}

      

+2


source







All Articles