sus_su.c 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <linux/module.h>
  2. #include <linux/kernel.h>
  3. #include <linux/fs.h>
  4. #include <linux/uaccess.h>
  5. #include <linux/cdev.h>
  6. #include <linux/random.h>
  7. #include <linux/cred.h>
  8. #include <linux/sus_su.h>
  9. #ifdef CONFIG_KSU_SUSFS_ENABLE_LOG
  10. extern bool susfs_is_log_enabled __read_mostly;
  11. #define SUSFS_LOGI(fmt, ...) if (susfs_is_log_enabled) pr_info("susfs_sus_su:[%u][%u][%s] " fmt, current_uid().val, current->pid, __func__, ##__VA_ARGS__)
  12. #define SUSFS_LOGE(fmt, ...) if (susfs_is_log_enabled) pr_err("susfs_sus_su:[%u][%u][%s]" fmt, current_uid().val, current->pid, __func__, ##__VA_ARGS__)
  13. #else
  14. #define SUSFS_LOGI(fmt, ...)
  15. #define SUSFS_LOGE(fmt, ...)
  16. #endif
  17. #define FIFO_SIZE 1024
  18. #define MAX_DRV_NAME 255
  19. static int cur_maj_dev_num = -1;
  20. static char fifo_buffer[FIFO_SIZE];
  21. static struct cdev sus_su_cdev;
  22. static const char *sus_su_token = "!@#$SU_IS_SUS$#@!-pRE6W9BKXrJr1hEKyvDq0CvWziVKbatT8yzq06fhtrEGky2tVS7Q2QTjhtMfVMGV";
  23. static char rand_drv_path[MAX_DRV_NAME+1] = "/dev/";
  24. static bool is_sus_su_enabled_before = false;
  25. extern bool susfs_is_allow_su(void);
  26. extern void ksu_escape_to_root(void);
  27. static void gen_rand_drv_name(char *buffer, size_t min_length, size_t max_length) {
  28. const char *symbols = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_-+@#:=";
  29. size_t symbols_length = strlen(symbols);
  30. size_t length, i;
  31. unsigned int rand_value;
  32. // Determine the random length of the string
  33. get_random_bytes(&rand_value, sizeof(rand_value));
  34. length = min_length + (rand_value % (max_length - min_length + 1));
  35. for (i = 0; i < length; ++i) {
  36. get_random_bytes(&rand_value, sizeof(rand_value));
  37. buffer[i] = symbols[rand_value % symbols_length];
  38. }
  39. buffer[length] = '\0'; // Null-terminate the string
  40. }
  41. static int fifo_open(struct inode *inode, struct file *file) {
  42. return 0;
  43. }
  44. static int fifo_release(struct inode *inode, struct file *file) {
  45. return 0;
  46. }
  47. static ssize_t fifo_read(struct file *file, char __user *buf, size_t len, loff_t *offset) {
  48. return 0;
  49. }
  50. static ssize_t fifo_write(struct file *file, const char __user *buf, size_t len, loff_t *offset) {
  51. int sus_su_token_len = strlen(sus_su_token);
  52. if (!susfs_is_allow_su()) {
  53. SUSFS_LOGE("root is not allowed for uid: '%d', pid: '%d'\n", current_uid().val, current->pid);
  54. return 0;
  55. }
  56. if (copy_from_user(fifo_buffer, buf, sus_su_token_len+1)) {
  57. SUSFS_LOGE("copy_from_user() failed, uid: '%d', pid: '%d'\n", current_uid().val, current->pid);
  58. return 0;
  59. }
  60. if (!memcmp(fifo_buffer, sus_su_token, sus_su_token_len+1)) {
  61. SUSFS_LOGI("granting root access for uid: '%d', pid: '%d'\n", current_uid().val, current->pid);
  62. ksu_escape_to_root();
  63. } else {
  64. SUSFS_LOGI("wrong token! deny root access for uid: '%d', pid: '%d'\n", current_uid().val, current->pid);
  65. }
  66. memset(fifo_buffer, 0, FIFO_SIZE);
  67. return 0;
  68. }
  69. static struct file_operations fops = {
  70. .owner = THIS_MODULE,
  71. .open = fifo_open,
  72. .release = fifo_release,
  73. .read = fifo_read,
  74. .write = fifo_write,
  75. };
  76. int sus_su_fifo_init(int *maj_dev_num, char *drv_path) {
  77. if (cur_maj_dev_num > 0) {
  78. SUSFS_LOGE("'%s' is already registered\n", rand_drv_path);
  79. return -1;
  80. }
  81. // generate a random driver name if it is executed for the first time
  82. if (!is_sus_su_enabled_before) {
  83. // min length 192, max length 248, just make sure max length doesn't exceeds 255
  84. gen_rand_drv_name(rand_drv_path+5, 192, 248);
  85. }
  86. cur_maj_dev_num = register_chrdev(0, rand_drv_path+5, &fops);
  87. if (cur_maj_dev_num < 0) {
  88. SUSFS_LOGE("Failed to register character device\n");
  89. return -1;
  90. }
  91. cdev_init(&sus_su_cdev, &fops);
  92. if (cdev_add(&sus_su_cdev, MKDEV(cur_maj_dev_num, 0), 1) < 0) {
  93. unregister_chrdev(cur_maj_dev_num, rand_drv_path+5);
  94. SUSFS_LOGE("Failed to add cdev\n");
  95. return -1;
  96. }
  97. strncpy(drv_path, rand_drv_path, strlen(rand_drv_path));
  98. *maj_dev_num = cur_maj_dev_num;
  99. SUSFS_LOGI("'%s' registered with major device number %d\n", rand_drv_path, cur_maj_dev_num);
  100. if (!is_sus_su_enabled_before)
  101. is_sus_su_enabled_before = true;
  102. return 0;
  103. }
  104. int sus_su_fifo_exit(int *maj_dev_num, char *drv_path) {
  105. if (cur_maj_dev_num < 0) {
  106. SUSFS_LOGE("'%s' was already unregistered before\n", rand_drv_path);
  107. return 0;
  108. }
  109. cdev_del(&sus_su_cdev);
  110. unregister_chrdev(cur_maj_dev_num, rand_drv_path+5);
  111. cur_maj_dev_num = -1;
  112. *maj_dev_num = cur_maj_dev_num;
  113. strncpy(drv_path, rand_drv_path, strlen(rand_drv_path));
  114. SUSFS_LOGI("'%s' unregistered\n", rand_drv_path);
  115. return 0;
  116. }