123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744 |
- #include <asm-generic/sections.h>
- #include <linux/mm.h>
- #include "../../mm/slab.h"
- #include <linux/slub_def.h>
- #include <linux/binfmts.h>
- #include <linux/kdp.h>
- #include <linux/mount.h>
- #include <linux/cred.h>
- #include <linux/security.h>
- #include <linux/init_task.h>
- #include "../../fs/mount.h"
- #define VERITY_PARAM_LENGTH 20
- #define KDP_CRED_SYS_ID 1000
- struct task_security_struct {
- u32 osid;
- u32 sid;
- u32 exec_sid;
- u32 create_sid;
- u32 keycreate_sid;
- u32 sockcreate_sid;
- void *bp_cred;
- };
- struct task_security_struct init_sec __kdp_ro;
- bool kdp_enable __kdp_ro = false;
- static int __check_verifiedboot __kdp_ro = 0;
- static int __is_kdp_recovery __kdp_ro = 0;
- static char verifiedbootstate[VERITY_PARAM_LENGTH];
- void __init kdp_init(void)
- {
- struct kdp_init cred;
- memset((void *)&cred, 0, sizeof(kdp_init));
- cred._srodata = (u64)__start_rodata;
- cred._erodata = (u64)__end_rodata;
- cred.init_mm_pgd = (u64)swapper_pg_dir;
- cred.credSize = sizeof(struct cred_kdp);
- cred.sp_size = sizeof(struct task_security_struct);
- cred.pgd_mm = offsetof(struct mm_struct, pgd);
- cred.uid_cred = offsetof(struct cred, uid);
- cred.euid_cred = offsetof(struct cred, euid);
- cred.gid_cred = offsetof(struct cred, gid);
- cred.egid_cred = offsetof(struct cred, egid);
- cred.bp_pgd_cred = offsetof(struct cred_kdp, bp_pgd);
- cred.bp_task_cred = offsetof(struct cred_kdp, bp_task);
- cred.type_cred = offsetof(struct cred_kdp, type);
- cred.security_cred = offsetof(struct cred, security);
- cred.usage_cred = offsetof(struct cred_kdp, use_cnt);
- cred.cred_task = offsetof(struct task_struct, cred);
- cred.mm_task = offsetof(struct task_struct, mm);
- cred.pid_task = offsetof(struct task_struct, pid);
- cred.rp_task = offsetof(struct task_struct, real_parent);
- cred.comm_task = offsetof(struct task_struct, comm);
- cred.bp_cred_secptr = offsetof(struct task_security_struct, bp_cred);
- cred.verifiedbootstate = (u64)verifiedbootstate;
- uh_call(UH_APP_KDP, KDP_INIT, (u64)&cred, 0, 0, 0);
- }
- static int __init verifiedboot_state_setup(char *str)
- {
- strlcpy(verifiedbootstate, str, sizeof(verifiedbootstate));
- if (!strncmp(verifiedbootstate, "orange", sizeof("orange")))
- __check_verifiedboot = 1;
- return 0;
- }
- __setup("androidboot.verifiedbootstate=", verifiedboot_state_setup);
- static int __init boot_recovery(char *str)
- {
- int temp = 0;
- if (get_option(&str, &temp)) {
- __is_kdp_recovery = temp;
- return 0;
- }
- return -EINVAL;
- }
- early_param("androidboot.boot_recovery", boot_recovery);
- #ifdef CONFIG_KDP_CRED
- struct cred_kdp_init {
- atomic_t use_cnt;
- struct ro_rcu_head ro_rcu_head_init;
- };
- struct cred_kdp_init init_cred_use_cnt = {
- .use_cnt = ATOMIC_INIT(4),
- .ro_rcu_head_init = {
- .non_rcu = 0,
- .bp_cred = NULL,
- },
- };
- struct cred_kdp init_cred_kdp __kdp_ro = {
- .use_cnt = (atomic_t *)&init_cred_use_cnt,
- .bp_task = &init_task,
- .bp_pgd = NULL,
- .type = 0,
- };
- static struct kmem_cache *cred_jar_ro;
- static struct kmem_cache *tsec_jar;
- static struct kmem_cache *usecnt_jar;
- static void cred_ctor(void *data) {}
- static void sec_ctor(void *data) {}
- static void usecnt_ctor(void *data) {}
- void __init kdp_cred_init(void)
- {
- slab_flags_t flags = SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT;
- if (!kdp_enable) {
- return;
- }
- cred_jar_ro = kmem_cache_create("cred_jar_ro",
- sizeof(struct cred_kdp),
- 0, flags, cred_ctor);
- if (!cred_jar_ro)
- panic("Unable to create RO Cred cache\n");
- tsec_jar = kmem_cache_create("tsec_jar",
- sizeof(struct task_security_struct),
- 0, flags, sec_ctor);
- if (!tsec_jar)
- panic("Unable to create RO security cache\n");
- usecnt_jar = kmem_cache_create("usecnt_jar",
- sizeof(struct cred_kdp_init),
- 0, flags, usecnt_ctor);
- if (!usecnt_jar)
- panic("Unable to create use count jar\n");
- uh_call(UH_APP_KDP, JARRO_TSEC_SIZE, (u64)cred_jar_ro->size,
- (u64)tsec_jar->size, 0, 0);
- }
- unsigned int kdp_get_usecount(struct cred *cred)
- {
- int ret = is_kdp_protect_addr((unsigned long)cred);
- if (ret == PROTECT_INIT)
- return (unsigned int)atomic_read(init_cred_kdp.use_cnt);
- else if (ret == PROTECT_KMEM)
- return (unsigned int)atomic_read(((struct cred_kdp *)cred)->use_cnt);
- else
- return atomic_read(&cred->usage);
- }
- void kdp_usecount_inc(struct cred *cred)
- {
- int ret = is_kdp_protect_addr((unsigned long)cred);
- if (ret == PROTECT_INIT)
- atomic_inc(init_cred_kdp.use_cnt);
- else if (ret == PROTECT_KMEM)
- atomic_inc(((struct cred_kdp *)cred)->use_cnt);
- else
- atomic_inc(&cred->usage);
- }
- unsigned int kdp_usecount_inc_not_zero(struct cred *cred)
- {
- int ret = is_kdp_protect_addr((unsigned long)cred);
- if (ret == PROTECT_INIT)
- return (unsigned int)atomic_inc_not_zero(init_cred_kdp.use_cnt);
- else if (ret == PROTECT_KMEM)
- return (unsigned int)atomic_inc_not_zero(((struct cred_kdp *)cred)->use_cnt);
- else
- return atomic_inc_not_zero(&cred->usage);
- }
- unsigned int kdp_usecount_dec_and_test(struct cred *cred)
- {
- int ret = is_kdp_protect_addr((unsigned long)cred);
- if (ret == PROTECT_INIT)
- return (unsigned int)atomic_dec_and_test(init_cred_kdp.use_cnt);
- else if (ret == PROTECT_KMEM)
- return (unsigned int)atomic_dec_and_test(((struct cred_kdp *)cred)->use_cnt);
- else
- return atomic_dec_and_test(&cred->usage);
- }
- void kdp_set_cred_non_rcu(struct cred *cred, int val)
- {
- if (is_kdp_protect_addr((unsigned long)cred))
- GET_ROCRED_RCU(cred)->non_rcu = val;
- else
- cred->non_rcu = val;
- }
- inline void set_kdp_cred_subscribers(struct cred *cred, int n)
- {
- #ifdef CONFIG_DEBUG_CREDENTIALS
- atomic_set(&cred->subscribers, n);
- #endif
- }
- int is_kdp_protect_addr(unsigned long addr)
- {
- struct kmem_cache *s;
- struct page *page;
- struct slab *p_slab;
- void *objp = (void *)addr;
- if (!objp)
- return 0;
- if (!kdp_enable)
- return 0;
- if ((addr == ((unsigned long)&init_cred)) ||
- (addr == ((unsigned long)&init_sec)))
- return PROTECT_INIT;
- page = virt_to_head_page(objp);
- p_slab = page_slab(page);
- s = p_slab->slab_cache;
- if (s && (s == cred_jar_ro || s == tsec_jar))
- return PROTECT_KMEM;
- return 0;
- }
- extern void security_cred_free_hook(struct cred *cred);
- void put_rocred_rcu(struct rcu_head *rcu)
- {
- struct cred *cred = container_of(rcu, struct ro_rcu_head, rcu)->bp_cred;
- if (atomic_read(((struct cred_kdp *)cred)->use_cnt) != 0)
- panic("RO_CRED: put_rocred_rcu() sees %p with usage %d\n",
- cred, atomic_read(((struct cred_kdp *)cred)->use_cnt));
- security_cred_free_hook(cred);
- kdp_free_security((unsigned long)cred->security);
- key_put(cred->session_keyring);
- key_put(cred->process_keyring);
- key_put(cred->thread_keyring);
- key_put(cred->request_key_auth);
- if (cred->group_info)
- put_group_info(cred->group_info);
- free_uid(cred->user);
- if (cred->ucounts)
- put_ucounts(cred->ucounts);
- put_user_ns(cred->user_ns);
- if (((struct cred_kdp *)cred)->use_cnt)
- kmem_cache_free(usecnt_jar, (void *)((struct cred_kdp *)cred)->use_cnt);
- kmem_cache_free(cred_jar_ro, cred);
- }
- void kdp_put_cred_rcu(struct cred *cred, void *put_cred_rcu)
- {
- if (is_kdp_protect_addr((unsigned long)cred)) {
- if (GET_ROCRED_RCU(cred)->non_rcu)
- put_rocred_rcu(&(GET_ROCRED_RCU(cred)->rcu));
- else
- call_rcu(&(GET_ROCRED_RCU(cred)->rcu), put_rocred_rcu);
- } else {
- void (*f)(struct rcu_head *) = put_cred_rcu;
- if (cred->non_rcu)
- f(&cred->rcu);
- else
- call_rcu(&cred->rcu, f);
- }
- }
- struct cred *prepare_ro_creds(struct cred *old, int kdp_cmd, u64 p)
- {
- u64 pgd = (u64)(current->mm ? current->mm->pgd : swapper_pg_dir);
- struct cred_kdp temp_old;
- struct cred_kdp *new_ro = NULL;
- struct cred_param param_data;
- void *use_cnt_ptr = NULL;
- void *rcu_ptr = NULL;
- void *tsec = NULL;
- new_ro = kmem_cache_alloc(cred_jar_ro, GFP_KERNEL | __GFP_NOFAIL);
- if (!new_ro)
- panic("[%d] : kmem_cache_alloc() failed", kdp_cmd);
- use_cnt_ptr = kmem_cache_alloc(usecnt_jar, GFP_KERNEL | __GFP_NOFAIL);
- if (!use_cnt_ptr)
- panic("[%d] : Unable to allocate usage pointer\n", kdp_cmd);
-
- rcu_ptr = (struct ro_rcu_head *)((atomic_t *)use_cnt_ptr + 1);
- ((struct ro_rcu_head *)rcu_ptr)->bp_cred = (void *)new_ro;
- tsec = kmem_cache_alloc(tsec_jar, GFP_KERNEL | __GFP_NOFAIL);
- if (!tsec)
- panic("[%d] : Unable to allocate security pointer\n", kdp_cmd);
-
- if ((u64)current->cred == (u64)&init_cred)
- memcpy(&temp_old, &init_cred_kdp, sizeof(struct cred_kdp));
- else
- memcpy(&temp_old, current->cred, sizeof(struct cred_kdp));
- memcpy(&temp_old, old, sizeof(struct cred));
-
- memset((void *)¶m_data, 0, sizeof(struct cred_param));
- param_data.cred = &temp_old;
- param_data.cred_ro = new_ro;
- param_data.use_cnt_ptr = use_cnt_ptr;
- param_data.sec_ptr = tsec;
- param_data.type = kdp_cmd;
- param_data.use_cnt = (u64)p;
- uh_call(UH_APP_KDP, PREPARE_RO_CRED, (u64)¶m_data, (u64)current, (u64)&init_cred, (u64)&init_cred_kdp);
- if (kdp_cmd == CMD_COPY_CREDS) {
- if ((new_ro->bp_task != (void *)p) ||
- new_ro->cred.security != tsec ||
- new_ro->use_cnt != use_cnt_ptr) {
- panic("[%d]: KDP Call failed task=0x%lx:0x%lx, sec=0x%lx:0x%lx, usecnt=0x%lx:0x%lx",
- kdp_cmd, (unsigned long) new_ro->bp_task, (unsigned long) p,
- (unsigned long) new_ro->cred.security, (unsigned long) tsec, (unsigned long) new_ro->use_cnt, (unsigned long) use_cnt_ptr);
- }
- } else {
- if ((new_ro->bp_task != current) ||
- (current->mm && new_ro->bp_pgd != (void *)pgd) ||
- (new_ro->cred.security != tsec) ||
- (new_ro->use_cnt != use_cnt_ptr)) {
- panic("[%d]: KDP Call failed task=0x%lx:0x%lx, sec=0x%lx:0x%lx, usecnt=0x%lx:0x%lx, pgd=0x%lx:0x%lx",
- kdp_cmd, (unsigned long) new_ro->bp_task, (unsigned long) current, (unsigned long) new_ro->cred.security, (unsigned long) tsec,
- (unsigned long) new_ro->use_cnt, (unsigned long) use_cnt_ptr, (unsigned long) new_ro->bp_pgd, (unsigned long) pgd);
- }
- }
- GET_ROCRED_RCU(new_ro)->non_rcu = old->non_rcu;
- GET_ROCRED_RCU(new_ro)->reflected_cred = 0;
- atomic_set(new_ro->use_cnt, 2);
- set_kdp_cred_subscribers((struct cred *)new_ro, 0);
- get_group_info(new_ro->cred.group_info);
- get_uid(new_ro->cred.user);
- get_user_ns(new_ro->cred.user_ns);
- #ifdef CONFIG_KEYS
- key_get(new_ro->cred.session_keyring);
- key_get(new_ro->cred.process_keyring);
- key_get(new_ro->cred.thread_keyring);
- key_get(new_ro->cred.request_key_auth);
- #endif
- if (!get_ucounts(new_ro->cred.ucounts))
- panic("[KDP] : ucount is NULL\n");
- validate_creds((struct cred *)new_ro);
- return (struct cred *)new_ro;
- }
- static bool is_kdp_tsec_jar(unsigned long addr)
- {
- struct kmem_cache *s;
- struct page *page;
- struct slab *p_slab;
- void *objp = (void *)addr;
- if (!objp)
- return false;
- page = virt_to_head_page(objp);
- p_slab = page_slab(page);
- s = p_slab->slab_cache;
- if (s && s == tsec_jar)
- return true;
- return false;
- }
- static inline int chk_invalid_kern_ptr(u64 tsec)
- {
- return (((u64)tsec >> 39) != (u64)0x1FFFFFF);
- }
- void kdp_free_security(unsigned long tsec)
- {
- if (!tsec || chk_invalid_kern_ptr(tsec))
- return;
- if (is_kdp_tsec_jar(tsec))
- kmem_cache_free(tsec_jar, (void *)tsec);
- else
- kfree((void *)tsec);
- }
- void kdp_assign_pgd(struct task_struct *p)
- {
- struct cred_kdp *p_cred = (struct cred_kdp *)p->cred;
- u64 pgd = (u64)(p->mm ? p->mm->pgd : swapper_pg_dir);
- if (p_cred->bp_pgd == (void *)pgd)
- return;
- uh_call(UH_APP_KDP, SET_CRED_PGD, (u64)p_cred, (u64)pgd, 0, 0);
- }
- void set_rocred_ucounts(struct cred *cred, struct ucounts *new_ucounts)
- {
- if (is_kdp_protect_addr((u64)cred)) {
- if (cred == &init_cred)
- uh_call(UH_APP_KDP, SET_CRED_UCOUNTS, (u64)cred, (u64)&init_cred, (u64)&(init_cred.ucounts), (u64)new_ucounts);
- else
- uh_call(UH_APP_KDP, SET_CRED_UCOUNTS, (u64)cred, (u64)&init_cred, (u64)&(cred->ucounts), (u64)new_ucounts);
- } else {
- cred->ucounts = new_ucounts;
- }
- }
- struct task_security_struct init_sec __kdp_ro;
- static inline unsigned int cmp_sec_integrity(const struct cred *cred, struct mm_struct *mm)
- {
- if (cred == &init_cred) {
- if (init_cred_kdp.bp_task != current)
- printk(KERN_ERR "[KDP] init_cred_kdp.bp_task: 0x%lx, current: 0x%lx\n",
- (unsigned long) init_cred_kdp.bp_task, (unsigned long) current);
- if (mm && (init_cred_kdp.bp_pgd != swapper_pg_dir) && (init_cred_kdp.bp_pgd != mm->pgd ))
- printk(KERN_ERR "[KDP] mm: 0x%lx, init_cred_kdp.bp_pgd: 0x%lx, swapper_pg_dir: %p, mm->pgd: 0x%lx\n",
- (unsigned long) mm, (unsigned long) init_cred_kdp.bp_pgd, swapper_pg_dir, (unsigned long) mm->pgd);
- return ((init_cred_kdp.bp_task != current) ||
- (mm && (!(in_interrupt() || in_softirq())) &&
- (init_cred_kdp.bp_pgd != swapper_pg_dir) &&
- (init_cred_kdp.bp_pgd != mm->pgd)));
- } else {
- if (((struct cred_kdp *)cred)->bp_task != current)
- printk(KERN_ERR "[KDP] cred->bp_task: 0x%lx, current: 0x%lx\n",
- (unsigned long) ((struct cred_kdp *)cred)->bp_task, (unsigned long) current);
- if (mm && (((struct cred_kdp *)cred)->bp_pgd != swapper_pg_dir) &&
- (((struct cred_kdp *)cred)->bp_pgd != mm->pgd))
- printk(KERN_ERR "[KDP] mm: 0x%lx, cred->bp_pgd: 0x%lx, swapper_pg_dir: %p, mm->pgd: 0x%lx\n",
- (unsigned long) mm, (unsigned long) ((struct cred_kdp *)cred)->bp_pgd, swapper_pg_dir, (unsigned long) mm->pgd);
- return ((((struct cred_kdp *)cred)->bp_task != current) ||
- (mm && (!(in_interrupt() || in_softirq())) &&
- (((struct cred_kdp *)cred)->bp_pgd != swapper_pg_dir) &&
- (((struct cred_kdp *)cred)->bp_pgd != mm->pgd)));
- }
-
- return 1;
- }
- static inline bool is_kdp_invalid_cred_sp(u64 cred, u64 sec_ptr)
- {
- struct task_security_struct *tsec = (struct task_security_struct *)sec_ptr;
- u64 cred_size = sizeof(struct cred_kdp);
- u64 tsec_size = sizeof(struct task_security_struct);
- if (cred == (u64)&init_cred)
- cred_size = sizeof(struct cred);
- if ((cred == (u64)&init_cred) && (sec_ptr == (u64)&init_sec))
- return false;
- if (!is_kdp_protect_addr(cred) ||
- !is_kdp_protect_addr(cred + cred_size) ||
- !is_kdp_protect_addr(sec_ptr) ||
- !is_kdp_protect_addr(sec_ptr + tsec_size)) {
-
-
-
-
-
- return true;
- }
- if ((u64)tsec->bp_cred != cred) {
-
-
- return true;
- }
- return false;
- }
- inline int kdp_restrict_fork(struct filename *path)
- {
- struct cred *shellcred;
- const struct cred_kdp *cred_kdp = (const struct cred_kdp *)(current->cred);
- if (!strcmp(path->name, "/system/bin/patchoat") ||
- !strcmp(path->name, "/system/bin/idmap2")) {
- return 0;
- }
- if ((cred_kdp->type) >> 1 & 1) {
- shellcred = prepare_creds();
- if (!shellcred)
- return 1;
- shellcred->uid.val = 2000;
- shellcred->gid.val = 2000;
- shellcred->euid.val = 2000;
- shellcred->egid.val = 2000;
- commit_creds(shellcred);
- }
- return 0;
- }
- #endif
- #ifdef CONFIG_KDP_NS
- static unsigned int cmp_ns_integrity(void)
- {
- struct kdp_mount *root = NULL;
- struct nsproxy *nsp = NULL;
- if (in_interrupt() || in_softirq())
- return 0;
- nsp = current->nsproxy;
- if (!nsp || !nsp->mnt_ns)
- return 0;
- root = (struct kdp_mount *)current->nsproxy->mnt_ns->root;
- if (root != (struct kdp_mount *)((struct kdp_vfsmount *)root->mnt)->bp_mount) {
- printk(KERN_ERR "[KDP] NameSpace Mismatch %lx != %lx\n nsp: 0x%lx, mnt_ns: 0x%lx\n",
- (unsigned long) root, (unsigned long) ((struct kdp_vfsmount *)root->mnt)->bp_mount, (unsigned long) nsp, (unsigned long) nsp->mnt_ns);
- return 1;
- }
- return 0;
- }
- static DEFINE_SPINLOCK(mnt_vfsmnt_lock);
- static struct kmem_cache *vfsmnt_cache __read_mostly;
- void cred_ctor_vfsmount(void *data)
- {
-
- }
- void __init kdp_mnt_init(void)
- {
- struct ns_param nsparam;
- vfsmnt_cache = kmem_cache_create("vfsmnt_cache", sizeof(struct kdp_vfsmount),
- 0, SLAB_HWCACHE_ALIGN | SLAB_PANIC, cred_ctor_vfsmount);
- if (!vfsmnt_cache)
- panic("Failed to allocate vfsmnt_cache\n");
- memset((void *)&nsparam, 0, sizeof(struct ns_param));
- nsparam.ns_buff_size = (u64)vfsmnt_cache->size;
- nsparam.ns_size = (u64)sizeof(struct kdp_vfsmount);
- nsparam.bp_offset = (u64)offsetof(struct kdp_vfsmount, bp_mount);
- nsparam.sb_offset = (u64)offsetof(struct kdp_vfsmount, mnt.mnt_sb);
- nsparam.flag_offset = (u64)offsetof(struct kdp_vfsmount, mnt.mnt_flags);
- nsparam.userns_offset = (u64)offsetof(struct kdp_vfsmount, mnt.mnt_userns);
-
- uh_call(UH_APP_KDP, NS_INIT, (u64)&nsparam, 0, 0, 0);
- }
- bool is_kdp_vfsmnt_cache(unsigned long addr)
- {
- static void *objp;
- static struct kmem_cache *s;
- static struct page *page;
- struct slab *p_slab;
- objp = (void *)addr;
- if (!objp)
- return false;
- page = virt_to_head_page(objp);
- p_slab = page_slab(page);
- s = p_slab->slab_cache;
- if (s && s == vfsmnt_cache)
- return true;
- return false;
- }
- inline void kdp_set_mnt_root_sb(struct vfsmount *mnt, struct dentry *mnt_root, struct super_block *mnt_sb)
- {
- uh_call(UH_APP_KDP, SET_NS_ROOT_SB, (u64)mnt, (u64)mnt_root, (u64)mnt_sb, 0);
- }
- inline void kdp_assign_mnt_flags(struct vfsmount *mnt, int flags)
- {
- if (mnt->mnt_flags == flags)
- return;
- uh_call(UH_APP_KDP, SET_NS_FLAGS, (u64)mnt, (u64)flags, 0, 0);
- }
- inline void kdp_clear_mnt_flags(struct vfsmount *mnt, int flags)
- {
- int f = mnt->mnt_flags;
- f &= ~flags;
- kdp_assign_mnt_flags(mnt, f);
- }
- void kdp_set_mnt_flags(struct vfsmount *mnt, int flags)
- {
- int f = mnt->mnt_flags;
- f |= flags;
- kdp_assign_mnt_flags(mnt, f);
- }
- void kdp_set_mnt_userns(struct vfsmount *mnt, struct user_namespace *userns)
- {
- if (mnt->mnt_userns == userns)
- return;
- uh_call(UH_APP_KDP, SET_NS_USERNS, (u64)mnt, (u64)userns, 0, 0);
- }
- void kdp_set_ns_data(struct vfsmount *mnt, void *data)
- {
- uh_call(UH_APP_KDP, SET_NS_DATA, (u64)mnt, (u64)data, 0, 0);
- }
- int kdp_mnt_alloc_vfsmount(struct mount *mnt)
- {
- struct kdp_vfsmount *vfsmnt = NULL;
- vfsmnt = kmem_cache_alloc(vfsmnt_cache, GFP_KERNEL);
- if (!vfsmnt)
- return 1;
- spin_lock(&mnt_vfsmnt_lock);
- uh_call(UH_APP_KDP, SET_NS_BP, (u64)vfsmnt, (u64)mnt, 0, 0);
- ((struct kdp_mount *)mnt)->mnt = (struct vfsmount *)vfsmnt;
- spin_unlock(&mnt_vfsmnt_lock);
- return 0;
- }
- void kdp_free_vfsmount(void *objp)
- {
- kmem_cache_free(vfsmnt_cache, objp);
- }
- #endif
- #ifdef CONFIG_KDP_CRED
- int security_integrity_current(void)
- {
- const struct cred *cur_cred = current_cred();
- rcu_read_lock();
- if (kdp_enable &&
- (is_kdp_invalid_cred_sp((u64)cur_cred, (u64)cur_cred->security)
- || cmp_sec_integrity(cur_cred, current->mm)
- #ifdef CONFIG_KDP_NS
- || cmp_ns_integrity()
- #endif
- )) {
- rcu_read_unlock();
- panic("KDP CRED PROTECTION VIOLATION\n");
- }
- rcu_read_unlock();
- return 0;
- }
- #endif
- inline int get_kdp_kmem_cache_type(const char *name)
- {
- if (name) {
- #ifdef CONFIG_KDP_CRED
- if (!strncmp(name, CRED_JAR_RO, strlen(CRED_JAR_RO)))
- return CRED_JAR_TYPE;
- if (!strncmp(name, TSEC_JAR, strlen(TSEC_JAR)))
- return TSEC_JAR_TYPE;
- #endif
- #ifdef CONFIG_KDP_NS
- if (!strncmp(name, VFSMNT_JAR, strlen(VFSMNT_JAR)))
- return VFSMNT_JAR_TYPE;
- #endif
- }
- return UNKNOWN_JAR_TYPE;
- }
- inline bool is_kdp_kmem_cache_name(const char *name)
- {
- if (name) {
- #ifdef CONFIG_KDP_CRED
- if (!strncmp(name, CRED_JAR_RO, strlen(CRED_JAR_RO)) ||
- !strncmp(name, TSEC_JAR, strlen(TSEC_JAR)))
- return true;
- #endif
- #ifdef CONFIG_KDP_NS
- if (!strncmp(name, VFSMNT_JAR, strlen(VFSMNT_JAR)))
- return true;
- #endif
- }
- return false;
- }
- inline bool is_kdp_kmem_cache(struct kmem_cache *s)
- {
- if (!s->name)
- return false;
- #ifdef CONFIG_KDP_CRED
- if (s == cred_jar_ro || s == tsec_jar)
- return true;
- #endif
- #ifdef CONFIG_KDP_NS
- if (s == vfsmnt_cache)
- return true;
- #endif
- return false;
- }
|