HAOC: Add support for x86 CRED Protection (CREDP).

Add support for x86 CRED Protection (CREDP)
in deepin kernel.

Signed-off-by: Liu Zhehui <liuzhh@zgclab.edu.cn>
This commit is contained in:
0bluewhale0 2025-04-20 17:32:48 +08:00 committed by Avenger-285714
parent 7806e1cc71
commit 416542dded
41 changed files with 1620 additions and 8 deletions

View File

@ -1557,6 +1557,9 @@ config IEE_PTRP
depends on IEE
def_bool y
config CREDP
depends on IEE
def_bool y
# Common NUMA Features
config NUMA
bool "NUMA Memory Allocation and Scheduler Support"

View File

@ -19,6 +19,37 @@ enum {
IEE_OP_SET_TOKEN_PGD,
IEE_OP_INVALIDATE_TOKEN,
IEE_OP_VALIDATE_TOKEN,
#endif
#ifdef CONFIG_CREDP
IEE_OP_COPY_CRED,
IEE_OP_SET_CRED_UID,
IEE_OP_SET_CRED_GID,
IEE_OP_SET_CRED_SUID,
IEE_OP_SET_CRED_SGID,
IEE_OP_SET_CRED_EUID,
IEE_OP_SET_CRED_EGID,
IEE_OP_SET_CRED_FSUID,
IEE_OP_SET_CRED_FSGID,
IEE_OP_SET_CRED_USER,
IEE_OP_SET_CRED_USER_NS,
IEE_OP_SET_CRED_GROUP_INFO,
IEE_OP_SET_CRED_SECUREBITS,
IEE_OP_SET_CRED_CAP_INHER,
IEE_OP_SET_CRED_CAP_PERM,
IEE_OP_SET_CRED_CAP_EFFECT,
IEE_OP_SET_CRED_CAP_BSET,
IEE_OP_SET_CRED_CAP_AMBIENT,
IEE_OP_SET_CRED_JIT_KEYRING,
IEE_OP_SET_CRED_SESS_KEYRING,
IEE_OP_SET_CRED_PROC_KEYRING,
IEE_OP_SET_CRED_THREAD_KEYRING,
IEE_OP_SET_CRED_REQ_KEYRING,
IEE_OP_SET_CRED_NON_RCU,
IEE_OP_SET_CRED_ATSET_USAGE,
IEE_OP_SET_CRED_ATOP_USAGE,
IEE_OP_SET_CRED_SECURITY,
IEE_OP_SET_CRED_RCU,
IEE_OP_SET_CRED_UCOUNTS,
#endif
IEE_FLAG_END
};
@ -31,4 +62,9 @@ enum {
#define IEE_LOAD_IDT 4
#endif
#ifdef CONFIG_CREDP
#define AT_ADD 1
#define AT_INC_NOT_ZERO 2
#define AT_SUB_AND_TEST 3
#endif
#endif

View File

@ -13,9 +13,9 @@
#include <linux/types.h>
#include <linux/sched.h>
void _iee_memcpy(unsigned long __unused, void *dst, void *src, size_t n);
void _iee_memset(unsigned long __unused, void *ptr, int data, size_t n);
void _iee_set_freeptr(unsigned long __unused, void **pptr, void *ptr);
void _iee_memcpy(unsigned long __unused,void *dst,void *src, size_t n);
void _iee_memset(unsigned long __unused,void *ptr, int data, size_t n);
void _iee_set_freeptr(unsigned long __unused,void **pptr,void *ptr);
unsigned long _iee_test_and_clear_bit(unsigned long __unused,
long nr, unsigned long *addr);
#ifdef CONFIG_IEE_PTRP
@ -24,4 +24,50 @@ void _iee_set_token_pgd(unsigned long __unused, struct task_struct *tsk,
void _iee_invalidate_token(unsigned long __unused, struct task_struct *tsk);
void _iee_validate_token(unsigned long __unused, struct task_struct *tsk);
#endif
#ifdef CONFIG_CREDP
#include <linux/cred.h>
void _iee_copy_cred(unsigned long __unused, struct cred *old, struct cred *new);
void _iee_set_cred_uid(unsigned long __unused, struct cred *cred, kuid_t uid);
void _iee_set_cred_gid(unsigned long __unused, struct cred *cred, kgid_t gid);
void _iee_set_cred_suid(unsigned long __unused, struct cred *cred, kuid_t suid);
void _iee_set_cred_sgid(unsigned long __unused, struct cred *cred, kgid_t sgid);
void _iee_set_cred_euid(unsigned long __unused, struct cred *cred, kuid_t euid);
void _iee_set_cred_egid(unsigned long __unused, struct cred *cred, kgid_t egid);
void _iee_set_cred_fsuid(unsigned long __unused, struct cred *cred, kuid_t fsuid);
void _iee_set_cred_fsgid(unsigned long __unused, struct cred *cred, kgid_t fsgid);
void _iee_set_cred_user(unsigned long __unused, struct cred *cred, struct user_struct *user);
void _iee_set_cred_user_ns(unsigned long __unused,
struct cred *cred, struct user_namespace *user_ns);
void _iee_set_cred_group_info(unsigned long __unused,
struct cred *cred, struct group_info *group_info);
void _iee_set_cred_securebits(unsigned long __unused,
struct cred *cred, unsigned int securebits);
void _iee_set_cred_cap_inheritable(unsigned long __unused,
struct cred *cred, kernel_cap_t cap_inheritable);
void _iee_set_cred_cap_permitted(unsigned long __unused,
struct cred *cred, kernel_cap_t cap_permitted);
void _iee_set_cred_cap_effective(unsigned long __unused,
struct cred *cred, kernel_cap_t cap_effective);
void _iee_set_cred_cap_bset(unsigned long __unused, struct cred *cred, kernel_cap_t cap_bset);
void _iee_set_cred_cap_ambient(unsigned long __unused, struct cred *cred, kernel_cap_t cap_ambient);
void _iee_set_cred_jit_keyring(unsigned long __unused,
struct cred *cred, unsigned char jit_keyring);
void _iee_set_cred_session_keyring(unsigned long __unused,
struct cred *cred, struct key *session_keyring);
void _iee_set_cred_process_keyring(unsigned long __unused,
struct cred *cred, struct key *process_keyring);
void _iee_set_cred_thread_keyring(unsigned long __unused,
struct cred *cred, struct key *thread_keyring);
void _iee_set_cred_request_key_auth(unsigned long __unused,
struct cred *cred, struct key *request_key_auth);
void _iee_set_cred_non_rcu(unsigned long __unused, struct cred *cred, int non_rcu);
void _iee_set_cred_atomic_set_usage(unsigned long __unused, struct cred *cred, int i);
unsigned long _iee_set_cred_atomic_op_usage(unsigned long __unused,
struct cred *cred, int flag, int nr);
void _iee_set_cred_security(unsigned long __unused, struct cred *cred,void *security);
void _iee_set_cred_rcu(unsigned long __unused, struct cred *cred, struct rcu_head *rcu);
void _iee_set_cred_ucounts(unsigned long __unused, struct cred *cred, struct ucounts *ucounts);
#endif
#endif

View File

@ -0,0 +1,285 @@
/* SPDX-License-Identifier: GPL-2.0-or-later */
#ifndef _LINUX_IEE_CRED_H
#define _LINUX_IEE_CRED_H
#include <asm/haoc/haoc-def.h>
#include <linux/cred.h>
extern unsigned long long iee_rw_gate(int flag, ...);
static void __maybe_unused iee_copy_cred(const struct cred *old, struct cred *new)
{
if(!haoc_enabled)
{
memcpy(new, old, sizeof(struct cred));
return;
}
iee_rw_gate(IEE_OP_COPY_CRED, old, new);
}
static void __maybe_unused iee_set_cred_uid(struct cred *cred, kuid_t uid)
{
if(!haoc_enabled)
{
cred->uid = uid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_UID, cred, uid);
}
static void __maybe_unused iee_set_cred_gid(struct cred *cred, kgid_t gid)
{
if(!haoc_enabled)
{
cred->gid = gid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_GID, cred, gid);
}
static void __maybe_unused iee_set_cred_suid(struct cred *cred, kuid_t suid)
{
if(!haoc_enabled)
{
cred->suid = suid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_SUID, cred, suid);
}
static void __maybe_unused iee_set_cred_sgid(struct cred *cred, kgid_t sgid)
{
if(!haoc_enabled)
{
cred->sgid = sgid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_SGID, cred, sgid);
}
static void __maybe_unused iee_set_cred_euid(struct cred *cred, kuid_t euid)
{
if(!haoc_enabled)
{
cred->euid = euid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_EUID, cred, euid);
}
static void __maybe_unused iee_set_cred_egid(struct cred *cred, kgid_t egid)
{
if(!haoc_enabled)
{
cred->egid = egid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_EGID, cred, egid);
}
static void __maybe_unused iee_set_cred_fsuid(struct cred *cred, kuid_t fsuid)
{
if(!haoc_enabled)
{
cred->fsuid = fsuid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_FSUID, cred, fsuid);
}
static void __maybe_unused iee_set_cred_fsgid(struct cred *cred, kgid_t fsgid)
{
if(!haoc_enabled)
{
cred->fsgid = fsgid;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_FSGID, cred, fsgid);
}
static void __maybe_unused iee_set_cred_user(struct cred *cred, struct user_struct *user)
{
if(!haoc_enabled)
{
cred->user = user;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_USER, cred, user);
}
static void __maybe_unused iee_set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
{
if(!haoc_enabled)
{
cred->user_ns = user_ns;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_USER_NS, cred, user_ns);
}
static void __maybe_unused iee_set_cred_ucounts(struct cred *cred, struct ucounts *ucounts)
{
if(!haoc_enabled)
{
cred->ucounts = ucounts;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_UCOUNTS, cred, ucounts);
}
static void __maybe_unused iee_set_cred_group_info(struct cred *cred, struct group_info *group_info)
{
if(!haoc_enabled)
{
cred->group_info = group_info;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_GROUP_INFO, cred, group_info);
}
static void __maybe_unused iee_set_cred_securebits(struct cred *cred,
unsigned int securebits)
{
if(!haoc_enabled)
{
cred->securebits = securebits;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_SECUREBITS, cred, securebits);
}
static void __maybe_unused iee_set_cred_cap_inheritable(struct cred *cred,
kernel_cap_t cap_inheritable)
{
if(!haoc_enabled)
{
cred->cap_inheritable = cap_inheritable;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_CAP_INHER, cred, cap_inheritable);
}
static void __maybe_unused iee_set_cred_cap_permitted(struct cred *cred, kernel_cap_t cap_permitted)
{
if(!haoc_enabled)
{
cred->cap_permitted = cap_permitted;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_CAP_PERM, cred, cap_permitted);
}
static void __maybe_unused iee_set_cred_cap_effective(struct cred *cred, kernel_cap_t cap_effective)
{
if(!haoc_enabled)
{
cred->cap_effective = cap_effective;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_CAP_EFFECT, cred, cap_effective);
}
static void __maybe_unused iee_set_cred_cap_bset(struct cred *cred, kernel_cap_t cap_bset)
{
if(!haoc_enabled)
{
cred->cap_bset = cap_bset;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_CAP_BSET, cred, cap_bset);
}
static void __maybe_unused iee_set_cred_cap_ambient(struct cred *cred, kernel_cap_t cap_ambient)
{
if(!haoc_enabled)
{
cred->cap_ambient = cap_ambient;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_CAP_AMBIENT, cred, cap_ambient);
}
static void __maybe_unused iee_set_cred_atomic_set_usage(struct cred *cred, int i)
{
if(!haoc_enabled)
{
atomic_long_set(&cred->usage, i);
return;
}
iee_rw_gate(IEE_OP_SET_CRED_ATSET_USAGE, cred, i);
}
static void __maybe_unused iee_set_cred_rcu(struct cred *cred, struct rcu_head *rcu)
{
iee_rw_gate(IEE_OP_SET_CRED_RCU, cred, rcu);
}
#ifdef CONFIG_KEYS
static void __maybe_unused iee_set_cred_jit_keyring(struct cred *cred, unsigned char jit_keyring)
{
if(!haoc_enabled)
{
cred->jit_keyring = jit_keyring;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_JIT_KEYRING, cred, jit_keyring);
}
static void __maybe_unused iee_set_cred_session_keyring(struct cred *cred,
struct key *session_keyring)
{
if(!haoc_enabled)
{
cred->session_keyring = session_keyring;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_SESS_KEYRING, cred, session_keyring);
}
static void __maybe_unused iee_set_cred_process_keyring(struct cred *cred,
struct key *process_keyring)
{
if(!haoc_enabled)
{
cred->process_keyring = process_keyring;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_PROC_KEYRING, cred, process_keyring);
}
static void __maybe_unused iee_set_cred_thread_keyring(struct cred *cred,
struct key *thread_keyring)
{
if(!haoc_enabled)
{
cred->thread_keyring = thread_keyring;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_THREAD_KEYRING, cred, thread_keyring);
}
static void __maybe_unused iee_set_cred_request_key_auth(struct cred *cred,
struct key *request_key_auth)
{
if(!haoc_enabled)
{
cred->request_key_auth = request_key_auth;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_REQ_KEYRING, cred, request_key_auth);
}
#endif
#ifdef CONFIG_SECURITY
static void __maybe_unused iee_set_cred_security(struct cred *cred, void *security)
{
if(!haoc_enabled)
{
cred->security = security;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_SECURITY, cred, security);
}
#endif
#endif

View File

@ -10,9 +10,15 @@
#ifndef _LINUX_IEE_FUNC_H
#define _LINUX_IEE_FUNC_H
#define HUGE_PMD_ORDER 9
#include <linux/slab.h>
extern void set_iee_page(unsigned long addr, unsigned int order);
extern void unset_iee_page(unsigned long addr, unsigned int order);
extern bool iee_free_slab_data(struct kmem_cache *s, struct slab *slab, unsigned int order);
extern unsigned int iee_calculate_order(struct kmem_cache *s, unsigned int order);
extern void iee_free_slab(struct kmem_cache *s, struct slab *slab,
void (*do_free_slab)(struct work_struct *work));
extern void iee_free_cred_slab(struct work_struct *work);
#endif /* _LINUX_IEE_FUNC_H */

View File

@ -1,2 +1,3 @@
obj-y += haoc.o
obj-y += iee/
obj-$(CONFIG_CREDP) += credp/

View File

@ -0,0 +1,3 @@
obj-y += credp.o
ccflags-y += -I$(srctree)/mm

View File

@ -0,0 +1,204 @@
// SPDX-License-Identifier: GPL-2.0
#include <asm/haoc/haoc-def.h>
#include <asm/haoc/iee.h>
#include <linux/cred.h>
#include <linux/mm.h>
#include <asm/haoc/iee-func.h>
#include <linux/slab.h>
#include "slab.h"
extern struct cred init_cred;
void _iee_set_cred_rcu(unsigned long __unused, struct cred *cred, struct rcu_head *rcu)
{
*((struct rcu_head **)(&(cred->rcu.func))) = rcu;
}
void _iee_set_cred_security(unsigned long __unused, struct cred *cred, void *security)
{
cred->security = security;
}
unsigned long _iee_set_cred_atomic_op_usage(unsigned long __unused,
struct cred *cred, int flag, int nr)
{
switch (flag) {
case AT_ADD: {
atomic_long_add(nr, &cred->usage);
return 0;
}
case AT_INC_NOT_ZERO: {
return atomic_long_inc_not_zero(&cred->usage);
}
case AT_SUB_AND_TEST: {
return atomic_long_sub_and_test(nr, &cred->usage);
}
}
return 0;
}
void _iee_set_cred_atomic_set_usage(unsigned long __unused, struct cred *cred, int i)
{
atomic_long_set(&cred->usage, i);
}
void _iee_set_cred_non_rcu(unsigned long __unused, struct cred *cred, int non_rcu)
{
cred->non_rcu = non_rcu;
}
void _iee_set_cred_session_keyring(unsigned long __unused, struct cred *cred,
struct key *session_keyring)
{
cred->session_keyring = session_keyring;
}
void _iee_set_cred_process_keyring(unsigned long __unused, struct cred *cred,
struct key *process_keyring)
{
cred->process_keyring = process_keyring;
}
void _iee_set_cred_thread_keyring(unsigned long __unused, struct cred *cred,
struct key *thread_keyring)
{
cred->thread_keyring = thread_keyring;
}
void _iee_set_cred_request_key_auth(unsigned long __unused, struct cred *cred,
struct key *request_key_auth)
{
cred->request_key_auth = request_key_auth;
}
void _iee_set_cred_jit_keyring(unsigned long __unused, struct cred *cred, unsigned char jit_keyring)
{
cred->jit_keyring = jit_keyring;
}
void _iee_set_cred_cap_inheritable(unsigned long __unused, struct cred *cred,
kernel_cap_t cap_inheritable)
{
cred->cap_inheritable = cap_inheritable;
}
void _iee_set_cred_cap_permitted(unsigned long __unused, struct cred *cred,
kernel_cap_t cap_permitted)
{
cred->cap_permitted = cap_permitted;
}
void _iee_set_cred_cap_effective(unsigned long __unused, struct cred *cred,
kernel_cap_t cap_effective)
{
cred->cap_effective = cap_effective;
}
void _iee_set_cred_cap_bset(unsigned long __unused, struct cred *cred, kernel_cap_t cap_bset)
{
cred->cap_bset = cap_bset;
}
void _iee_set_cred_cap_ambient(unsigned long __unused, struct cred *cred, kernel_cap_t cap_ambient)
{
cred->cap_ambient = cap_ambient;
}
void _iee_set_cred_securebits(unsigned long __unused, struct cred *cred,
unsigned int securebits)
{
cred->securebits = securebits;
}
void _iee_set_cred_group_info(unsigned long __unused, struct cred *cred,
struct group_info *group_info)
{
cred->group_info = group_info;
}
void _iee_set_cred_ucounts(unsigned long __unused, struct cred *cred, struct ucounts *ucounts)
{
cred->ucounts = ucounts;
}
void _iee_set_cred_user_ns(unsigned long __unused, struct cred *cred,
struct user_namespace *user_ns)
{
cred->user_ns = user_ns;
}
void _iee_set_cred_user(unsigned long __unused, struct cred *cred, struct user_struct *user)
{
cred->user = user;
}
void _iee_set_cred_fsgid(unsigned long __unused, struct cred *cred, kgid_t fsgid)
{
cred->fsgid = fsgid;
}
void _iee_set_cred_fsuid(unsigned long __unused, struct cred *cred, kuid_t fsuid)
{
cred->fsuid = fsuid;
}
void _iee_set_cred_egid(unsigned long __unused, struct cred *cred, kgid_t egid)
{
cred->egid = egid;
}
void _iee_set_cred_euid(unsigned long __unused, struct cred *cred, kuid_t euid)
{
cred->euid = euid;
}
void _iee_set_cred_sgid(unsigned long __unused, struct cred *cred, kgid_t sgid)
{
cred->sgid = sgid;
}
void _iee_set_cred_suid(unsigned long __unused, struct cred *cred, kuid_t suid)
{
cred->suid = suid;
}
void _iee_copy_cred(unsigned long __unused, struct cred *old, struct cred *new)
{
if (new == &init_cred)
panic("copy_cred for init_cred: %lx\n", (unsigned long)new);
struct rcu_head *rcu = (struct rcu_head *)(new->rcu.func);
memcpy(new, old, sizeof(struct cred));
*(struct rcu_head **)(&(new->rcu.func)) = rcu;
*(struct rcu_head *)(new->rcu.func) = *(struct rcu_head *)(old->rcu.func);
}
void _iee_set_cred_gid(unsigned long __unused, struct cred *cred, kgid_t gid)
{
cred->gid = gid;
}
void _iee_set_cred_uid(unsigned long __unused, struct cred *cred, kuid_t uid)
{
cred->uid = uid;
}
struct iee_free_slab_work {
struct work_struct work;
struct kmem_cache *s;
struct slab *slab;
};
void iee_free_cred_slab(struct work_struct *work)
{
struct iee_free_slab_work *iee_free_slab_work =
container_of(work, struct iee_free_slab_work, work);
struct slab *slab = iee_free_slab_work->slab;
struct folio *folio = slab_folio(slab);
int order = folio_order(folio);
unset_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)), order);
__free_pages(&folio->page, order);
kfree(iee_free_slab_work);
}

