Undo the stupidity I inflicted on these files and replace it with

some (hopefully) less offensive stupidity:

If we detect that a user has loaded a module that fails to initialize
itself correctly, panic. There really isn't a safe way to recover from
something like this; we can't know that the module is bad until after
the entry point is called, by which time it's too late to do anything
about it.
This commit is contained in:
Bill Paul 1995-04-20 05:08:53 +00:00
parent e902d016a6
commit de2a1afc47
3 changed files with 30 additions and 77 deletions

View File

@ -30,7 +30,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id$
* $Id$
*/
/*
@ -73,7 +73,6 @@
static int lkm_v = 0;
static int lkm_state = LKMS_IDLE;
static char modname[MAXLKMNAME];
#ifndef MAXLKMS
#define MAXLKMS 20
@ -135,7 +134,8 @@ lkmunreserve()
if (curp && curp->area) {
kmem_free(kmem_map, curp->area, curp->size);/**/
curp->area = 0;
curp->private.lkm_any = NULL;
if (curp->private.lkm_any != NULL)
curp->private.lkm_any = NULL;
}
lkm_state = LKMS_IDLE;
@ -214,8 +214,7 @@ lkmcioctl(dev, cmd, data, flag)
* Get memory for module
*/
curp->size = resrvp->size;
/* XXX RIXME: Save the module name for sanity checking. */
strcpy(modname,resrvp->name);
curp->area = kmem_alloc(kmem_map, curp->size);/**/
curp->offset = 0; /* load offset */
@ -294,30 +293,7 @@ lkmcioctl(dev, cmd, data, flag)
#endif /* DEBUG */
return ENXIO;
}
/*
* Check that this isn't a duplicate module (broken
* modules are too stupid to check this for
* themselves). We must do this *BEFORE* we call
* the entry point of the module, since we might not
* be able to unload the module aftwewards without
* panicking the system. This defeats the purpose of
* the lkmexists() checking that takes place for
* properly designed modules, but I can't find a better
* way to do it, so...
* XXX FIXME: Name matching can easily be defeated if
* the user renames the module. :(
*/
for (i = 0; i < MAXLKMS; i++) {
if (!lkmods[i].used || &lkmods[i] == curp)
continue;
if (!strcmp(modname,
lkmods[i].private.lkm_any->lkm_name)) {
lkm_state = LKMS_UNLOADING;
lkmunreserve();
curp->used = 0;
return EBUSY;
}
}
curp->entry = (int (*)()) (*((int *) (data)));
/* call entry(load)... (assigns "private" portion) */
@ -333,34 +309,26 @@ lkmcioctl(dev, cmd, data, flag)
break;
}
/*
* XXX FIXME: Somebody has apparently decided that we can
* load modules that don't play by the rules, which means
* they have no proper startup and shutdown routines,
* and consequently they have no 'private' sections.
* This is bad ju-ju: no private section means no lkm_name,
* and no lkm_name means modstat will panic us. To
* protect ourselves, we have to dummy up an lkm_any
* structure by ourselves.
* It's possible for a user to load a module that doesn't
* initialize itself correctly. (You can even get away with
* using it for a while.) Unfortunately, we are faced with
* the following problems:
* - we can't tell a good module from a bad one until
* after we've run its entry function (if the private
* section is uninitalized after we return from the
* entry, then something's fishy)
* - now that we've called the entry function, we can't
* forcibly unload the module without risking a crash
* - since we don't know what the module's entry function
* did, we can't easily clean up the mess it may have
* made, so we can't know just how unstable the system
* may be
* So, being stuck between a rock and a hard place, we
* have no choice but to do this...
*/
if (curp->private.lkm_any == NULL) {
#ifdef DEBUG
/* chastise the module programmer for being a dolt */
printf("warning: module #%d has no 'private' data!\n",
curp->id);
#endif
/* We lose some memory here, but we can't unload
this module anyway, so what the hell. */
curp->private.lkm_any = malloc(sizeof(struct lkm_any),
M_IOCTLOPS, M_WAITOK);
/* This is all thoroughly bogus,
but it's better than a panic. */
curp->private.lkm_any->lkm_offset = 0;
curp->private.lkm_any->lkm_ver = LKM_VERSION;
curp->private.lkm_any->lkm_type = LM_UNKNOWN;
curp->private.lkm_any->lkm_name = malloc(MAXLKMNAME,
M_IOCTLOPS, M_WAITOK);
strcpy(curp->private.lkm_any->lkm_name, modname);
}
if (curp->private.lkm_any == NULL)
panic("loadable module initialization failed");
curp->used = 1;
#ifdef DEBUG
printf("LKM: LMREADY\n");
@ -409,24 +377,11 @@ lkmcioctl(dev, cmd, data, flag)
err = ENOENT;
break;
}
/*
* XXX FIXME: Remember those modules without the 'private'
* sections? Don't even *think* about unloading them.
*/
if (curp->private.lkm_any->lkm_type == LM_UNKNOWN) {
#ifdef DEBUG
/* abuse the module programmer again. */
printf ("warning: module #%d can't be unloaded!\n",
curp->id);
#endif
/* call entry(unload) */
if ((*(curp->entry))(curp, LKM_E_UNLOAD, LKM_VERSION)) {
err = EBUSY;
break;
} else {
/* call entry(unload) */
if ((*(curp->entry))(curp, LKM_E_UNLOAD, LKM_VERSION)) {
err = EBUSY;
break;
}
}
lkm_state = LKMS_UNLOADING; /* non-idle for lkmunreserve */

View File

@ -49,8 +49,7 @@ typedef enum loadmod {
LM_DEV,
LM_STRMOD,
LM_EXEC,
LM_MISC,
LM_UNKNOWN
LM_MISC
} MODTYPE;

View File

@ -29,7 +29,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: modstat.c,v 1.1 1994/08/19 12:14:06 davidg Exp $
* $Id: modstat.c,v 1.2 1995/04/18 02:19:17 wpaul Exp $
*/
#include <stdio.h>
@ -61,8 +61,7 @@ static char *type_names[] = {
"DEV",
"STRMOD",
"EXEC",
"MISC",
"UNKNOWN"
"MISC"
};
int