Android SELinux の avc: 拒否ログはどこに出力され閉じられますか?
一部のシナリオでは、SELinux をオンにする必要はありません。つまり、SELinux は Permissive に設定されています。ただし、プログラム設計が SELinux sepolicy に準拠していない場合、 log は、頻繁に avc: Denyed.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
1. avc: 拒否されたログはどこに出力されますか?
Linux バージョン 4.14:
Linux カーネル コードには、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 の 3 つの関数が順番に呼び出され、関連情報が出力されます。
このうち、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);
}
}
2. 不要な場合に avc:denied ログを閉じるにはどうすればよいですか?
次のように変更します。
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 // 屏蔽代码
}
実際には、ログを出力する部分をコメントアウトするだけです。