View File

@ -19,6 +19,37 @@ iee_func iee_funcs[] = {
(iee_func)_iee_set_token_pgd,
(iee_func)_iee_invalidate_token,
(iee_func)_iee_validate_token,
#endif
#ifdef CONFIG_CREDP
(iee_func)_iee_copy_cred,
(iee_func)_iee_set_cred_uid,
(iee_func)_iee_set_cred_gid,
(iee_func)_iee_set_cred_suid,
(iee_func)_iee_set_cred_sgid,
(iee_func)_iee_set_cred_euid,
(iee_func)_iee_set_cred_egid,
(iee_func)_iee_set_cred_fsuid,
(iee_func)_iee_set_cred_fsgid,
(iee_func)_iee_set_cred_user,
(iee_func)_iee_set_cred_user_ns,
(iee_func)_iee_set_cred_group_info,
(iee_func)_iee_set_cred_securebits,
(iee_func)_iee_set_cred_cap_inheritable,
(iee_func)_iee_set_cred_cap_permitted,
(iee_func)_iee_set_cred_cap_effective,
(iee_func)_iee_set_cred_cap_bset,
(iee_func)_iee_set_cred_cap_ambient,
(iee_func)_iee_set_cred_jit_keyring,
(iee_func)_iee_set_cred_session_keyring,
(iee_func)_iee_set_cred_process_keyring,
(iee_func)_iee_set_cred_thread_keyring,
(iee_func)_iee_set_cred_request_key_auth,
(iee_func)_iee_set_cred_non_rcu,
(iee_func)_iee_set_cred_atomic_set_usage,
(iee_func)_iee_set_cred_atomic_op_usage,
(iee_func)_iee_set_cred_security,
(iee_func)_iee_set_cred_rcu,
(iee_func)_iee_set_cred_ucounts,
#endif
NULL
};

