Advertisement
xosski

Kernel recon

Dec 26th, 2024
9
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.97 KB | None | 0 0
  1. #include <linux/atomic.h>
  2. #include <linux/cdev.h>
  3. #include <linux/device.h>
  4. #include <linux/fs.h>
  5. #include <linux/init.h>
  6. #include <linux/kernel.h>
  7. #include <linux/module.h>
  8. #include <linux/uaccess.h>
  9. #include <linux/utsname.h>
  10. #include <linux/sysinfo.h>
  11. #include <linux/sched.h>
  12. #include <linux/slab.h>
  13. #include <linux/string.h>
  14.  
  15. #define DEVICE_NAME "kfetch"
  16. #define BUFFER_SIZE 1024
  17.  
  18. enum {
  19. UNUSED = 0,
  20. EXCLUSIVE_OPEN = 1,
  21. };
  22.  
  23. /* Feature masks */
  24. #define KFETCH_RELEASE 0x01
  25. #define KFETCH_CPU_MODEL 0x02
  26. #define KFETCH_NUM_CPUS 0x04
  27. #define KFETCH_MEM 0x08
  28. #define KFETCH_NUM_PROCS 0x10
  29. #define KFETCH_UPTIME 0x20
  30.  
  31. static int device_open(struct inode *, struct file *);
  32. static int device_release(struct inode *, struct file *);
  33. static ssize_t device_read(struct file *, char __user *, size_t, loff_t *);
  34. static ssize_t device_write(struct file *, const char __user *, size_t, loff_t *);
  35.  
  36. static int major_number;
  37. static atomic_t is_device_open = ATOMIC_INIT(UNUSED);
  38. static char message[BUFFER_SIZE];
  39. static struct class *device_class;
  40.  
  41. /* File operations structure */
  42. static struct file_operations fops = {
  43. .owner = THIS_MODULE,
  44. .read = device_read,
  45. .write = device_write,
  46. .open = device_open,
  47. .release = device_release,
  48. };
  49.  
  50. static int __init kfetch_init(void)
  51. {
  52. major_number = register_chrdev(0, DEVICE_NAME, &fops);
  53. if (major_number < 0) {
  54. pr_err("Failed to register character device\n");
  55. return major_number;
  56. }
  57.  
  58. device_class = class_create(THIS_MODULE, DEVICE_NAME);
  59. if (IS_ERR(device_class)) {
  60. unregister_chrdev(major_number, DEVICE_NAME);
  61. pr_err("Failed to create device class\n");
  62. return PTR_ERR(device_class);
  63. }
  64.  
  65. if (IS_ERR(device_create(device_class, NULL, MKDEV(major_number, 0), NULL, DEVICE_NAME))) {
  66. class_destroy(device_class);
  67. unregister_chrdev(major_number, DEVICE_NAME);
  68. pr_err("Failed to create device\n");
  69. return -1;
  70. }
  71.  
  72. pr_info("Device created at /dev/%s\n", DEVICE_NAME);
  73. return 0;
  74. }
  75.  
  76. static void __exit kfetch_exit(void)
  77. {
  78. if (device_class) {
  79. device_destroy(device_class, MKDEV(major_number, 0));
  80. class_destroy(device_class);
  81. }
  82.  
  83. if (major_number >= 0) {
  84. unregister_chrdev(major_number, DEVICE_NAME);
  85. }
  86.  
  87. pr_info("Device unregistered and resources freed\n");
  88. }
  89.  
  90. static void fetch_kernel_info(char *buffer)
  91. {
  92. struct new_utsname *uts = utsname();
  93. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "Kernel:\t%s\n", uts->release);
  94. }
  95.  
  96. static void fetch_cpu_model(char *buffer)
  97. {
  98. struct file *file;
  99. char line[128];
  100. mm_segment_t old_fs;
  101. char *model_name = NULL;
  102.  
  103. old_fs = get_fs();
  104. set_fs(KERNEL_DS);
  105.  
  106. file = filp_open("/proc/cpuinfo", O_RDONLY, 0);
  107. if (IS_ERR(file)) {
  108. set_fs(old_fs);
  109. return;
  110. }
  111.  
  112. while (kernel_read(file, line, sizeof(line) - 1, &file->f_pos) > 0) {
  113. line[sizeof(line) - 1] = '\0';
  114. if (strstr(line, "model name")) {
  115. model_name = strchr(line, ':');
  116. if (model_name) {
  117. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "CPU:\t%s\n", model_name + 2);
  118. }
  119. break;
  120. }
  121. }
  122.  
  123. filp_close(file, NULL);
  124. set_fs(old_fs);
  125. }
  126.  
  127. static void fetch_cpu_count(char *buffer)
  128. {
  129. int cpu_count = num_online_cpus();
  130. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "CPUs:\t%d\n", cpu_count);
  131. }
  132.  
  133. static void fetch_memory_info(char *buffer)
  134. {
  135. struct sysinfo si;
  136. si_meminfo(&si);
  137. unsigned long total_mem = si.totalram >> 10;
  138. unsigned long free_mem = si.freeram >> 10;
  139. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "Memory:\t%lu MB / %lu MB\n", free_mem, total_mem);
  140. }
  141.  
  142. static void fetch_process_count(char *buffer)
  143. {
  144. int proc_count = 0;
  145. struct task_struct *task;
  146.  
  147. for_each_process(task)
  148. proc_count++;
  149.  
  150. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "Processes:\t%d\n", proc_count);
  151. }
  152.  
  153. static void fetch_uptime(char *buffer)
  154. {
  155. struct sysinfo si;
  156. si_meminfo(&si);
  157. do_sysinfo(&si);
  158. unsigned long uptime_minutes = si.uptime / 60;
  159. snprintf(buffer + strlen(buffer), BUFFER_SIZE - strlen(buffer), "Uptime:\t%lu mins\n", uptime_minutes);
  160. }
  161.  
  162. static int device_open(struct inode *inode, struct file *file)
  163. {
  164. if (atomic_cmpxchg(&is_device_open, UNUSED, EXCLUSIVE_OPEN))
  165. return -EBUSY;
  166.  
  167. try_module_get(THIS_MODULE);
  168. return 0;
  169. }
  170.  
  171. static int device_release(struct inode *inode, struct file *file)
  172. {
  173. atomic_set(&is_device_open, UNUSED);
  174. module_put(THIS_MODULE);
  175. return 0;
  176. }
  177.  
  178. static ssize_t device_read(struct file *filp, char __user *buffer, size_t len, loff_t *offset)
  179. {
  180. size_t msg_len = strlen(message);
  181. size_t remaining = msg_len - *offset;
  182.  
  183. if (remaining == 0)
  184. return 0;
  185.  
  186. if (len > remaining)
  187. len = remaining;
  188.  
  189. if (copy_to_user(buffer, message + *offset, len))
  190. return -EFAULT;
  191.  
  192. *offset += len;
  193. return len;
  194. }
  195.  
  196. static ssize_t device_write(struct file *filp, const char __user *buffer, size_t len, loff_t *offset)
  197. {
  198. int feature_mask;
  199.  
  200. if (len != sizeof(int))
  201. return -EINVAL;
  202.  
  203. if (copy_from_user(&feature_mask, buffer, sizeof(int)))
  204. return -EFAULT;
  205.  
  206. memset(message, 0, BUFFER_SIZE);
  207.  
  208. if (feature_mask & KFETCH_RELEASE)
  209. fetch_kernel_info(message);
  210. if (feature_mask & KFETCH_CPU_MODEL)
  211. fetch_cpu_model(message);
  212. if (feature_mask & KFETCH_NUM_CPUS)
  213. fetch_cpu_count(message);
  214. if (feature_mask & KFETCH_MEM)
  215. fetch_memory_info(message);
  216. if (feature_mask & KFETCH_NUM_PROCS)
  217. fetch_process_count(message);
  218. if (feature_mask & KFETCH_UPTIME)
  219. fetch_uptime(message);
  220.  
  221. return len;
  222. }
  223.  
  224. module_init(kfetch_init);
  225. module_exit(kfetch_exit);
  226.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement