Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 23 Mar 2001 10:57:34 -0800 (PST)
From:      jtrainor@fastekintl.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/26034: kldload() panics if error code is returned from <module_name>_load().
Message-ID:  <200103231857.f2NIvY209246@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>Number:         26034
>Category:       kern
>Synopsis:       kldload() panics if error code is returned from <module_name>_load().
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Fri Mar 23 11:00:03 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jim Trainor
>Release:        FreeBSD 4.2-RELEASE #0: 11/20/2000
>Organization:
Fastek International Ltd.
>Environment:
FreeBSD BSDDEV.fastekintl.com 4.2-RELEASE FreeBSD 4.2-RELEASE #0: Mon Nov 20 13:02:55 GMT 2000     jkh@bento.FreeBSD.org:/usr/src/sys/compile/GENERIC  i386

>Description:
panic trap 12 (page fault) in kldload while attempting to return an error from <module_name>_load.  If I set the return value prior to entering the case statement, proper behavior is observed.  If I set the return value inside the case statement, panic occurs.  See code below.
>How-To-Repeat:
/* =============================================================== */
/* Program..... KLD Character Device Implementation Skeleton       */
/* Version..... 1.0                                                */
/* File........ CDEVEXAM.C                                         */
/* Date........ 03/04/2001                                         */
/* Programmer.. Jim Trainor                                        */
/* Copyright (c)2001 Fastek International Ltd.                     */
/* --------------------------------------------------------------- */
/* */
/* --------------------------------------------------------------- */
/* This code is from the article "Dynamic Kernel Linker (KLD)      */
/* Facility Programming Tutorial" by Andrew Reiter.  The article   */
/* was in "daemonnews" October 2000.                               */
/* The module is loaded with "kldload ./cdev_exam.ko"              */
/* --------------------------------------------------------------- */
/* $Header$                                                        */
/* --------------------------------------------------------------- */
/* <revision comments in the form>                                 */
/* mm/dd/yyyy - pid - comment                                      */
/* =============================================================== */
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/uio.h>
#include <sys/conf.h>	/* for macro DEV_MODULE */

/* --------------------------------------------------------------- */
/* Device access function declarations                             */
/* --------------------------------------------------------------- */
int example_open(dev_t dev, int oflags, int devtype, struct proc *p);
int example_close(dev_t dev, int fflag, int devtype, struct proc *p);
int example_read(dev_t dev, struct uio *uio, int ioflag);
int example_write(dev_t dev, struct uio *uio, int ioflag);

/* --------------------------------------------------------------- */
/* Define global variables.                                        */
/* --------------------------------------------------------------- */
/* Stores string recv'd by _write() */
static char buf[512+1];
static int len;

/* 
 * Used as the variable that is the reference to our device
 * in devfs... we must keep this variable sane until we 
 * call kldunload.
 */
  
static dev_t sdev;

/* --------------------------------------------------------------- */
/* File operations supported by our device driver                  */
/* --------------------------------------------------------------- */
static struct cdevsw example_cdevsw = 
{
	example_open,
	example_close,
	example_read,
	example_write,
	noioctl,
	nopoll,
	nommap,
	nostrategy,
	"example",
	34,			/* /usr/src/sys/conf/majors */		
	nodump,
	nopsize,
	D_TTY,
	-1
};

/* --------------------------------------------------------------- */
/* chardev_example_load()                                          */
/*                                                                 */
/* This is used as the function that handles what is to occur      */
/* when the KLD binary is loaded and unloaded via the kldload      */
/* and kldunload programs.                                         */
/* --------------------------------------------------------------- */
static int
chardev_example_load(struct module *m, int what, void *arg)
{
	int err = 0;
  
    /* Test load failure case 1 - before case */
/*	err = EINVAL; */

	if(!err)
	{
		switch (what) 
		{
		case MOD_LOAD:					/* kldload */
			/* Test load failure case 2 - inside case */
			err = EINVAL;
			if(!err)
			{
				sdev = make_dev(&example_cdevsw,	/* explained below */
					0,
					UID_ROOT,
					GID_WHEEL,
					0600,
					"example");
				printf("Example device loaded.\n");
			}
		break;
		case MOD_UNLOAD:
			destroy_dev(sdev);			/* explained below */
			printf("Example device unloaded.\n");
		break;
		default:
			err = EINVAL;
		break;
		}
	}
	return(err);
}

/* --------------------------------------------------------------- */
/* example_open()                                                  */
/*                                                                 */
/* This open function solely checks for open(2) flags. We are only */
/* allowing for the flags to be O_RDWR for the purpose of showing  */
/* how one could only allow a read-only device, for example.       */
/* --------------------------------------------------------------- */
int example_open(dev_t dev, int oflags, int devtype, struct proc *p)
{
	int err = 0;

	memset(&buf, '\0', 513);
	len = 0;
	uprintf("Opened device \"example\" successfully.\n");
	return(err);
}

/* --------------------------------------------------------------- */
/* example_close()                                                 */
/*                                                                 */
/* Simply "closes" our device that was opened with example_open.   */
/* --------------------------------------------------------------- */
int example_close(dev_t dev, int fflag, int devtype, struct proc *p)
{
	memset(&buf, '\0', 513);
	len = 0;
	uprintf("Closing device \"example.\"\n"); 
	return(0);
} 

/* --------------------------------------------------------------- */
/* example_write()                                                 */
/*                                                                 */
/* The read function just takes the buf that was saved             */
/* via example_write() and returns it to userland for              */
/* accessing.                                                      */
/* --------------------------------------------------------------- */
int example_read(dev_t dev, struct uio *uio, int ioflag)
{
	int err = 0;

	if (len <= 0)
	{
		err = -1; 
	}
	else
	{/* copy buf to userland */
		err = copystr(&buf, uio->uio_iov->iov_base, 513, &len);
	}
	return(err);
}

/* --------------------------------------------------------------- */
/* example_write()                                                 */
/*                                                                 */
/* example_write takes in a character string and saves it to buf   */        
/* for later accessing.                                            */
/* --------------------------------------------------------------- */
int example_write(dev_t dev, struct uio *uio, int ioflag)
{
	int err = 0;

	err = copyinstr(uio->uio_iov->iov_base, &buf, 512, &len);
	if (err != 0)
	{
		uprintf("Write to \"example\" failed.\n");
	}
	return(err);
}

DEV_MODULE(chardev_example, chardev_example_load, NULL);


>Fix:

>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200103231857.f2NIvY209246>