View File

@ -13,6 +13,7 @@
#ifdef CONFIG_IEE_PTRP
#include <asm/haoc/iee-token.h>
#endif
extern bool haoc_enabled;
void set_iee_page(unsigned long addr, unsigned int order)
{
@ -33,6 +34,8 @@ struct iee_free_slab_work {
void iee_free_slab(struct kmem_cache *s, struct slab *slab,
void (*do_free_slab)(struct work_struct *work))
{
if(haoc_enabled)
return;
struct iee_free_slab_work *iee_free_slab_work =
kmalloc(sizeof(struct iee_free_slab_work), GFP_ATOMIC);
@ -72,9 +75,17 @@ bool iee_free_slab_data(struct kmem_cache *s, struct slab *slab,
unsigned int iee_calculate_order(struct kmem_cache *s, unsigned int order)
{
if(!haoc_enabled)
{
return order;
}
#ifdef CONFIG_IEE_PTRP
if (strcmp(s->name, "task_struct") == 0)
return IEE_DATA_ORDER;
#endif
#ifdef CONFIG_CREDP
if (strcmp(s->name, "cred_jar") == 0)
order = IEE_DATA_ORDER;
#endif
return order;
}

View File

@ -71,6 +71,7 @@ SYM_FUNC_START(iee_rw_gate)
jmp __x86_return_thunk /* ret */
SYM_FUNC_END(iee_rw_gate)
EXPORT_SYMBOL(iee_rw_gate)
#ifdef CONFIG_IEE_SIP
SYM_FUNC_START(iee_rwx_gate)

View File

@ -165,6 +165,7 @@ void __init iee_init(void)
}
bool __ro_after_init haoc_enabled;
EXPORT_SYMBOL(haoc_enabled);
#ifdef CONFIG_IEE_SIP
extern unsigned long cr4_pinned_mask;
#endif

View File

@ -114,6 +114,12 @@ __iee_si_text_end = .;
. = ALIGN(PAGE_SIZE); \
__iee_si_data_end = .;
#endif
#ifdef CONFIG_CREDP
#define CRED_DATA \
. = ALIGN(PAGE_SIZE); \
*(.iee.cred) \
. = ALIGN(PAGE_SIZE);
#endif
PHDRS {
text PT_LOAD FLAGS(5); /* R_E */
@ -202,6 +208,9 @@ SECTIONS
DATA_DATA
#ifdef CONFIG_IEE_SIP
IEE_SI_DATA
#endif
#ifdef CONFIG_CREDP
CRED_DATA
#endif
CONSTRUCTORS

View File

@ -53,6 +53,10 @@
#include <trace/events/sched.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
static bool dump_vma_snapshot(struct coredump_params *cprm);
static void free_vma_snapshot(struct coredump_params *cprm);
@ -564,7 +568,11 @@ void do_coredump(const kernel_siginfo_t *siginfo)
*/
if (__get_dumpable(cprm.mm_flags) == SUID_DUMP_ROOT) {
/* Setuid core dump mode */
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(cred, GLOBAL_ROOT_UID);
#else
cred->fsuid = GLOBAL_ROOT_UID; /* Dump root private */
#endif
need_suid_safe = true;
}

View File

@ -81,6 +81,9 @@
#ifdef CONFIG_IEE_PTRP
#include <asm/haoc/iee-token.h>
#endif
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
static int bprm_creds_from_file(struct linux_binprm *bprm);
@ -1690,12 +1693,20 @@ static void bprm_fill_uid(struct linux_binprm *bprm, struct file *file)
if (mode & S_ISUID) {
bprm->per_clear |= PER_CLEAR_ON_SETID;
#ifdef CONFIG_CREDP
iee_set_cred_euid(bprm->cred, vfsuid_into_kuid(vfsuid));
#else
bprm->cred->euid = vfsuid_into_kuid(vfsuid);
#endif
}
if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
bprm->per_clear |= PER_CLEAR_ON_SETID;
#ifdef CONFIG_CREDP
iee_set_cred_egid(bprm->cred, vfsgid_into_kgid(vfsgid));
#else
bprm->cred->egid = vfsgid_into_kgid(vfsgid);
#endif
}
}

View File

@ -15,6 +15,10 @@
#include <linux/sunrpc/metrics.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "flexfilelayout.h"
#include "../nfs4session.h"
#include "../nfs4idmap.h"
@ -502,8 +506,13 @@ ff_layout_alloc_lseg(struct pnfs_layout_hdr *lh,
rc = -ENOMEM;
if (!kcred)
goto out_err_free;
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(kcred, uid);
iee_set_cred_fsgid(kcred, gid);
#else
kcred->fsuid = uid;
kcred->fsgid = gid;
#endif
cred = RCU_INITIALIZER(kcred);
if (lgr->range.iomode == IOMODE_READ)

View File

@ -48,6 +48,11 @@
#include <linux/module.h>
#include <linux/user_namespace.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "internal.h"
#include "netns.h"
#include "nfs4idmap.h"
@ -226,8 +231,13 @@ int nfs_idmap_init(void)
goto failed_reg_legacy;
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(cred, keyring);
iee_set_cred_jit_keyring(cred, KEY_REQKEY_DEFL_THREAD_KEYRING);
#else
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
#endif
id_resolver_cache = cred;
return 0;

View File

@ -2,6 +2,9 @@
/* Copyright (C) 1995, 1996 Olaf Kirch <okir@monad.swb.de> */
#include <linux/sched.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "nfsd.h"
#include "auth.h"
@ -32,22 +35,40 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
if (!new)
return -ENOMEM;
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, rqstp->rq_cred.cr_uid);
iee_set_cred_fsgid(new, rqstp->rq_cred.cr_gid);
#else
new->fsuid = rqstp->rq_cred.cr_uid;
new->fsgid = rqstp->rq_cred.cr_gid;
#endif
rqgi = rqstp->rq_cred.cr_group_info;
if (flags & NFSEXP_ALLSQUASH) {
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, exp->ex_anon_uid);
iee_set_cred_fsgid(new, exp->ex_anon_gid);
#else
new->fsuid = exp->ex_anon_uid;
new->fsgid = exp->ex_anon_gid;
#endif
gi = groups_alloc(0);
if (!gi)
goto oom;
} else if (flags & NFSEXP_ROOTSQUASH) {
if (uid_eq(new->fsuid, GLOBAL_ROOT_UID))
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, exp->ex_anon_uid);
#else
new->fsuid = exp->ex_anon_uid;
#endif
if (gid_eq(new->fsgid, GLOBAL_ROOT_GID))
#ifdef CONFIG_CREDP
iee_set_cred_fsgid(new, exp->ex_anon_gid);
#else
new->fsgid = exp->ex_anon_gid;
#endif
gi = groups_alloc(rqgi->ngroups);
if (!gi)
@ -67,18 +88,35 @@ int nfsd_setuser(struct svc_rqst *rqstp, struct svc_export *exp)
}
if (uid_eq(new->fsuid, INVALID_UID))
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, exp->ex_anon_uid);
#else
new->fsuid = exp->ex_anon_uid;
#endif
if (gid_eq(new->fsgid, INVALID_GID))
#ifdef CONFIG_CREDP
iee_set_cred_fsgid(new, exp->ex_anon_gid);
#else
new->fsgid = exp->ex_anon_gid;
#endif
set_groups(new, gi);
put_group_info(gi);
if (!uid_eq(new->fsuid, GLOBAL_ROOT_UID))
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, cap_drop_nfsd_set(new->cap_effective));
#else
new->cap_effective = cap_drop_nfsd_set(new->cap_effective);
#endif
else
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted));
#else
new->cap_effective = cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted);
#endif
put_cred(override_creds(new));
put_cred(new);
return 0;

View File

@ -35,6 +35,9 @@
#include <linux/sunrpc/xprt.h>
#include <linux/sunrpc/svc_xprt.h>
#include <linux/slab.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "nfsd.h"
#include "state.h"
#include "netns.h"
@ -946,8 +949,13 @@ static const struct cred *get_backchannel_cred(struct nfs4_client *clp, struct r
if (!kcred)
return NULL;
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(kcred, ses->se_cb_sec.uid);
iee_set_cred_fsgid(kcred, ses->se_cb_sec.gid);
#else
kcred->fsuid = ses->se_cb_sec.uid;
kcred->fsgid = ses->se_cb_sec.gid;
#endif
return kcred;
}
}

View File

@ -44,6 +44,10 @@
#include <linux/sunrpc/clnt.h>
#include <linux/nfsd/cld.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "nfsd.h"
#include "state.h"
#include "vfs.h"
@ -78,8 +82,13 @@ nfs4_save_creds(const struct cred **original_creds)
if (!new)
return -ENOMEM;
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, GLOBAL_ROOT_UID);
iee_set_cred_fsgid(new, GLOBAL_ROOT_GID);
#else
new->fsuid = GLOBAL_ROOT_UID;
new->fsgid = GLOBAL_ROOT_GID;
#endif
*original_creds = override_creds(new);
put_cred(new);
return 0;

View File

@ -11,6 +11,9 @@
#include <linux/exportfs.h>
#include <linux/sunrpc/svcauth_gss.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "nfsd.h"
#include "vfs.h"
#include "auth.h"
@ -223,9 +226,14 @@ static __be32 nfsd_set_fh_dentry(struct svc_rqst *rqstp, struct svc_fh *fhp)
error = nfserrno(-ENOMEM);
goto out;
}
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted));
#else
new->cap_effective =
cap_raise_nfsd_set(new->cap_effective,
new->cap_permitted);
#endif
put_cred(override_creds(new));
put_cred(new);
} else {

View File

@ -34,6 +34,9 @@
#include <linux/compat.h>
#include <linux/mnt_idmapping.h>
#include <linux/filelock.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "internal.h"
@ -413,18 +416,35 @@ static const struct cred *access_override_creds(void)
* this work. Make sure it stays in sync if making any changes in this
* routine.
*/
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(override_cred, override_cred->uid);
iee_set_cred_fsgid(override_cred, override_cred->gid);
#else
override_cred->fsuid = override_cred->uid;
override_cred->fsgid = override_cred->gid;
#endif
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
/* Clear the capabilities if we switch to a non-root user */
kuid_t root_uid = make_kuid(override_cred->user_ns, 0);
if (!uid_eq(override_cred->uid, root_uid))
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = override_cred->cap_effective;
tmp_cap.val = 0;
iee_set_cred_cap_effective(override_cred, tmp_cap);
} while (0);
#else
cap_clear(override_cred->cap_effective);
#endif
else
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(override_cred, override_cred->cap_permitted);
#else
override_cred->cap_effective =
override_cred->cap_permitted;
#endif
}
/*
@ -444,7 +464,11 @@ static const struct cred *access_override_creds(void)
* expecting RCU freeing. But normal thread-synchronous
* cred accesses will keep things non-RCY.
*/
#ifdef CONFIG_CREDP
iee_set_cred_non_rcu(override_cred, 1);
#else
override_cred->non_rcu = 1;
#endif
old_cred = override_creds(override_cred);

