* Copyright (c) 2023 Huawei Device Co., Ltd.
*/
#include <internal.h>
#include <linux/security.h>
#include <linux/seq_file.h>
#include <linux/mm_types.h>
#include <linux/mm.h>
#include <linux/mm_inline.h>
#include <linux/hck/lite_hck_hideaddr.h>
#include <linux/hck/lite_vendor_hooks.h>
#include <linux/init.h>
#include <linux/module.h>
#include "avc.h"
#include "objsec.h"
#include "hideaddr.h"
#include <linux/version.h>
static bool is_anon_exec(struct vm_area_struct *vma)
{
const char *name = NULL;
vm_flags_t flags = vma->vm_flags;
if (!(flags & VM_EXEC))
return false;
name = arch_vma_name(vma);
if (!name) {
struct anon_vma_name *anon_name;
anon_name = anon_vma_name(vma);
if (!anon_name)
return false;
}
return true;
}
static int hideaddr_avc_has_perm(u16 tclass, u32 requested, struct seq_file *m)
{
struct av_decision avd;
struct inode *inode_task = file_inode(m->file);
struct task_struct *task = get_proc_task(inode_task);
u32 secid;
security_cred_getsecid(task->cred, &secid);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(6, 6, 0))
return avc_has_perm_noaudit(&selinux_state, secid, secid, tclass, requested,
AVC_STRICT, &avd);
#else
return avc_has_perm_noaudit(secid, secid, tclass, requested,
AVC_STRICT, &avd);
#endif
}
static void hideaddr_header_prefix(unsigned long *start, unsigned long *end,
vm_flags_t *flags, struct seq_file *m, struct vm_area_struct *vma)
{
if (!is_anon_exec(vma))
return;
if (hideaddr_avc_has_perm(SECCLASS_HIDEADDR, HIDEADDR__HIDE_EXEC_ANON_MEM, m))
return;
if (!hideaddr_avc_has_perm(SECCLASS_HIDEADDR, HIDEADDR__HIDE_EXEC_ANON_MEM_DEBUG, m))
return;
*start = 0;
*end = 0;
*flags = 0;
}
void hideaddr_header_prefix_lhck_register(void)
{
REGISTER_HCK_LITE_HOOK(hideaddr_header_prefix_lhck, hideaddr_header_prefix);
}