Casinos Not On GamstopNon Gamstop CasinosCasinos Not On GamstopOnline Casinos UKNon Gamstop Casino
26th Sep 2002 [SBWID-4893]
COMMAND
	kernel
SYSTEMS AFFECTED
	 OpenBSD 2.9
	 OpenBSD 3.0
PROBLEM
	Marco Peereboom found following : while coding in userland,  he  crashes
	down the kernel...
	Here is the code :
	
	[root@corona src]# cat crashme.c
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	#include 
	/* globals */
	int fd[8]; /* temp pipe file descriptors */
	int fd_real[4]; /* real pipe's */
	static int __DEBUG__  = 0;
	static int __SYSLOG__  = 0;
	void enable_debug(void)
	{
	         __DEBUG__ = 1;
	}
	void disable_debug(void)
	{
	         __DEBUG__ = 0;
	}
	void enable_syslog(void)
	{
	         __SYSLOG__ = 1;
	}
	void disable_syslog(void)
	{
	         __SYSLOG__ = 0;
	}
	void s_fprintf(FILE *file, const char *fmt, ...)
	{
	         va_list ap;
	         if (__DEBUG__) {
	                 fflush(file);
	                 va_start(ap, fmt);
	                 vfprintf(file, fmt, ap);
	                 va_end(ap);
	                 fflush(file);
	         }
	         if (__SYSLOG__) {
	                 va_start(ap, fmt);
	                 vsyslog(LOG_INFO, fmt, ap);
	                 va_end(ap);
	         }
	}
	void *s_malloc(size_t size)
	{
	         char serr[40]; /* can not allocate more mem so lets use this
	ugly beast */
	         void *p;
	         if (__DEBUG__ || __SYSLOG__) {
	                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: malloc(%i)\n",
	getpid(), getppid(), size);
	         }
	         if ((p = malloc(size)) == NULL ) {
	                 sprintf(serr,"PID=%i, Could not allocate memory",
	getpid());
	                 perror(serr);
	                 exit(6);
	         }
	         return p;
	}
	void s_perror(const char *str)
	{
	         char *buf;
	         if (__DEBUG__ || __SYSLOG__) {
	                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: perror(%s)\n",
	getpid(), getppid(), str);
	         }
	         buf = s_malloc(11 + strlen(str)); /* PID=%-5i = 11 chars */
	         sprintf(buf, "PID=%-5i %s", getpid(), str);
	         perror(buf);
	         free(buf);
	}
	void s_pipe(int *fd)
	{
	         if (__DEBUG__ || __SYSLOG__) {
	                 s_fprintf(stderr, "PID=%-5i PPID=%-5i: pipe(%x)\n",
	getpid(), getppid(), (unsigned int)fd);
	         }
	         if (pipe(fd) == -1)
	         {
	                 s_perror("Could not create pipe");
	                 exit(3);
	         }
	}
	int main(int argc, char **argv)
	{
	         enable_debug();
	         enable_syslog();
	         fprintf(stderr, "Before pipe\n");
	         s_pipe(NULL); /* test if s_pipe exits */
	         fprintf(stderr, "Will never reach this\n");
	         return 0;
	}
	
SOLUTION
	Marco Peereboom explains :
	I tried to debug the kernel and I was partially successful  at  that.  I
	definitively need more practice at BSD kernel debugging  ;)  but  I  did
	find what was wrong. We were releasing the user mode retval  instead  of
	the *real* rval kernel mode values. And since  retval  was  pointing  at
	NULL bad things happened.
	Anyway here is the patch for 3.0:
	
	[root@corona kern]# diff -u uipc_syscalls.c.old uipc_syscalls.c
	--- uipc_syscalls.c.old Sun Dec  2 10:48:21 2001
	+++ uipc_syscalls.c     Sun Dec  2 10:48:48 2001
	@@ -903,8 +903,8 @@
	         error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
	             2 * sizeof (int));
	         if (error) {
	-               fdrelease(p, retval[0]);
	-               fdrelease(p, retval[1]);
	+               fdrelease(p, rval[0]);
	+               fdrelease(p, rval[1]);
	         }
	         return (error);
	  }
	
	Here is the patch for 2.9:
	
	[root@vuurmuur kern]# diff -u uipc_syscalls.c.old uipc_syscalls.c
	--- uipc_syscalls.c.old Sun Dec  2 11:00:51 2001
	+++ uipc_syscalls.c     Sun Dec  2 11:01:17 2001
	@@ -886,8 +886,8 @@
	         error = copyout((caddr_t)fds, (caddr_t)SCARG(uap, fdp),
	             2 * sizeof (int));
	         if (error) {
	-               fdrelease(p, retval[0]);
	-               fdrelease(p, retval[1]);
	+               fdrelease(p, rval[0]);
	+               fdrelease(p, rval[1]);
	         }
	         return (error);
	  }
	

Internet highlights