View File

@ -14,6 +14,9 @@
#include <linux/posix_acl_xattr.h>
#include <linux/atomic.h>
#include <linux/ratelimit.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "overlayfs.h"
static unsigned short ovl_redirect_max = 256;
@ -590,8 +593,13 @@ static int ovl_create_or_link(struct dentry *dentry, struct inode *inode,
* create a new inode, so just use the ovl mounter's
* fs{u,g}id.
*/
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(override_cred, inode->i_uid);
iee_set_cred_fsgid(override_cred, inode->i_gid);
#else
override_cred->fsuid = inode->i_uid;
override_cred->fsgid = inode->i_gid;
#endif
err = security_dentry_create_files_as(dentry,
attr->mode, &dentry->d_name, old_cred,
override_cred);

View File

@ -18,6 +18,9 @@
#include <linux/file.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "overlayfs.h"
#include "params.h"
@ -1490,7 +1493,16 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
sb->s_export_op = &ovl_export_fid_operations;
/* Never override disk quota limits or use reserved space */
#ifdef CONFIG_CREDP
{
kernel_cap_t tmp = cred->cap_effective;
cap_lower(tmp, CAP_SYS_RESOURCE);
iee_set_cred_cap_effective(cred, tmp);
}
#else
cap_lower(cred->cap_effective, CAP_SYS_RESOURCE);
#endif
sb->s_magic = OVERLAYFS_SUPER_MAGIC;
sb->s_xattr = ofs->config.userxattr ? ovl_user_xattr_handlers :

View File

@ -14,6 +14,9 @@
#include <linux/key-type.h>
#include <linux/keyctl.h>
#include <linux/inet.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "cifsglob.h"
#include "cifs_spnego.h"
#include "cifs_debug.h"
@ -214,8 +217,13 @@ init_cifs_spnego(void)
* the results it looks up
*/
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(cred, keyring);
iee_set_cred_jit_keyring(cred, KEY_REQKEY_DEFL_THREAD_KEYRING);
#else
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
#endif
spnego_cred = cred;
cifs_dbg(FYI, "cifs spnego keyring: %d\n", key_serial(keyring));

View File

@ -17,6 +17,9 @@
#include <linux/posix_acl.h>
#include <linux/posix_acl_xattr.h>
#include <keys/user-type.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "cifspdu.h"
#include "cifsglob.h"
#include "cifsacl.h"
@ -491,8 +494,13 @@ init_cifs_idmap(void)
/* instruct request_key() to use this special keyring as a cache for
* the results it looks up */
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(cred, keyring);
iee_set_cred_jit_keyring(cred, KEY_REQKEY_DEFL_THREAD_KEYRING);
#else
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
#endif
root_cred = cred;
cifs_dbg(FYI, "cifs idmap keyring: %d\n", key_serial(keyring));

View File

@ -1079,6 +1079,14 @@
* They will fit only a subset of the architectures
*/
#ifdef CONFIG_CREDP
#define CRED_DATA \
. = ALIGN(PAGE_SIZE); \
*(.iee.cred) \
. = ALIGN(PAGE_SIZE);
#else
#define CRED_DATA
#endif
/*
* Writeable data.
@ -1096,6 +1104,7 @@
. = ALIGN(PAGE_SIZE); \
.data : AT(ADDR(.data) - LOAD_OFFSET) { \
INIT_TASK_DATA(inittask) \
CRED_DATA \
NOSAVE_DATA \
PAGE_ALIGNED_DATA(pagealigned) \
CACHELINE_ALIGNED_DATA(cacheline) \

View File

@ -16,6 +16,10 @@
#include <linux/sched.h>
#include <linux/deepin_kabi.h>
#include <linux/sched/user.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/haoc-def.h>
extern unsigned long long iee_rw_gate(int flag, ...);
#endif
struct cred;
struct inode;
@ -176,6 +180,27 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
cred->cap_inheritable));
}
#ifdef CONFIG_CREDP
static void __maybe_unused iee_set_cred_non_rcu(struct cred *cred, int non_rcu)
{
if(!haoc_enabled)
{
cred->non_rcu = 0;
return;
}
iee_rw_gate(IEE_OP_SET_CRED_NON_RCU, cred, non_rcu);
*(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)) = non_rcu;
}
static bool __maybe_unused iee_set_cred_atomic_op_usage(struct cred *cred, int flag, int nr)
{
bool ret;
ret = iee_rw_gate(IEE_OP_SET_CRED_ATOP_USAGE, cred, flag, nr);
return ret;
}
#endif
/**
* get_new_cred - Get a reference on a new set of credentials
* @cred: The new credentials to reference
@ -185,7 +210,14 @@ static inline bool cap_ambient_invariant_ok(const struct cred *cred)
*/
static inline struct cred *get_new_cred(struct cred *cred)
{
#ifdef CONFIG_CREDP
if(haoc_enabled)
iee_set_cred_atomic_op_usage(cred, AT_ADD, 1);
else
atomic_long_inc(&cred->usage);
#else
atomic_long_inc(&cred->usage);
#endif
return cred;
}
@ -207,7 +239,11 @@ static inline const struct cred *get_cred(const struct cred *cred)
struct cred *nonconst_cred = (struct cred *) cred;
if (!cred)
return cred;
#ifdef CONFIG_CREDP
iee_set_cred_non_rcu(nonconst_cred, 0);
#else
nonconst_cred->non_rcu = 0;
#endif
return get_new_cred(nonconst_cred);
}
@ -216,9 +252,25 @@ static inline const struct cred *get_cred_rcu(const struct cred *cred)
struct cred *nonconst_cred = (struct cred *) cred;
if (!cred)
return NULL;
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
if (!iee_set_cred_atomic_op_usage(nonconst_cred, AT_INC_NOT_ZERO, 0))
return NULL;
}
else{
if (!atomic_long_inc_not_zero(&nonconst_cred->usage))
return NULL;
}
#else
if (!atomic_long_inc_not_zero(&nonconst_cred->usage))
return NULL;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_non_rcu(nonconst_cred, 0);
#else
nonconst_cred->non_rcu = 0;
#endif
return cred;
}
@ -238,8 +290,20 @@ static inline void put_cred(const struct cred *_cred)
struct cred *cred = (struct cred *) _cred;
if (cred) {
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
if (iee_set_cred_atomic_op_usage(cred, AT_SUB_AND_TEST, 1))
__put_cred(cred);
}
else{
if (atomic_long_dec_and_test(&(cred)->usage))
__put_cred(cred);
}
#else
if (atomic_long_dec_and_test(&(cred)->usage))
__put_cred(cred);
#endif
}
}

View File

