kernel: fix probe_kernel_read failed to read user addr
This commit is contained in:
@@ -131,3 +131,43 @@ ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count,
|
|||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
||||||
|
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||||
|
long count)
|
||||||
|
{
|
||||||
|
return strncpy_from_user_nofault(dst, unsafe_addr, count);
|
||||||
|
}
|
||||||
|
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
|
||||||
|
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||||
|
long count)
|
||||||
|
{
|
||||||
|
return strncpy_from_unsafe_user(dst, unsafe_addr, count);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
// Copied from: https://elixir.bootlin.com/linux/v4.9.337/source/mm/maccess.c#L201
|
||||||
|
long ksu_strncpy_from_user_nofault(char *dst, const void __user *unsafe_addr,
|
||||||
|
long count)
|
||||||
|
{
|
||||||
|
mm_segment_t old_fs = get_fs();
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
set_fs(USER_DS);
|
||||||
|
pagefault_disable();
|
||||||
|
ret = strncpy_from_user(dst, unsafe_addr, count);
|
||||||
|
pagefault_enable();
|
||||||
|
set_fs(old_fs);
|
||||||
|
|
||||||
|
if (ret >= count) {
|
||||||
|
ret = count;
|
||||||
|
dst[ret - 1] = '\0';
|
||||||
|
} else if (ret > 0) {
|
||||||
|
ret++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@@ -6,21 +6,20 @@
|
|||||||
#include "linux/version.h"
|
#include "linux/version.h"
|
||||||
#include "linux/uaccess.h"
|
#include "linux/uaccess.h"
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 8, 0)
|
extern long ksu_strncpy_from_user_nofault(char *dst,
|
||||||
#define ksu_strncpy_from_user_nofault strncpy_from_user_nofault
|
const void __user *unsafe_addr,
|
||||||
#elif LINUX_VERSION_CODE >= KERNEL_VERSION(5, 3, 0)
|
long count);
|
||||||
#define ksu_strncpy_from_user_nofault strncpy_from_unsafe_user
|
|
||||||
#else
|
|
||||||
#define ksu_strncpy_from_user_nofault probe_kernel_read
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 10, 0)
|
||||||
extern struct key *init_session_keyring;
|
extern struct key *init_session_keyring;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
extern void ksu_android_ns_fs_check();
|
extern void ksu_android_ns_fs_check();
|
||||||
extern struct file *ksu_filp_open_compat(const char *filename, int flags, umode_t mode);
|
extern struct file *ksu_filp_open_compat(const char *filename, int flags,
|
||||||
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count, loff_t *pos);
|
umode_t mode);
|
||||||
extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf, size_t count, loff_t *pos);
|
extern ssize_t ksu_kernel_read_compat(struct file *p, void *buf, size_t count,
|
||||||
|
loff_t *pos);
|
||||||
|
extern ssize_t ksu_kernel_write_compat(struct file *p, const void *buf,
|
||||||
|
size_t count, loff_t *pos);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user