某些场景下并不需要打开SELinux,也就是SELinux设为Permissive,但如果程序设计不符合SELinux sepolicy, 日志中会频繁打印 如下类似avc: denied的log
[ 24.018396] type=1400 audit(1622165470.867:666): avc: denied { read } for pid=2358 comm="testagent" name="ApkLife.data" dev="tmpfs" ino=28549 scontext=u:r:stbdetector:s0 tcontext=u:object_r:system_app_tmpfs:s0 tclass=file permissive=1 [ 24.024144] type=1400 audit(1622165470.867:667): avc: denied { open } for pid=2358 comm="testagent" path="/data/local/vixtel/temp/ApkLife.data" dev="tmpfs" ino=28549 scontext=u:r:stbdetector:s0 tcontext=u:object_r:system_app_tmpfs:s0 tclass=file permissive=1
一、avc: denied log是哪里打印出来的?
(Linux version 4.14)
在Linux kernel代码中,/security/lsm_audit.c 中有函数 common_lsm_audit,定义如下:
/** * common_lsm_audit - generic LSM auditing function * @a: auxiliary audit data * @pre_audit: lsm-specific pre-audit callback * @post_audit: lsm-specific post-audit callback * * setup the audit buffer for common security information * uses callback to print LSM specific information */ void common_lsm_audit(struct common_audit_data *a, void (*pre_audit)(struct audit_buffer *, void *), void (*post_audit)(struct audit_buffer *, void *)) { struct audit_buffer *ab; if (a == NULL) return; /* we use GFP_ATOMIC so we won't sleep */ ab = audit_log_start(current->audit_context, GFP_ATOMIC | __GFP_NOWARN, AUDIT_AVC); if (ab == NULL) return; if (pre_audit) pre_audit(ab, a); dump_common_audit_data(ab, a); if (post_audit) post_audit(ab, a); audit_log_end(ab); }
在这个函数中依次调用了 pre_audit , dump_common_audit_data ,post_audit 三个函数来打印相关信息
其中 pre_audit 和 post_audit 定义如下:
// common_lsm_audit 的调用 common_lsm_audit(a, avc_audit_pre_callback, avc_audit_post_callback); // 函数定义 static void avc_audit_pre_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, "avc: %s ", ad->selinux_audit_data->denied ? "denied" : "granted"); avc_dump_av(ab, ad->selinux_audit_data->tclass, ad->selinux_audit_data->audited); audit_log_format(ab, " for "); } /** * avc_audit_post_callback - SELinux specific information * will be called by generic audit code * @ab: the audit buffer * @a: audit_data */ static void avc_audit_post_callback(struct audit_buffer *ab, void *a) { struct common_audit_data *ad = a; audit_log_format(ab, " "); avc_dump_query(ab, ad->selinux_audit_data->state, ad->selinux_audit_data->ssid, ad->selinux_audit_data->tsid, ad->selinux_audit_data->tclass); if (ad->selinux_audit_data->denied) { audit_log_format(ab, " permissive=%u", ad->selinux_audit_data->result ? 0 : 1); } }
二、avc: denied log在不需要时如何关闭?
简单的关闭方法就是把打印log 的部分注释掉
如下:
void common_lsm_audit(struct common_audit_data *a, void (*pre_audit)(struct audit_buffer *, void *), void (*post_audit)(struct audit_buffer *, void *)) { struct audit_buffer *ab; if (a == NULL) return; #if 0 // 屏蔽代码 /* we use GFP_ATOMIC so we won't sleep */ ab = audit_log_start(current->audit_context, GFP_ATOMIC | __GFP_NOWARN, AUDIT_AVC); if (ab == NULL) return; if (pre_audit) pre_audit(ab, a); dump_common_audit_data(ab, a); if (post_audit) post_audit(ab, a); audit_log_end(ab); #endif // 屏蔽代码 }