内核审计系统初步分析(1)

2009年4月27日 | 由 helight | 1000字 | 阅读大约需要2分钟 | 归档于 kernel | 标签 #kernel

最近一段时间在看内核关于审计的东西,今天作一点最近看的整理,内核的审计系统也算是比较新的东西了,还有内核跟踪一类的动西,也是在2。6。30中才看到有独立的目录了。

其实内核的审计还是没有跳出对进程的管理,也主要是是对每个进程的活动情况进行记录。在struct thread_info结构中的flags项中有增加了许多的内容,其中就有几个标志就是关于是否启用内核审计的。如下面的几项:

#define TIF_SYSCALL_TRACE       0       /* syscall trace active */
#define TIF_NOTIFY_RESUME       1       /* callback before returning to user */
#define TIF_SIGPENDING          2       /* signal pending */
#define TIF_NEED_RESCHED        3       /* rescheduling necessary */
#define TIF_SINGLESTEP          4       /* reenable singlestep on user return*/
#define TIF_IRET                5       /* force IRET */
#define TIF_SYSCALL_EMU         6       /* syscall emulation active */
#define TIF_SYSCALL_AUDIT       7       /* syscall auditing active */

thread_info结构的定义:

struct thread_info {
        struct task_struct      *task;          /* main task structure */
        struct exec_domain      *exec_domain;   /* execution domain */
        __u32                   flags;          /* low level flags */
        __u32                   status;         /* thread synchronous flags */
        __u32                   cpu;            /* current CPU */
        int                     preempt_count;  /* 0 => preemptable,
                                                   <0 => BUG */
        mm_segment_t            addr_limit;
        struct restart_block    restart_block;
        void __user             *sysenter_return;
#ifdef CONFIG_X86_32
        unsigned long           previous_esp;   /* ESP of the previous stack in
                                                   case of nested (IRQ) stacks
                                                */
        __u8                    supervisor_stack[0];
#endif
        int                     uaccess_err;
};

也发现很多时候的系统跟踪还是没有跳离对系统调用的跟踪。从上面的标志就可以看出来阿!

其实现在在linux内核中在内核堆栈下面就是thread_info这个数据结构,而task_struct又是这个结构的第一项。所以我们在看内核源码的时候发现,内核很多时候是直接找thread_info这个数据结构,而不是task_struct这个结构。在内核/arch/x86/kernel/entry_32.S中的系统调用表查寻的时候也是使用的是thread_info这个数据结构。

而且在现自的linux的task_struct这个数据结构中也多了这么一项,它是专门用来做内核审计数据存放的一个数据结构。

struct task_struct {

	struct audit_context *audit_context; 

}

这个数据结构一般情况下是一个NULL指针,只有在thread_info的flags中的内核审计标志设置之后系统才会申请空间来存放审计数据,所以从这个意义上说也算比较轻量级或是引用了写时复制技术中的思想了。

这个数据结构相对来说也是一个比较庞大的数据结构。下面给出这数据结构,我会在以后的分析这中逐步指出其中的含义和意义。

/* The per-task audit context. */
struct audit_context {
        int                 dummy;      /* must be the first element */
        int                 in_syscall; /* 1 if task is in a syscall 该值是:1 则表示任务在系统调用中 */
        enum audit_state    state, current_state;
        unsigned int        serial;     /* serial number for record */
        struct timespec     ctime;      /* time of syscall entry */
        int                 major;      /* syscall number */
        unsigned long       argv[4];    /* syscall arguments */
        int                 return_valid; /* return code is valid */
        long                return_code;/* syscall return code */
        u64                 prio;
        int                 name_count;
        struct audit_names  names[AUDIT_NAMES];
        char *              filterkey;  /* key for rule that triggered record */
        struct path         pwd;
        struct audit_context *previous; /* For nested syscalls */
        struct audit_aux_data *aux;
        struct audit_aux_data *aux_pids;
        struct sockaddr_storage *sockaddr;
        size_t sockaddr_len;
                                /* Save things to print about task_struct */
        pid_t               pid, ppid;
        uid_t               uid, euid, suid, fsuid;
        gid_t               gid, egid, sgid, fsgid;
        unsigned long       personality;
        int                 arch;

}