2014-12-05 4 views
3

SELinux 모듈은 청취 소켓에 netlink 브로드 캐스트를 보냅니다. 다른 커널 모듈에서 netlink 브로드 캐스트를 수신 할 수 있는지 궁금합니다. SELinux를 넷 링크 코드에서커널 모듈에서 netlink 브로드 캐스트 청취

는 :

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

당신은 사용자 땅으로이 작업을 수행해야합니다 : 소켓 바인드를 엽니 다 그것을 그룹 SELNLGRP_AVC에 전달하고 nl 메시지를 수신하십시오. 원하는 경우 코드를 작성할 수 있습니다. – srd

+0

커널 공간에서이 작업을 수행하는 방법을 알아 냈습니다. 내 게시 된 답변을 참조하십시오. – MarkP

답변

2

난 당신이 일반 소켓의 사용을 통해 넷 링크 데이터를 수신 할 수 있음을 발견했다. 그리고 네, 그것은 커널 공간에서 가능합니다. 데이터를 수신하기 위해

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; 

:

당신은 기본적으로 생성하고 소켓에 바인드해야

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 */ 
    } 
}