• audit


    一、socket系统调用创建socket/sock

    系统调用参数family为PF_NETLINK,protocol为NETLINK_AUDIT

    186  int audit_open() {
    187      return socket(PF_NETLINK, SOCK_RAW | SOCK_CLOEXEC, NETLINK_AUDIT);
    188  }

    1.创建struct socket

    2. 创建struct sock(struct netlink_sock)

    调用net_proto_family类型里的create函数指针创建netlink_sock,family为PF_NETLINK,所以net_families[family]即指向netlink_family_ops,所以是调用netlink_create()。netlink_sock里包含了struct sock,并且把它放置在第一个field,所以创建了netlink_sock也即创建了sock,因为netlink_proto里的slab成员没有设置,所以是调用的kmalloc(netlink_proto.obj_size)来分配的netlink_sock,netlink_proto.obj_size即为netlink_sock struct size;

    设置socket的proto_ops类型成员ops为netlink_ops,这个后面user space使用这个socket调用sendto、recvfrom等系统调用将会调用到这个函数集里的对应函数(netlink_sendmsg/netlink_recvmsg等);

    调用sock_init_data()绑定socket和sock,设置sock struct的一些成员,比如sk_rcvbuf、sk_sndbuf两个buffer的size、sk_data_ready成员设置为sock_def_readable(有数据发给这个socket,调用这个函数唤醒在这个socket上等待的线程);

    设置sock的sk_protocol成员为NETLINK_AUDIT

    3.为socket创建fd

    创建fd,这个fd将会返回给user space,之后user space调用socket相关的系统调用都将根据这个fd来操作,在kernel里根据这个fd再找到对应的socket

    二、sendto系统调用设置user space的audit线程

    user space构造好audit_message,这个struct第一个成员为nlmsghdr,data成员为数组,数组size为8970,这个数组是存放的message payload,此时message payload为audit_status,设置了这个struct的pid为logd.auditd线程的pid、mask成员为AUDIT_STATUS_PID。然后设置audit_message.nlh.nlmsg_len,这个len是nlmsghdr struct size+payload size(即audit_status struct size)。然后是调用了sendto系统调用;

     #define MAX_AUDIT_MESSAGE_LENGTH 8970
    44  struct audit_message {
    45      struct nlmsghdr nlh;
    46      char data[MAX_AUDIT_MESSAGE_LENGTH];
    47  };

    kernel __sys_sendto() 

    根据buf、len设置iovec、iov_iter;

    根据fd找到对应的socket;

    调用netlink_sendmsg()

    --如果netlink_sock还没有bind,即其bound成员为false,则调用netlink_autobind(),在此函数里会设置netlink_sock的portid,这个portid即是此user线程所在的进程的pid,此pid通过task_tgid_vnr(current)得到,之后有一个插入hash table的动作,然后将netlink_sock.bound设置为1;

    --调用netlink_alloc_large_skb()分配一个sk_buff,此时传入的size参数为netlink msg size(msg header+msg payload),然后设置sk_buff.cb的portid成员为netlink_sock.portid、将user space的netlink msg(header+payload) copy到sk_buff;

    --user space没有设置sockaddr_nl除nl_family外的其它所有成员(这些成员的值均被memset为0了),所以dst_group、dst_portid均为0,所以没有调用netlink_broadcast();

    --调用netlink_unicast(),此时的dst_portid为0,为0表示kernel里的sock,根据portid以及sk_protocol查找对应的sock,这里的sk_protocol为NETLINK_AUDIT,所以这里查询到的sock为kernel audit所创建的sock,因为是kernel  sock,所以调用netlink_unicast_kernel,它会调用netlink_rcv指针函数,此时它指向audit_receive();

  • 相关阅读:
    web 学习资源整理
    CodeSmith 学习资料收集
    常用 T_SQL 语句
    SQL Server 2000查询分析器自定义查询快捷键
    插入标识列 identity_insert
    c# 上传FTP文件
    (.Net 3.5Sp1)WebForm使用System.Web.Routing
    SPQuery.ViewAttributes
    ChatterBot之linux下安装mongodb 02
    linux端口开放指定端口的两种方法
  • 原文地址:https://www.cnblogs.com/aspirs/p/16030964.html
Copyright © 2020-2023  润新知