@ -19,6 +19,10 @@
#include <linux/binfmts.h>
#include <linux/cn_proc.h>
#include <linux/uidgid.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#include <asm/haoc/iee-func.h>
#endif
#if 0
#define kdebug(FMT, ...) \
@ -33,7 +37,12 @@ do { \
} while (0)
#endif
#ifdef CONFIG_CREDP
struct kmem_cache *cred_jar;
static struct kmem_cache *rcu_jar;
#else
static struct kmem_cache *cred_jar;
#endif
/* init to 2 - one for init_task, one to ensure it is never freed */
static struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
@ -41,6 +50,32 @@ static struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
/*
* The initial credentials for the initial task
*/
#ifdef CONFIG_CREDP
struct cred init_cred __section(".iee.cred") = {
.usage = ATOMIC_INIT(4),
#ifdef CONFIG_DEBUG_CREDENTIALS
.subscribers = ATOMIC_INIT(2),
.magic = CRED_MAGIC,
#endif
.uid = GLOBAL_ROOT_UID,
.gid = GLOBAL_ROOT_GID,
.suid = GLOBAL_ROOT_UID,
.sgid = GLOBAL_ROOT_GID,
.euid = GLOBAL_ROOT_UID,
.egid = GLOBAL_ROOT_GID,
.fsuid = GLOBAL_ROOT_UID,
.fsgid = GLOBAL_ROOT_GID,
.securebits = SECUREBITS_DEFAULT,
.cap_inheritable = CAP_EMPTY_SET,
.cap_permitted = CAP_FULL_SET,
.cap_effective = CAP_FULL_SET,
.cap_bset = CAP_FULL_SET,
.user = INIT_USER,
.user_ns = &init_user_ns,
.group_info = &init_groups,
.ucounts = &init_ucounts,
};
#else
struct cred init_cred = {
.usage = ATOMIC_INIT(4),
.uid = GLOBAL_ROOT_UID,
@ -61,13 +96,22 @@ struct cred init_cred = {
.group_info = &init_groups,
.ucounts = &init_ucounts,
};
#endif
/*
* The RCU callback to actually dispose of a set of credentials
*/
static void put_cred_rcu(struct rcu_head *rcu)
{
#ifdef CONFIG_CREDP
struct cred *cred = NULL;
if(haoc_enabled)
cred = *(struct cred **)(rcu + 1);
else
cred = container_of(rcu, struct cred, rcu);
#else
struct cred *cred = container_of(rcu, struct cred, rcu);
#endif
kdebug("put_cred_rcu(%p)", cred);
@ -86,6 +130,12 @@ static void put_cred_rcu(struct rcu_head *rcu)
if (cred->ucounts)
put_ucounts(cred->ucounts);
put_user_ns(cred->user_ns);
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
kmem_cache_free(rcu_jar, (struct rcu_head *)(cred->rcu.func));
}
#endif
kmem_cache_free(cred_jar, cred);
}
@ -104,10 +154,26 @@ void __put_cred(struct cred *cred)
BUG_ON(cred == current->cred);
BUG_ON(cred == current->real_cred);
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
if (*(int *)(&(((struct rcu_head *)(cred->rcu.func))->next)))
put_cred_rcu((struct rcu_head *)(cred->rcu.func));
else
call_rcu((struct rcu_head *)(cred->rcu.func), put_cred_rcu);
}
else{
if (cred->non_rcu)
put_cred_rcu(&cred->rcu);
else
call_rcu(&cred->rcu, put_cred_rcu);
}
#else
if (cred->non_rcu)
put_cred_rcu(&cred->rcu);
else
call_rcu(&cred->rcu, put_cred_rcu);
#endif
}
EXPORT_SYMBOL(__put_cred);
@ -173,7 +239,21 @@ struct cred *cred_alloc_blank(void)
if (!new)
return NULL;
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
iee_set_cred_rcu(new, kmem_cache_zalloc(rcu_jar, GFP_KERNEL));
*(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new;
}
iee_set_cred_atomic_set_usage(new, 1);
#else
atomic_long_set(&new->usage, 1);
#ifdef CONFIG_DEBUG_CREDENTIALS
new->magic = CRED_MAGIC;
#endif
#endif
if (security_cred_alloc_blank(new, GFP_KERNEL_ACCOUNT) < 0)
goto error;
@ -208,13 +288,27 @@ struct cred *prepare_creds(void)
if (!new)
return NULL;
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
iee_set_cred_rcu(new, kmem_cache_alloc(rcu_jar, GFP_KERNEL));
*(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new;
}
#endif
kdebug("prepare_creds() alloc %p", new);
old = task->cred;
#ifdef CONFIG_CREDP
iee_copy_cred(old, new);
iee_set_cred_non_rcu(new, 0);
iee_set_cred_atomic_set_usage(new, 1);
#else
memcpy(new, old, sizeof(struct cred));
new->non_rcu = 0;
atomic_long_set(&new->usage, 1);
#endif
get_group_info(new->group_info);
get_uid(new->user);
get_user_ns(new->user_ns);
@ -227,10 +321,18 @@ struct cred *prepare_creds(void)
#endif
#ifdef CONFIG_SECURITY
#ifdef CONFIG_CREDP
iee_set_cred_security(new, NULL);
#else
new->security = NULL;
#endif
#endif
#ifdef CONFIG_CREDP
iee_set_cred_ucounts(new, get_ucounts(new->ucounts));
#else
new->ucounts = get_ucounts(new->ucounts);
#endif
if (!new->ucounts)
goto error;
@ -260,15 +362,30 @@ struct cred *prepare_exec_creds(void)
#ifdef CONFIG_KEYS
/* newly exec'd tasks don't get a thread keyring */
key_put(new->thread_keyring);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(new, NULL);
#else
new->thread_keyring = NULL;
#endif
/* inherit the session keyring; new process keyring */
key_put(new->process_keyring);
#ifdef CONFIG_CREDP
iee_set_cred_process_keyring(new, NULL);
#else
new->process_keyring = NULL;
#endif
#endif
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, new->euid);
iee_set_cred_suid(new, new->euid);
iee_set_cred_fsgid(new, new->egid);
iee_set_cred_sgid(new, new->egid);
#else
new->suid = new->fsuid = new->euid;
new->sgid = new->fsgid = new->egid;
#endif
return new;
}
@ -323,7 +440,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
* had one */
if (new->thread_keyring) {
key_put(new->thread_keyring);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(new, NULL);
#else
new->thread_keyring = NULL;
#endif
if (clone_flags & CLONE_THREAD)
install_thread_keyring_to_cred(new);
}
@ -333,7 +454,11 @@ int copy_creds(struct task_struct *p, unsigned long clone_flags)
*/
if (!(clone_flags & CLONE_THREAD)) {
key_put(new->process_keyring);
#ifdef CONFIG_CREDP
iee_set_cred_process_keyring(new, NULL);
#else
new->process_keyring = NULL;
#endif
}
#endif
@ -591,7 +716,11 @@ int set_cred_ucounts(struct cred *new)
if (!(new_ucounts = alloc_ucounts(new->user_ns, new->uid)))
return -EAGAIN;
#ifdef CONFIG_CREDP
iee_set_cred_ucounts(new, new_ucounts);
#else
new->ucounts = new_ucounts;
#endif
put_ucounts(old_ucounts);
return 0;
@ -603,8 +732,23 @@ int set_cred_ucounts(struct cred *new)
void __init cred_init(void)
{
/* allocate a slab in which we can store credentials */
#ifdef CONFIG_CREDP
cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);
rcu_jar = kmem_cache_create("rcu_jar", sizeof(struct rcu_head) + sizeof(struct cred *), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);
if(haoc_enabled)
{
// Map init_cred
*((struct rcu_head **)(&(init_cred.rcu.func))) =
(struct rcu_head *)kmem_cache_zalloc(rcu_jar, GFP_KERNEL);
*(struct cred **)(((struct rcu_head *)(init_cred.rcu.func)) + 1) = &init_cred;
}
#else
cred_jar = kmem_cache_create("cred_jar", sizeof(struct cred), 0,
SLAB_HWCACHE_ALIGN|SLAB_PANIC|SLAB_ACCOUNT, NULL);
#endif
}
/**
@ -635,29 +779,59 @@ struct cred *prepare_kernel_cred(struct task_struct *daemon)
if (!new)
return NULL;
#ifdef CONFIG_CREDP
if(haoc_enabled)
{
iee_set_cred_rcu(new, kmem_cache_alloc(rcu_jar, GFP_KERNEL));
*(struct cred **)(((struct rcu_head *)(new->rcu.func)) + 1) = new;
}
#endif
kdebug("prepare_kernel_cred() alloc %p", new);
old = get_task_cred(daemon);
#ifdef CONFIG_CREDP
iee_copy_cred(old, new);
iee_set_cred_non_rcu(new, 0);
iee_set_cred_atomic_set_usage(new, 1);
#else
*new = *old;
new->non_rcu = 0;
atomic_long_set(&new->usage, 1);
#endif
get_uid(new->user);
get_user_ns(new->user_ns);
get_group_info(new->group_info);
#ifdef CONFIG_KEYS
#ifdef CONFIG_CREDP
iee_set_cred_session_keyring(new, NULL);
iee_set_cred_process_keyring(new, NULL);
iee_set_cred_thread_keyring(new, NULL);
iee_set_cred_request_key_auth(new, NULL);
iee_set_cred_jit_keyring(new, KEY_REQKEY_DEFL_THREAD_KEYRING);
#else
new->session_keyring = NULL;
new->process_keyring = NULL;
new->thread_keyring = NULL;
new->request_key_auth = NULL;
new->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
#endif
#endif
#ifdef CONFIG_SECURITY
#ifdef CONFIG_CREDP
iee_set_cred_security(new, NULL);
#else
new->security = NULL;
#endif
#endif
#ifdef CONFIG_CREDP
iee_set_cred_ucounts(new, get_ucounts(new->ucounts));
#else
new->ucounts = get_ucounts(new->ucounts);
#endif
if (!new->ucounts)
goto error;
@ -724,8 +898,13 @@ int set_create_files_as(struct cred *new, struct inode *inode)
{
if (!uid_valid(inode->i_uid) || !gid_valid(inode->i_gid))
return -EINVAL;
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, inode->i_uid);
iee_set_cred_fsgid(new, inode->i_gid);
#else
new->fsuid = inode->i_uid;
new->fsgid = inode->i_gid;
#endif
return security_kernel_create_files_as(new, inode);
}
EXPORT_SYMBOL(set_create_files_as);

View File

@ -11,6 +11,9 @@
#include <linux/user_namespace.h>
#include <linux/vmalloc.h>
#include <linux/uaccess.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
struct group_info *groups_alloc(int gidsetsize)
{
@ -119,7 +122,11 @@ void set_groups(struct cred *new, struct group_info *group_info)
{
put_group_info(new->group_info);
get_group_info(group_info);
#ifdef CONFIG_CREDP
iee_set_cred_group_info(new, group_info);
#else
new->group_info = group_info;
#endif
}
EXPORT_SYMBOL(set_groups);

View File

@ -74,6 +74,9 @@
#include <linux/uaccess.h>
#include <asm/io.h>
#include <asm/unistd.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "uid16.h"
@ -395,7 +398,11 @@ long __sys_setregid(gid_t rgid, gid_t egid)
if (gid_eq(old->gid, krgid) ||
gid_eq(old->egid, krgid) ||
ns_capable_setid(old->user_ns, CAP_SETGID))
#ifdef CONFIG_CREDP
iee_set_cred_gid(new, krgid);
#else
new->gid = krgid;
#endif
else
goto error;
}
@ -404,15 +411,27 @@ long __sys_setregid(gid_t rgid, gid_t egid)
gid_eq(old->egid, kegid) ||
gid_eq(old->sgid, kegid) ||
ns_capable_setid(old->user_ns, CAP_SETGID))
#ifdef CONFIG_CREDP
iee_set_cred_egid(new, kegid);
#else
new->egid = kegid;
#endif
else
goto error;
}
if (rgid != (gid_t) -1 ||
(egid != (gid_t) -1 && !gid_eq(kegid, old->gid)))
#ifdef CONFIG_CREDP
iee_set_cred_sgid(new, new->egid);
#else
new->sgid = new->egid;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_fsgid(new, new->egid);
#else
new->fsgid = new->egid;
#endif
retval = security_task_fix_setgid(new, old, LSM_SETID_RE);
if (retval < 0)
@ -454,9 +473,25 @@ long __sys_setgid(gid_t gid)
retval = -EPERM;
if (ns_capable_setid(old->user_ns, CAP_SETGID))
#ifdef CONFIG_CREDP
{
iee_set_cred_fsgid(new, kgid);
iee_set_cred_sgid(new, kgid);
iee_set_cred_egid(new, kgid);
iee_set_cred_gid(new, kgid);
}
#else
new->gid = new->egid = new->sgid = new->fsgid = kgid;
#endif
else if (gid_eq(kgid, old->gid) || gid_eq(kgid, old->sgid))
#ifdef CONFIG_CREDP
{
iee_set_cred_fsgid(new, kgid);
iee_set_cred_egid(new, kgid);
}
#else
new->egid = new->fsgid = kgid;
#endif
else
goto error;
@ -488,7 +523,11 @@ static int set_user(struct cred *new)
return -EAGAIN;
free_uid(new->user);
#ifdef CONFIG_CREDP
iee_set_cred_user(new, new_user);
#else
new->user = new_user;
#endif
return 0;
}
@ -549,7 +588,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
retval = -EPERM;
if (ruid != (uid_t) -1) {
#ifdef CONFIG_CREDP
iee_set_cred_uid(new, kruid);
#else
new->uid = kruid;
#endif
if (!uid_eq(old->uid, kruid) &&
!uid_eq(old->euid, kruid) &&
!ns_capable_setid(old->user_ns, CAP_SETUID))
@ -557,7 +600,11 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
}
if (euid != (uid_t) -1) {
#ifdef CONFIG_CREDP
iee_set_cred_euid(new, keuid);
#else
new->euid = keuid;
#endif
if (!uid_eq(old->uid, keuid) &&
!uid_eq(old->euid, keuid) &&
!uid_eq(old->suid, keuid) &&
@ -572,8 +619,16 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
}
if (ruid != (uid_t) -1 ||
(euid != (uid_t) -1 && !uid_eq(keuid, old->uid)))
#ifdef CONFIG_CREDP
iee_set_cred_suid(new, new->euid);
#else
new->suid = new->euid;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, new->euid);
#else
new->fsuid = new->euid;
#endif
retval = security_task_fix_setuid(new, old, LSM_SETID_RE);
if (retval < 0)
@ -626,7 +681,12 @@ long __sys_setuid(uid_t uid)
retval = -EPERM;
if (ns_capable_setid(old->user_ns, CAP_SETUID)) {
#ifdef CONFIG_CREDP
iee_set_cred_uid(new, kuid);
iee_set_cred_suid(new, kuid);
#else
new->suid = new->uid = kuid;
#endif
if (!uid_eq(kuid, old->uid)) {
retval = set_user(new);
if (retval < 0)
@ -636,7 +696,12 @@ long __sys_setuid(uid_t uid)
goto error;
}
#ifdef CONFIG_CREDP
iee_set_cred_euid(new, kuid);
iee_set_cred_fsuid(new, kuid);
#else
new->fsuid = new->euid = kuid;
#endif
retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
if (retval < 0)
@ -710,7 +775,11 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
return -ENOMEM;
if (ruid != (uid_t) -1) {
#ifdef CONFIG_CREDP
iee_set_cred_uid(new, kruid);
#else
new->uid = kruid;
#endif
if (!uid_eq(kruid, old->uid)) {
retval = set_user(new);
if (retval < 0)
@ -718,10 +787,22 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
}
}
if (euid != (uid_t) -1)
#ifdef CONFIG_CREDP
iee_set_cred_euid(new, keuid);
#else
new->euid = keuid;
#endif
if (suid != (uid_t) -1)
#ifdef CONFIG_CREDP
iee_set_cred_suid(new, ksuid);
#else
new->suid = ksuid;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, new->euid);
#else
new->fsuid = new->euid;
#endif
retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
if (retval < 0)
@ -810,12 +891,28 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
return -ENOMEM;
if (rgid != (gid_t) -1)
#ifdef CONFIG_CREDP
iee_set_cred_gid(new, krgid);
#else
new->gid = krgid;
#endif
if (egid != (gid_t) -1)
#ifdef CONFIG_CREDP
iee_set_cred_egid(new, kegid);
#else
new->egid = kegid;
#endif
if (sgid != (gid_t) -1)
#ifdef CONFIG_CREDP
iee_set_cred_sgid(new, ksgid);
#else
new->sgid = ksgid;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_fsgid(new, new->egid);
#else
new->fsgid = new->egid;
#endif
retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
if (retval < 0)
@ -882,7 +979,11 @@ long __sys_setfsuid(uid_t uid)
uid_eq(kuid, old->suid) || uid_eq(kuid, old->fsuid) ||
ns_capable_setid(old->user_ns, CAP_SETUID)) {
if (!uid_eq(kuid, old->fsuid)) {
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, kuid);
#else
new->fsuid = kuid;
#endif
if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
goto change_okay;
}
@ -926,7 +1027,11 @@ long __sys_setfsgid(gid_t gid)
gid_eq(kgid, old->sgid) || gid_eq(kgid, old->fsgid) ||
ns_capable_setid(old->user_ns, CAP_SETGID)) {
if (!gid_eq(kgid, old->fsgid)) {
#ifdef CONFIG_CREDP
iee_set_cred_fsgid(new, kgid);
#else
new->fsgid = kgid;
#endif
if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
goto change_okay;
}

View File

@ -31,6 +31,9 @@
#include <linux/freezer.h>
#include <trace/events/module.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
@ -91,9 +94,15 @@ static int call_usermodehelper_exec_async(void *data)
goto out;
spin_lock(&umh_sysctl_lock);
#ifdef CONFIG_CREDP
iee_set_cred_cap_bset(new, cap_intersect(usermodehelper_bset, new->cap_bset));
iee_set_cred_cap_inheritable(new, cap_intersect(usermodehelper_inheritable,
new->cap_inheritable));
#else
new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
new->cap_inheritable = cap_intersect(usermodehelper_inheritable,
new->cap_inheritable);
#endif
spin_unlock(&umh_sysctl_lock);
if (sub_info->init) {

View File

@ -21,6 +21,9 @@
#include <linux/fs_struct.h>
#include <linux/bsearch.h>
#include <linux/sort.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
static struct kmem_cache *user_ns_cachep __ro_after_init;
static DEFINE_MUTEX(userns_state_mutex);
@ -45,6 +48,19 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
/* Start with the same capabilities as init but useless for doing
* anything as the capabilities are bound to the new user namespace.
*/
#ifdef CONFIG_CREDP
iee_set_cred_securebits(cred, SECUREBITS_DEFAULT);
iee_set_cred_cap_inheritable(cred, CAP_EMPTY_SET);
iee_set_cred_cap_permitted(cred, CAP_FULL_SET);
iee_set_cred_cap_effective(cred, CAP_FULL_SET);
iee_set_cred_cap_ambient(cred, CAP_EMPTY_SET);
iee_set_cred_cap_bset(cred, CAP_FULL_SET);
#ifdef CONFIG_KEYS
key_put(cred->request_key_auth);
iee_set_cred_request_key_auth(cred, NULL);
#endif
iee_set_cred_user_ns(cred, user_ns);
#else
cred->securebits = SECUREBITS_DEFAULT;
cred->cap_inheritable = CAP_EMPTY_SET;
cred->cap_permitted = CAP_FULL_SET;
@ -57,6 +73,7 @@ static void set_cred_user_ns(struct cred *cred, struct user_namespace *user_ns)
#endif
/* tgcred will be cleared in our caller bc CLONE_THREAD won't be set */
cred->user_ns = user_ns;
#endif
}
static unsigned long enforced_nproc_rlimit(void)

