kernel: refine prctl harden
* I am not sure if this gonna defeats the main purpose or not, but it fix prctl issue. Signed-off-by: rsuntk <rsuntk@yukiprjkt.my.id>
This commit is contained in:
@@ -295,36 +295,37 @@ static void init_uid_scanner(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool is_prctl_valid(int option)
|
||||||
|
{
|
||||||
|
// do uid checks first before compare to 0xdeadbeef
|
||||||
|
if (is_allow_su()) {
|
||||||
|
if (option == KERNEL_SU_OPTION)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
int ksu_handle_prctl(int option, unsigned long arg2, unsigned long arg3,
|
||||||
unsigned long arg4, unsigned long arg5)
|
unsigned long arg4, unsigned long arg5)
|
||||||
{
|
{
|
||||||
// if success, we modify the arg5 as result!
|
// if success, we modify the arg5 as result!
|
||||||
u32 *result = (u32 *)arg5;
|
u32 *result = (u32 *)arg5;
|
||||||
u32 reply_ok = KERNEL_SU_OPTION;
|
u32 reply_ok = KERNEL_SU_OPTION;
|
||||||
|
uid_t current_uid_val = current_uid().val;
|
||||||
|
|
||||||
// we can skip this check when a manager is crowned already
|
// we can skip this check when a manager is crowned already
|
||||||
if (likely(ksu_is_manager_uid_valid()))
|
if (likely(ksu_is_manager_uid_valid()))
|
||||||
goto skip_check;
|
goto skip;
|
||||||
|
|
||||||
// this is mostly for that multiuser bs
|
|
||||||
// here we just let them suffer
|
|
||||||
uid_t current_uid_val = current_uid().val;
|
|
||||||
uid_t manager_uid = ksu_get_manager_uid();
|
uid_t manager_uid = ksu_get_manager_uid();
|
||||||
if (current_uid_val != manager_uid &&
|
if (current_uid_val != manager_uid &&
|
||||||
current_uid_val % 100000 == manager_uid) {
|
current_uid_val % 100000 == manager_uid) {
|
||||||
ksu_set_manager_uid(current_uid_val);
|
ksu_set_manager_uid(current_uid_val);
|
||||||
}
|
}
|
||||||
|
|
||||||
skip_check:
|
skip:
|
||||||
// yes this causes delay, but this keeps the delay consistent, which is what we want
|
kcompat_barrier();
|
||||||
// with a proper barrier for safety as the compiler and cpu might try to do something smart.
|
if (!is_prctl_valid(option))
|
||||||
KCOMPAT_BARRIER();
|
|
||||||
if (!is_allow_su())
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// we move it after uid check here so they cannot
|
|
||||||
// compare 0xdeadbeef call to a non-0xdeadbeef call
|
|
||||||
if (KERNEL_SU_OPTION != option)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
bool from_root = 0 == current_uid().val;
|
bool from_root = 0 == current_uid().val;
|
||||||
|
|||||||
@@ -8,11 +8,11 @@
|
|||||||
#include "linux/key.h"
|
#include "linux/key.h"
|
||||||
|
|
||||||
#if defined(CONFIG_X86)
|
#if defined(CONFIG_X86)
|
||||||
#define KCOMPAT_BARRIER() barrier_nospec()
|
#define kcompat_barrier() barrier_nospec()
|
||||||
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
|
#elif defined(CONFIG_ARM) || defined(CONFIG_ARM64)
|
||||||
#define KCOMPAT_BARRIER() isb() // arch/arm64/include/asm/barrier.h
|
#define kcompat_barrier() isb() // arch/arm64/include/asm/barrier.h
|
||||||
#else
|
#else
|
||||||
#define KCOMPAT_BARRIER() barrier() // well, compiler atleast.
|
#define kcompat_barrier() barrier() // well, compiler atleast.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user