From owner-freebsd-bugs Fri Mar 23 11: 0:36 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 0431937B71B for ; Fri, 23 Mar 2001 11:00:03 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f2NJ03909678; Fri, 23 Mar 2001 11:00:03 -0800 (PST) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id B1E9037B719 for ; Fri, 23 Mar 2001 10:57:34 -0800 (PST) (envelope-from nobody@FreeBSD.org) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.1/8.11.1) id f2NIvY209246; Fri, 23 Mar 2001 10:57:34 -0800 (PST) (envelope-from nobody) Message-Id: <200103231857.f2NIvY209246@freefall.freebsd.org> Date: Fri, 23 Mar 2001 10:57:34 -0800 (PST) From: jtrainor@fastekintl.com To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: kern/26034: kldload() panics if error code is returned from _load(). Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 26034 >Category: kern >Synopsis: kldload() panics if error code is returned from _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 _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$ */ /* --------------------------------------------------------------- */ /* */ /* mm/dd/yyyy - pid - comment */ /* =============================================================== */ #include #include #include #include #include #include /* 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