View File

@ -25,6 +25,9 @@ typedef u64 freelist_full_t;
#if defined(system_has_freelist_aba) && !defined(CONFIG_HAVE_ALIGNED_STRUCT_PAGE)
#undef system_has_freelist_aba
#endif
#ifdef CONFIG_CREDP
extern struct kmem_cache *cred_jar;
#endif
/*
* Freelist pointer and counter to cmpxchg together, avoids the typical ABA
@ -721,7 +724,9 @@ static inline struct kmem_cache *slab_pre_alloc_hook(struct kmem_cache *s,
return s;
}
#ifdef CONFIG_CREDP
#include<asm/haoc/iee-access.h>
#endif
static inline void slab_post_alloc_hook(struct kmem_cache *s,
struct obj_cgroup *objcg, gfp_t flags,
size_t size, void **p, bool init,
@ -766,7 +771,16 @@ static inline void slab_post_alloc_hook(struct kmem_cache *s,
for (i = 0; i < size; i++) {
p[i] = kasan_slab_alloc(s, p[i], flags, kasan_init);
if (p[i] && init && (!kasan_init || !kasan_has_integrated_init()))
{
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar)
iee_memset(p[i], 0, zero_size);
else
memset(p[i], 0, zero_size);
#else
memset(p[i], 0, zero_size);
#endif
}
kmemleak_alloc_recursive(p[i], s->object_size, 1,
s->flags, flags);
kmsan_slab_alloc(s, p[i], flags);

107
mm/slub.c
View File

@ -50,6 +50,9 @@
#ifdef CONFIG_IEE_PTRP
#include <asm/haoc/iee-token.h>
#endif
#if defined(CONFIG_CREDP)
#include <asm/haoc/iee-access.h>
#endif
#include "internal.h"
@ -465,6 +468,13 @@ static inline void set_freepointer(struct kmem_cache *s, void *object, void *fp)
#endif
freeptr_addr = (unsigned long)kasan_reset_tag((void *)freeptr_addr);
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar) {
iee_set_freeptr((void **)freeptr_addr,
(void *)(freelist_ptr_encode(s, fp, freeptr_addr).v));
return;
}
#endif
*(freeptr_t *)freeptr_addr = freelist_ptr_encode(s, fp, freeptr_addr);
}
@ -811,6 +821,29 @@ static void set_track_update(struct kmem_cache *s, void *object,
{
struct track *p = get_track(s, object, alloc);
#ifdef CONFIG_CREDP
struct track tmp;
if (haoc_enabled && s == cred_jar) {
tmp = *p;
#ifdef CONFIG_STACKDEPOT
tmp.handle = handle;
#endif
tmp.addr = addr;
tmp.cpu = smp_processor_id();
tmp.pid = current->pid;
tmp.when = jiffies;
iee_memcpy(p, &tmp, sizeof(struct track));
} else {
#ifdef CONFIG_STACKDEPOT
p->handle = handle;
#endif
p->addr = addr;
p->cpu = smp_processor_id();
p->pid = current->pid;
p->when = jiffies;
}
#else
#ifdef CONFIG_STACKDEPOT
p->handle = handle;
#endif
@ -818,6 +851,7 @@ static void set_track_update(struct kmem_cache *s, void *object,
p->cpu = smp_processor_id();
p->pid = current->pid;
p->when = jiffies;
#endif
}
static __always_inline void set_track(struct kmem_cache *s, void *object,
@ -836,7 +870,14 @@ static void init_tracking(struct kmem_cache *s, void *object)
return;
p = get_track(s, object, TRACK_ALLOC);
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar)
iee_memset(p, 0, 2*sizeof(struct track));
else
memset(p, 0, 2*sizeof(struct track));
#else
memset(p, 0, 2*sizeof(struct track));
#endif
}
static void print_track(const char *s, struct track *t, unsigned long pr_time)
@ -1046,7 +1087,14 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
unsigned int poison_size = s->object_size;
if (s->flags & SLAB_RED_ZONE) {
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar)
iee_memset(p - s->red_left_pad, val, s->red_left_pad);
else
memset(p - s->red_left_pad, val, s->red_left_pad);
#else
memset(p - s->red_left_pad, val, s->red_left_pad);
#endif
if (slub_debug_orig_size(s) && val == SLUB_RED_ACTIVE) {
/*
@ -1059,12 +1107,31 @@ static void init_object(struct kmem_cache *s, void *object, u8 val)
}
if (s->flags & __OBJECT_POISON) {
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar) {
iee_memset(p, POISON_FREE, poison_size - 1);
iee_memset(&p[poison_size - 1], POISON_END, 1);
} else {
memset(p, POISON_FREE, poison_size - 1);
p[poison_size - 1] = POISON_END;
}
#else
memset(p, POISON_FREE, poison_size - 1);
#endif
p[poison_size - 1] = POISON_END;
}
if (s->flags & SLAB_RED_ZONE)
#ifdef CONFIG_CREDP
{
if (haoc_enabled && s == cred_jar)
iee_memset(p + poison_size, val, s->inuse - poison_size);
else
memset(p + poison_size, val, s->inuse - poison_size);
}
#else
memset(p + poison_size, val, s->inuse - poison_size);
#endif
}
static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
@ -1439,7 +1506,14 @@ void setup_slab_debug(struct kmem_cache *s, struct slab *slab, void *addr)
return;
metadata_access_enable();
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar)
iee_memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab));
else
memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab));
#else
memset(kasan_reset_tag(addr), POISON_INUSE, slab_size(slab));
#endif
metadata_access_disable();
}
@ -2065,6 +2139,11 @@ static struct slab *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
#ifdef CONFIG_IEE
if(haoc_enabled)
iee_allocate_slab_data(s, slab, oo_order(oo));
#endif
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar)
set_iee_page((unsigned long)page_address(folio_page(slab_folio(slab), 0)),
oo_order(oo));
#endif
account_slab(slab, oo_order(oo), s, flags);
@ -2124,6 +2203,16 @@ static void __free_slab(struct kmem_cache *s, struct slab *slab)
if (iee_free_slab_data(s, slab, order))
return;
}
#endif
#ifdef CONFIG_CREDP
if (haoc_enabled && s == cred_jar) {
#ifdef CONFIG_X86_64
iee_free_slab(s, slab, iee_free_cred_slab);
return;
#else
unset_iee_page((unsigned long)page_address(folio_page(folio, 0)), order);
#endif
}
#endif
__free_pages(&folio->page, order);
}
@ -3503,10 +3592,17 @@ static __fastpath_inline void *slab_alloc_node(struct kmem_cache *s, struct list
if (!s)
return NULL;
#ifdef CONFIG_CREDP
if(haoc_enabled)
goto slab_alloc;
#endif
object = kfence_alloc(s, orig_size, gfpflags);
if (unlikely(object))
goto out;
#ifdef CONFIG_CREDP
slab_alloc:
#endif
object = __slab_alloc_node(s, gfpflags, node, addr, orig_size);
maybe_wipe_obj_freeptr(s, object);
@ -3989,6 +4085,11 @@ static inline int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags,
local_lock_irqsave(&s->cpu_slab->lock, irqflags);
for (i = 0; i < size; i++) {
#ifdef CONFIG_CREDP
/* Skip kfence_alloc for iee kmem caches. */
if(haoc_enabled)
goto slab_alloc;
#endif
void *object = kfence_alloc(s, s->object_size, flags);
if (unlikely(object)) {
@ -3996,6 +4097,9 @@ static inline int __kmem_cache_alloc_bulk(struct kmem_cache *s, gfp_t flags,
continue;
}
#ifdef CONFIG_CREDP
slab_alloc:
#endif
object = c->freelist;
if (unlikely(!object)) {
/*
@ -4523,8 +4627,7 @@ static int calculate_sizes(struct kmem_cache *s)
s->reciprocal_size = reciprocal_value(size);
order = calculate_order(size);
#ifdef CONFIG_IEE
if(haoc_enabled)
order = iee_calculate_order(s, order);
order = iee_calculate_order(s, order);
#endif
if ((int)order < 0)
return 0;

View File

@ -32,6 +32,9 @@
#include <linux/dns_resolver.h>
#include <keys/dns_resolver-type.h>
#include <keys/user-type.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "internal.h"
MODULE_DESCRIPTION("DNS Resolver");
@ -365,8 +368,13 @@ static int __init init_dns_resolver(void)
/* instruct request_key() to use this special keyring as a cache for
* the results it looks up */
set_bit(KEY_FLAG_ROOT_CAN_CLEAR, &keyring->flags);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(cred, keyring);
iee_set_cred_jit_keyring(cred, KEY_REQKEY_DEFL_THREAD_KEYRING);
#else
cred->thread_keyring = keyring;
cred->jit_keyring = KEY_REQKEY_DEFL_THREAD_KEYRING;
#endif
dns_resolver_cache = cred;
kdebug("DNS resolver keyring: %d\n", key_serial(keyring));

View File

@ -38,9 +38,13 @@ static const struct rpc_authops __rcu *auth_flavors[RPC_AUTH_MAXFLAVOR] = {
static LIST_HEAD(cred_unused);
static unsigned long number_cred_unused;
#ifdef CONFIG_CREDP
static struct cred *machine_cred;
#else
static struct cred machine_cred = {
.usage = ATOMIC_INIT(1),
};
#endif
/*
* Return the machine_cred pointer to be used whenever
@ -48,7 +52,11 @@ static struct cred machine_cred = {
*/
const struct cred *rpc_machine_cred(void)
{
#ifdef CONFIG_CREDP
return machine_cred;
#else
return &machine_cred;
#endif
}
EXPORT_SYMBOL_GPL(rpc_machine_cred);
@ -659,15 +667,27 @@ rpcauth_bindcred(struct rpc_task *task, const struct cred *cred, int flags)
if (task->tk_op_cred)
/* Task must use exactly this rpc_cred */
new = get_rpccred(task->tk_op_cred);
#ifdef CONFIG_CREDP
else if (cred && cred != machine_cred)
#else
else if (cred != NULL && cred != &machine_cred)
#endif
new = auth->au_ops->lookup_cred(auth, &acred, lookupflags);
#ifdef CONFIG_CREDP
else if (cred == machine_cred)
#else
else if (cred == &machine_cred)
#endif
new = rpcauth_bind_machine_cred(task, lookupflags);
/* If machine cred couldn't be bound, try a root cred */
if (new)
;
#ifdef CONFIG_CREDP
else if (cred == machine_cred)
#else
else if (cred == &machine_cred)
#endif
new = rpcauth_bind_root_cred(task, lookupflags);
else if (flags & RPC_TASK_NULLCREDS)
new = authnull_ops.lookup_cred(NULL, NULL, 0);
@ -871,6 +891,11 @@ static struct shrinker rpc_cred_shrinker = {
int __init rpcauth_init_module(void)
{
#ifdef CONFIG_CREDP
machine_cred = prepare_creds();
if (!machine_cred)
panic("RPCAUTH: fail to allocate machine_cred");
#endif
int err;
err = rpc_init_authunix();
@ -888,6 +913,9 @@ out1:
void rpcauth_remove_module(void)
{
#ifdef CONFIG_CREDP
abort_creds(machine_cred);
#endif
rpc_destroy_authunix();
unregister_shrinker(&rpc_cred_shrinker);
}

View File

@ -25,6 +25,9 @@
#include <linux/binfmts.h>
#include <linux/personality.h>
#include <linux/mnt_idmapping.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
/*
* If a non-root user executes a setuid-root binary in
@ -265,7 +268,14 @@ int cap_capset(struct cred *new,
/* verify the _new_Effective_ is a subset of the _new_Permitted_ */
if (!cap_issubset(*effective, *permitted))
return -EPERM;
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, *effective);
iee_set_cred_cap_inheritable(new, *inheritable);
iee_set_cred_cap_permitted(new, *permitted);
iee_set_cred_cap_ambient(new, cap_intersect(new->cap_ambient,
cap_intersect(*permitted, *inheritable)));
#else
new->cap_effective = *effective;
new->cap_inheritable = *inheritable;
new->cap_permitted = *permitted;
@ -277,6 +287,7 @@ int cap_capset(struct cred *new,
new->cap_ambient = cap_intersect(new->cap_ambient,
cap_intersect(*permitted,
*inheritable));
#endif
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EINVAL;
return 0;
@ -601,9 +612,17 @@ static inline int bprm_caps_from_vfs_caps(struct cpu_vfs_cap_data *caps,
* pP' = (X & fP) | (pI & fI)
* The addition of pA' is handled later.
*/
#ifdef CONFIG_CREDP
kernel_cap_t temp = new->cap_permitted;
temp.val = (new->cap_bset.val & caps->permitted.val) |
(new->cap_inheritable.val & caps->inheritable.val);
iee_set_cred_cap_permitted(new, temp);
#else
new->cap_permitted.val =
(new->cap_bset.val & caps->permitted.val) |
(new->cap_inheritable.val & caps->inheritable.val);
#endif
if (caps->permitted.val & ~new->cap_permitted.val)
/* insufficient to execute correctly */
@ -726,7 +745,16 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file,
int rc = 0;
struct cpu_vfs_cap_data vcaps;
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = bprm->cred->cap_permitted;
tmp_cap.val = 0;
iee_set_cred_cap_permitted(bprm->cred, tmp_cap);
} while (0);
#else
cap_clear(bprm->cred->cap_permitted);
#endif
if (!file_caps_enabled)
return 0;
@ -757,7 +785,16 @@ static int get_file_caps(struct linux_binprm *bprm, struct file *file,
out:
if (rc)
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = bprm->cred->cap_permitted;
tmp_cap.val = 0;
iee_set_cred_cap_permitted(bprm->cred, tmp_cap);
} while (0);
#else
cap_clear(bprm->cred->cap_permitted);
#endif
return rc;
}
@ -809,8 +846,13 @@ static void handle_privileged_root(struct linux_binprm *bprm, bool has_fcap,
*/
if (__is_eff(root_uid, new) || __is_real(root_uid, new)) {
/* pP' = (cap_bset & ~0) | (pI & ~0) */
#ifdef CONFIG_CREDP
iee_set_cred_cap_permitted(new, cap_combine(old->cap_bset,
old->cap_inheritable));
#else
new->cap_permitted = cap_combine(old->cap_bset,
old->cap_inheritable);
#endif
}
/*
* If only the real uid is 0, we do not set the effective bit.
@ -919,34 +961,73 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
/* downgrade; they get no more than they had, and maybe less */
if (!ns_capable(new->user_ns, CAP_SETUID) ||
(bprm->unsafe & LSM_UNSAFE_NO_NEW_PRIVS)) {
#ifdef CONFIG_CREDP
iee_set_cred_euid(new, new->uid);
iee_set_cred_egid(new, new->gid);
#else
new->euid = new->uid;
new->egid = new->gid;
#endif
}
#ifdef CONFIG_CREDP
iee_set_cred_cap_permitted(new, cap_intersect(new->cap_permitted,
old->cap_permitted));
#else
new->cap_permitted = cap_intersect(new->cap_permitted,
old->cap_permitted);
#endif
}
#ifdef CONFIG_CREDP
iee_set_cred_fsuid(new, new->euid);
iee_set_cred_suid(new, new->euid);
iee_set_cred_fsgid(new, new->egid);
iee_set_cred_sgid(new, new->egid);
#else
new->suid = new->fsuid = new->euid;
new->sgid = new->fsgid = new->egid;
#endif
/* File caps or setid cancels ambient. */
if (has_fcap || is_setid)
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = new->cap_ambient;
tmp_cap.val = 0;
iee_set_cred_cap_ambient(new, tmp_cap);
} while (0);
#else
cap_clear(new->cap_ambient);
#endif
/*
* Now that we've computed pA', update pP' to give:
* pP' = (X & fP) | (pI & fI) | pA'
*/
#ifdef CONFIG_CREDP
iee_set_cred_cap_permitted(new,
cap_combine(new->cap_permitted, new->cap_ambient));
#else
new->cap_permitted = cap_combine(new->cap_permitted, new->cap_ambient);
#endif
/*
* Set pE' = (fE ? pP' : pA'). Because pA' is zero if fE is set,
* this is the same as pE' = (fE ? pP' : 0) | pA'.
*/
if (effective)
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, new->cap_permitted);
#else
new->cap_effective = new->cap_permitted;
#endif
else
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, new->cap_ambient);
#else
new->cap_effective = new->cap_ambient;
#endif
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EPERM;
@ -957,7 +1038,12 @@ int cap_bprm_creds_from_file(struct linux_binprm *bprm, struct file *file)
return ret;
}
#ifdef CONFIG_CREDP
iee_set_cred_securebits(new,
new->securebits & ~issecure_mask(SECURE_KEEP_CAPS));
#else
new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
#endif
if (WARN_ON(!cap_ambient_invariant_ok(new)))
return -EPERM;
@ -1092,8 +1178,17 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old)
!uid_eq(new->euid, root_uid) &&
!uid_eq(new->suid, root_uid))) {
if (!issecure(SECURE_KEEP_CAPS)) {
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = new->cap_permitted;
tmp_cap.val = 0;
iee_set_cred_cap_permitted(new, tmp_cap);
} while (0);
#else
cap_clear(new->cap_permitted);
cap_clear(new->cap_effective);
#endif
}
/*
@ -1101,12 +1196,34 @@ static inline void cap_emulate_setxuid(struct cred *new, const struct cred *old)
* by exec to drop capabilities. We should make sure that
* this remains the case.
*/
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = new->cap_ambient;
tmp_cap.val = 0;
iee_set_cred_cap_ambient(new, tmp_cap);
} while (0);
#else
cap_clear(new->cap_ambient);
#endif
}
if (uid_eq(old->euid, root_uid) && !uid_eq(new->euid, root_uid))
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = new->cap_effective;
tmp_cap.val = 0;
iee_set_cred_cap_effective(new, tmp_cap);
} while (0);
#else
cap_clear(new->cap_effective);
#endif
if (!uid_eq(old->euid, root_uid) && uid_eq(new->euid, root_uid))
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, new->cap_permitted);
#else
new->cap_effective = new->cap_permitted;
#endif
}
/**
@ -1142,13 +1259,23 @@ int cap_task_fix_setuid(struct cred *new, const struct cred *old, int flags)
if (!issecure(SECURE_NO_SETUID_FIXUP)) {
kuid_t root_uid = make_kuid(old->user_ns, 0);
if (uid_eq(old->fsuid, root_uid) && !uid_eq(new->fsuid, root_uid))
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new,
cap_drop_fs_set(new->cap_effective));
#else
new->cap_effective =
cap_drop_fs_set(new->cap_effective);
#endif
if (!uid_eq(old->fsuid, root_uid) && uid_eq(new->fsuid, root_uid))
#ifdef CONFIG_CREDP
iee_set_cred_cap_effective(new, cap_raise_fs_set(new->cap_effective,
new->cap_permitted));
#else
new->cap_effective =
cap_raise_fs_set(new->cap_effective,
new->cap_permitted);
#endif
}
break;
@ -1243,7 +1370,16 @@ static int cap_prctl_drop(unsigned long cap)
new = prepare_creds();
if (!new)
return -ENOMEM;
#ifdef CONFIG_CREDP
{
kernel_cap_t tmp = new->cap_bset;
cap_lower(tmp, cap);
iee_set_cred_cap_bset(new, tmp);
}
#else
cap_lower(new->cap_bset, cap);
#endif
return commit_creds(new);
}
@ -1319,7 +1455,11 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
new = prepare_creds();
if (!new)
return -ENOMEM;
#ifdef CONFIG_CREDP
iee_set_cred_securebits(new, arg2);
#else
new->securebits = arg2;
#endif
return commit_creds(new);
case PR_GET_SECUREBITS:
@ -1338,9 +1478,19 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
if (!new)
return -ENOMEM;
if (arg2)
#ifdef CONFIG_CREDP
iee_set_cred_securebits(new,
new->securebits | issecure_mask(SECURE_KEEP_CAPS));
#else
new->securebits |= issecure_mask(SECURE_KEEP_CAPS);
#endif
else
#ifdef CONFIG_CREDP
iee_set_cred_securebits(new,
new->securebits & ~issecure_mask(SECURE_KEEP_CAPS));
#else
new->securebits &= ~issecure_mask(SECURE_KEEP_CAPS);
#endif
return commit_creds(new);
case PR_CAP_AMBIENT:
@ -1351,7 +1501,16 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
new = prepare_creds();
if (!new)
return -ENOMEM;
#ifdef CONFIG_CREDP
do {
kernel_cap_t tmp_cap = new->cap_ambient;
tmp_cap.val = 0;
iee_set_cred_cap_ambient(new, tmp_cap);
} while (0);
#else
cap_clear(new->cap_ambient);
#endif
return commit_creds(new);
}
@ -1375,9 +1534,27 @@ int cap_task_prctl(int option, unsigned long arg2, unsigned long arg3,
if (!new)
return -ENOMEM;
if (arg2 == PR_CAP_AMBIENT_RAISE)
#ifdef CONFIG_CREDP
{
kernel_cap_t tmp = new->cap_ambient;
cap_raise(tmp, arg3);
iee_set_cred_cap_ambient(new, tmp);
}
#else
cap_raise(new->cap_ambient, arg3);
#endif
else
#ifdef CONFIG_CREDP
{
kernel_cap_t tmp = new->cap_ambient;
cap_lower(tmp, arg3);
iee_set_cred_cap_ambient(new, tmp);
}
#else
cap_lower(new->cap_ambient, arg3);
#endif
return commit_creds(new);
}

View File

@ -22,6 +22,9 @@
#include <linux/uio.h>
#include <linux/uaccess.h>
#include <keys/request_key_auth-type.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "internal.h"
#define KEY_MAX_DESC_SIZE 4096
@ -1155,7 +1158,11 @@ static int keyctl_change_reqkey_auth(struct key *key)
return -ENOMEM;
key_put(new->request_key_auth);
#ifdef CONFIG_CREDP
iee_set_cred_request_key_auth(new, key_get(key));
#else
new->request_key_auth = key_get(key);
#endif
return commit_creds(new);
}
@ -1432,7 +1439,11 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
}
set:
#ifdef CONFIG_CREDP
iee_set_cred_jit_keyring(new, reqkey_defl);
#else
new->jit_keyring = reqkey_defl;
#endif
commit_creds(new);
return old_setting;
error:
@ -1644,9 +1655,20 @@ long keyctl_session_to_parent(void)
cred = cred_alloc_blank();
if (!cred)
goto error_keyring;
#ifdef CONFIG_CREDP
if(haoc_enabled)
newwork = (struct rcu_head *)(cred->rcu.func);
else
newwork = &cred->rcu;
#else
newwork = &cred->rcu;
#endif
#ifdef CONFIG_CREDP
iee_set_cred_session_keyring(cred, key_ref_to_ptr(keyring_r));
#else
cred->session_keyring = key_ref_to_ptr(keyring_r);
#endif
keyring_r = NULL;
init_task_work(newwork, key_change_session_keyring);
@ -1704,8 +1726,16 @@ long keyctl_session_to_parent(void)
unlock:
write_unlock_irq(&tasklist_lock);
rcu_read_unlock();
if (oldwork)
if (oldwork){
#ifdef CONFIG_CREDP
if(haoc_enabled)
put_cred(*(struct cred **)(oldwork + 1));
else
put_cred(container_of(oldwork, struct cred, rcu));
#else
put_cred(container_of(oldwork, struct cred, rcu));
#endif
}
if (newwork)
put_cred(cred);
return ret;

View File

@ -17,6 +17,9 @@
#include <linux/uaccess.h>
#include <linux/init_task.h>
#include <keys/request_key_auth-type.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
#include "internal.h"
/* Session keyring create vs join semaphore */
@ -232,7 +235,11 @@ int install_thread_keyring_to_cred(struct cred *new)
if (IS_ERR(keyring))
return PTR_ERR(keyring);
#ifdef CONFIG_CREDP
iee_set_cred_thread_keyring(new, keyring);
#else
new->thread_keyring = keyring;
#endif
return 0;
}
@ -279,7 +286,11 @@ int install_process_keyring_to_cred(struct cred *new)
if (IS_ERR(keyring))
return PTR_ERR(keyring);
#ifdef CONFIG_CREDP
iee_set_cred_process_keyring(new, keyring);
#else
new->process_keyring = keyring;
#endif
return 0;
}
@ -338,7 +349,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
/* install the keyring */
old = cred->session_keyring;
#ifdef CONFIG_CREDP
iee_set_cred_session_keyring(cred, keyring);
#else
cred->session_keyring = keyring;
#endif
if (old)
key_put(old);
@ -911,7 +926,15 @@ error:
void key_change_session_keyring(struct callback_head *twork)
{
const struct cred *old = current_cred();
#ifdef CONFIG_CREDP
struct cred *new =NULL;
if(haoc_enabled)
new = *(struct cred **)(twork + 1);
else
new = container_of(twork, struct cred, rcu);
#else
struct cred *new = container_of(twork, struct cred, rcu);
#endif
if (unlikely(current->flags & PF_EXITING)) {
put_cred(new);
@ -925,6 +948,31 @@ void key_change_session_keyring(struct callback_head *twork)
return;
}
#ifdef CONFIG_CREDP
iee_set_cred_uid(new, old->uid);
iee_set_cred_euid(new, old->euid);
iee_set_cred_suid(new, old->suid);
iee_set_cred_fsuid(new, old->fsuid);
iee_set_cred_gid(new, old->gid);
iee_set_cred_egid(new, old->egid);
iee_set_cred_sgid(new, old->sgid);
iee_set_cred_fsgid(new, old->fsgid);
iee_set_cred_user(new, get_uid(old->user));
iee_set_cred_ucounts(new, old->ucounts);
iee_set_cred_user_ns(new, get_user_ns(old->user_ns));
iee_set_cred_group_info(new, get_group_info(old->group_info));
iee_set_cred_securebits(new, old->securebits);
iee_set_cred_cap_inheritable(new, old->cap_inheritable);
iee_set_cred_cap_permitted(new, old->cap_permitted);
iee_set_cred_cap_effective(new, old->cap_effective);
iee_set_cred_cap_ambient(new, old->cap_ambient);
iee_set_cred_cap_bset(new, old->cap_bset);
iee_set_cred_jit_keyring(new, old->jit_keyring);
iee_set_cred_thread_keyring(new, key_get(old->thread_keyring));
iee_set_cred_process_keyring(new, key_get(old->process_keyring));
#else
new-> uid = old-> uid;
new-> euid = old-> euid;
new-> suid = old-> suid;
@ -948,6 +996,7 @@ void key_change_session_keyring(struct callback_head *twork)
new->jit_keyring = old->jit_keyring;
new->thread_keyring = key_get(old->thread_keyring);
new->process_keyring = key_get(old->process_keyring);
#endif
security_transfer_creds(new, old);

View File

@ -30,6 +30,9 @@
#include <linux/string.h>
#include <linux/msg.h>
#include <net/flow.h>
#ifdef CONFIG_CREDP
#include <asm/haoc/iee-cred.h>
#endif
/* How many LSMs were built into the kernel? */
#define LSM_COUNT (__end_lsm_info - __start_lsm_info)
@ -570,11 +573,19 @@ EXPORT_SYMBOL(unregister_blocking_lsm_notifier);
static int lsm_cred_alloc(struct cred *cred, gfp_t gfp)
{
if (blob_sizes.lbs_cred == 0) {
#ifdef CONFIG_CREDP
iee_set_cred_security(cred, NULL);
#else
cred->security = NULL;
#endif
return 0;
}
#ifdef CONFIG_CREDP
iee_set_cred_security(cred, kzalloc(blob_sizes.lbs_cred, gfp));
#else
cred->security = kzalloc(blob_sizes.lbs_cred, gfp);
#endif
if (cred->security == NULL)
return -ENOMEM;
return 0;
@ -2954,7 +2965,11 @@ void security_cred_free(struct cred *cred)
call_void_hook(cred_free, cred);
kfree(cred->security);
#ifdef CONFIG_CREDP
iee_set_cred_security(cred, NULL);
#else
cred->security = NULL;
#endif
}
/**