Chinaunix首页 | 论坛 | 博客
  • 博客访问: 107883
  • 博文数量: 41
  • 博客积分: 2520
  • 博客等级: 少校
  • 技术积分: 440
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-22 16:25
文章分类

全部博文(41)

文章存档

2010年(41)

我的朋友

分类: LINUX

2010-01-27 10:56:52

根据AUDIT_FILTER_TYPE链表进行审计消息的过滤(&audit_filter_list[AUDIT_FILTER_TYPE])

函数:

int audit_filter_type(int type)

调用过程:

audit_log_start() -> audit_filter_type()

 

函数分析:

int audit_filter_type(int type)

{

struct audit_entry *e;

int result = 0;

rcu_read_lock();

if (list_empty(&audit_filter_list[AUDIT_FILTER_TYPE]))

           goto unlock_and_return;

 

list_for_each_entry_rcu(e, &audit_filter_list[AUDIT_FILTER_TYPE],

                             list) {

           int i;

           for (i = 0; i < e->rule.field_count; i++) {             //从实际情况来说,应该不需要循环,因为当初exclde这个链的rule只能设置一个fieldmsgtype

                    struct audit_field *f = &e->rule.fields[i];

                    if (f->type == AUDIT_MSGTYPE) {

                             result = audit_comparator(type, f->op, f->val);

                             if (!result)

                                       break;

                    }

           }

           if (result)                 //只要任何一个rule匹配了msgtype,就认为匹配

                    goto unlock_and_return;

}

unlock_and_return:

rcu_read_unlock();

return result;              //匹配为1,不匹配为0

}

 

audit_log_start()

{

     if (unlikely(audit_filter_type(type)))

              return NULL;       //如果audit_filter_type返回1,那么不进行审计

}

根据AUDIT_FILTER_USER链表进行审计消息的过滤(&audit_filter_list[AUDIT_FILTER_USER])

函数:

int audit_filter_user(struct netlink_skb_parms *cb, int type)

调用过程:

audit_receive_msg() -> audit_filter_user()

 

调用audit_filter_user_rules,对指定rule的每个fieldaudit_field *f = &rule->fields[i];

                   switch (f->type) {

                   case AUDIT_PID:

                   case AUDIT_UID:

                   case AUDIT_GID:

                   case AUDIT_LOGINUID:

                   }

                   可以看出,AUDIT_FILTER_USER链表仅会对以上四种id进行过滤。

如果每个域值的判断都成立,那么标志state(rule->action)并返回1。任意一个域值的判断不成立的话,立即返回0

audit_filter_user

对此链表的某个rule,如果audit_filter_user_rules返回1,那么就要退出audit_filter_user。返回值为1,除非statenever

如果此链表没有任何一个rule应用audit_filter_user_rules会返回1,那么默认返回1

就是说,

case AUDIT_USER:

case AUDIT_FIRST_USER_MSG...AUDIT_LAST_USER_MSG:

case AUDIT_FIRST_USER_MSG2...AUDIT_LAST_USER_MSG2:

 

这些类型的消息默认是要记录的。

 

根据AUDIT_FILTER_TASK链表进行审计消息的过滤(&audit_filter_list[AUDIT_FILTER_TASK])

函数:

static enum audit_state audit_filter_task(struct task_struct *tsk)

 

调用audit_filter_rules,对指定rule的每个fieldaudit_field *f = &rule->fields[i];

audit_filter_rules判断的域很多,参考代码:

          switch (f->type) {

          case AUDIT_PID:

                   result = audit_comparator(tsk->pid, f->op, f->val);

                   break;

          case AUDIT_PERM:

                   result = audit_match_perm(ctx, f->val);

                   break;

          }

 

对于某条rule,如果每个域值的判断都成立,那么标志state(rule->action)并返回1。任意一个域值的判断不成立的话,立即返回0

 

对此链表的某个rule,如果audit_filter_rules返回1,即找到一条匹配的rule,那么就要退出audit_filter_task。返回值为statestate已经被赋值为AUDIT_DISABLED(never)AUDIT_RECORD_CONTEXT(always)

如果此链表没有任何一个rule应用audit_filter_rules会返回1,那么默认返回stateAUDIT_BUILD_CONTEXT

 

此函数的被调用过程:

fork_idle & do_fork -> copy_process -> audit_alloc -> audit_filter_task

下一步需要确定这两个fork函数所有会被用到的时机。

 

每一个进程产生的时候都会根据audit_filter_task决定[state == AUDIT_DISABLED]是否分配tsk->audit_context。如果不分配的话,那么系统调用是不能对这样的进程所产生的系统调用进行审计的。

 

audit_filter_syscall

对每个rule的判定,和audit_filter_task一样,都调用了audit_filter_rules

audit_filter_task

audit_filter_rules(tsk, &e->rule, NULL, NULL, &state)) {

audit_filter_syscall

audit_filter_rules(tsk, &e->rule, ctx, NULL, &state)) {

 

1.      audit_aux_data

struct audit_aux_data {

     struct audit_aux_data       *next;

     int                         type;

};

2.      派生结构

a)         

struct audit_aux_data_mq_open {

     struct audit_aux_data       d;

     int                         oflag;

     mode_t                      mode;

     struct mq_attr              attr;

};

 

b)         

struct audit_aux_data_mq_sendrecv {

     struct audit_aux_data       d;

     mqd_t                       mqdes;

     size_t                      msg_len;

     unsigned int                msg_prio;

     struct timespec             abs_timeout;

};

 

c)         

struct audit_aux_data_mq_notify {

     struct audit_aux_data       d;

     mqd_t                       mqdes;

     struct sigevent    notification;

};

 

d)         

struct audit_aux_data_mq_getsetattr {

     struct audit_aux_data       d;

     mqd_t                       mqdes;

     struct mq_attr              mqstat;

};

 

e)         

struct audit_aux_data_ipcctl {

     struct audit_aux_data       d;

     struct ipc_perm             p;

     unsigned long               qbytes;

     uid_t                       uid;

     gid_t                       gid;

     mode_t                      mode;

     u32                         osid;

};

 

f)         

struct audit_aux_data_execve {

     struct audit_aux_data       d;

     int argc;

     int envc;

     char mem[0];

};

 

g)         

struct audit_aux_data_socketcall {

     struct audit_aux_data       d;

     int                         nargs;

     unsigned long               args[0];

};

 

h)         

struct audit_aux_data_sockaddr {

     struct audit_aux_data       d;

     int                         len;

     char                        a[0];

};

 

i)         

struct audit_aux_data_pids {

     struct audit_aux_data       d;

     pid_t                       target_pid[AUDIT_AUX_PIDS];

     uid_t                       target_auid[AUDIT_AUX_PIDS];

     uid_t                       target_uid[AUDIT_AUX_PIDS];

     unsigned int                target_sessionid[AUDIT_AUX_PIDS];

     u32                         target_sid[AUDIT_AUX_PIDS];

     char                        target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];

     int                         pid_count;

};

 

阅读(1094) | 评论(0) | 转发(0) |
0

上一篇:Kernel Audit System (1)

下一篇:trivial bash skill

给主人留下些什么吧!~~