Auditについて
Linux2.6にはauditが入っている。
SELinuxなどのセキュアOSでは、これを使ってログ取ってるが、あまり知られていない。
組込み種ITやってたら、auditを直す必要に迫られたので、解析してみよう。
組込みSELinuxのauditの問題
SELinuxのアクセス拒否ログは、
type=PATH <アクセスしたファイルのフルパス情報>
type=AVC <アクセス拒否情報、ファイル名は、フルパスじゃない>
のように2種類の項目が出る(他にも色々出るけど、主なもの)
が、なぜかSHアーキテクチャだと、
type=AVCは出るのだが、type=PATHに相当する部分が出ないことが発覚。
これだと、アクセス拒否されたファイルのフルパスが分からなくて困る。
さて、何で出ないのかと調べてみると、、
type=PATHのログは、システムコールのログ取得部分(kernel/auditsc.c)で出力される。
が、auditsc.cの処理を正しく動かすためには、arch以下に手を加える必要がある。
が、SHでは、この対応がまだだったので、動かなかった。
auditはアーキテクチャ依存だったのか。。
SHでもauditを使えるようにしてみる
以下自分用メモ
システムコールの入口、出口の部分で、
audit関連の関数を呼ぶようにすればいい。
さて、システムコールの入口出口は、
SHの場合、arch/sh/entry-common.S
のようだ。これはアセンブラ。ついにアセンブラをいじる羽目に。
例えば、
システムコール出口のコードは以下のようだ。
arch/sh/entry-common.S 224 syscall_exit_work: 225 ! r0: current_thread_info->flags 226 ! r8: current_thread_info 227 tst #_TIF_SYSCALL_TRACE, r0 228 bt/s work_pending 229 tst #_TIF_NEED_RESCHED, r0 230 #ifdef CONFIG_TRACE_IRQFLAGS 231 mov.l 5f, r0 232 jsr @r0 233 nop 234 #endif 235 sti 236 ! XXX setup arguments... 237 mov.l 4f, r0 ! do_syscall_trace 238 jsr @r0 ->do_syscall_trace関数呼び出し ... 407 4: .long do_syscall_trace
syscall_exit_workというところで始まり、
237 mov.l 4f, r0 ! do_syscall_trace
で、ptrace.cのdo_syscall_traceに処理が飛ぶ。
まず、このdo_syscall_trace(ptrace.c中)を、auditの処理をするように修正。
また、
auditに必要な情報として、do_syscall_traceに
システムコール番号と、
レジスタ情報を渡す必要がある
コードを眺めてみると、SHでは、
r3レジスタがシステムコール番号、
r15レジスタがスタックポインタ、r15周辺に各種レジスタが退避されてるようだ。
r3、r15の値を、do_syscall_traceに渡せばいいはず。。
また、do_syscall_trace内では、
r4が第一引数、r5が第二引き数として使われる。
なので、r4にr3をコピー、r5にr15をコピーすればいい。
236 ! XXX setup arguments... mov r3 r4 mov r15 r5 237 mov.l 4f, r0 ! do_syscall_trace 238 jsr @r0
で、ゴニョゴニョやってみたら、
システムコールのログが取れるようになった。
auditdを使わない場合は、audit=1をカーネル起動パラメータに渡さないと、システムコールのログが出ないのに注意。
が、これでもなお念願のPATHエントリが出ない。。。
auditdを動かすと出るようだが、auditdを入れるのは面倒なので、
auditdは抜きにしたい。原因調査中。
kernel/auditsc.c 1080 void audit_syscall_entry(int arch, int major, 1081 unsigned long a1, unsigned long a2, 1082 unsigned long a3, unsigned long a4) 1083 { .. 1139 context->dummy = !audit_n_rules; →context->dummyは、audit_n_rulesがゼロだと、1にセットされる で、PATH取得に使われる処理は、context->dummyが1だと、何もしない。
ということは、PATH取得のためには、audit_n_rulesを何でもいいので非ゼロにする必要がある。それか、context->dummyに1をゼロにセットすればいいのか??