Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/kern fix two issues regarding handling of ksyms (modload...



details:   https://anonhg.NetBSD.org/src/rev/e57235e9d824
branches:  trunk
changeset: 572343:e57235e9d824
user:      jdolecek <jdolecek%NetBSD.org@localhost>
date:      Thu Dec 30 11:35:41 2004 +0000

description:
fix two issues regarding handling of ksyms (modload -s):
* only add the symbol table for the current module if the LKM_E_LOAD
  hook returns success; otherwise we overwrite the LKM_E_LOAD error,
  which may ultimately lead to (incorrectly) allowing the module load
* only delete the sumbol table for current module if we actually added
  the symbol table; avoids deleting symbol table of previously loaded
  module when the same module is loaded twice, when the second load
  fails with EEXIST

fixes PR kern/28803 by Jens Kessmeier

diffstat:

 sys/kern/kern_lkm.c |  35 +++++++++++++++++++++--------------
 1 files changed, 21 insertions(+), 14 deletions(-)

diffs (116 lines):

diff -r 15178d6ec3e3 -r e57235e9d824 sys/kern/kern_lkm.c
--- a/sys/kern/kern_lkm.c       Thu Dec 30 10:09:32 2004 +0000
+++ b/sys/kern/kern_lkm.c       Thu Dec 30 11:35:41 2004 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: kern_lkm.c,v 1.78 2004/10/25 23:37:58 peter Exp $      */
+/*     $NetBSD: kern_lkm.c,v 1.79 2004/12/30 11:35:41 jdolecek Exp $   */
 
 /*
  * Copyright (c) 1994 Christopher G. Demetriou
@@ -41,7 +41,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kern_lkm.c,v 1.78 2004/10/25 23:37:58 peter Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kern_lkm.c,v 1.79 2004/12/30 11:35:41 jdolecek Exp $");
 
 #include "opt_ddb.h"
 #include "opt_malloclog.h"
@@ -104,7 +104,7 @@
 static struct lkm_table *lkmlookup(int, char *, int *);
 static struct lkm_table *lkmalloc(void);
 static void lkmfree(void);
-static void lkmunreserve(void);
+static void lkmunreserve(int);
 static int _lkm_syscall(struct lkm_table *, int);
 static int _lkm_vfs(struct lkm_table *, int);
 static int _lkm_dev(struct lkm_table *, int);
@@ -264,14 +264,15 @@
  * or explicitly by modload as a result of a link failure.
  */
 static void
-lkmunreserve(void)
+lkmunreserve(int delsymtab)
 {
 
        if (lkm_state == LKMS_IDLE)
                return;
 
        if (curp && curp->syms) {
-               ksyms_delsymtab(curp->private.lkm_any->lkm_name);
+               if (delsymtab)
+                       ksyms_delsymtab(curp->private.lkm_any->lkm_name);
                uvm_km_free(kernel_map, curp->syms, curp->sym_size);/**/
                curp->syms = 0;
        }
@@ -308,7 +309,7 @@
                 * by way of error or by way of close-on-exit from
                 * a premature exit of "modload".
                 */
-               lkmunreserve(); /* coerce state to LKM_IDLE */
+               lkmunreserve(1);        /* coerce state to LKM_IDLE */
                lkmfree();
        }
 
@@ -452,7 +453,7 @@
                if ((flag & FWRITE) == 0) /* only allow this if writing */
                        return EPERM;
 
-               lkmunreserve(); /* coerce state to LKM_IDLE */
+               lkmunreserve(0);        /* coerce state to LKM_IDLE */
                if (curp != NULL)
                        lkmfree();
 #ifdef DEBUG
@@ -476,10 +477,11 @@
                        return ENXIO;
                }
 
-               if (curp->size - curp->offset > 0)
+               if (curp->size - curp->offset > 0) {
                        /* The remainder must be bss, so we clear it */
                        memset((caddr_t)curp->area + curp->offset, 0,
                               curp->size - curp->offset);
+               }
 
                if (curp->syms && curp->sym_offset >= curp->sym_size) {
                        error = ksyms_addsymtab("/lkmtemp/",
@@ -499,20 +501,25 @@
 
                /* call entry(load)... (assigns "private" portion) */
                error = (*(curp->entry))(curp, LKM_E_LOAD, LKM_VERSION);
+
                if (curp->syms && curp->sym_offset >= curp->sym_size) {
                        ksyms_delsymtab("/lkmtemp/");
-                       error = ksyms_addsymtab(curp->private.lkm_any->lkm_name,
-                           (char *)curp->syms, curp->sym_symsize,
-                           (char *)curp->syms + curp->sym_symsize,
-                           curp->sym_size - curp->sym_symsize);
+
+                       if (!error) {
+                               error = ksyms_addsymtab(curp->private.lkm_any->lkm_name,
+                                   (char *)curp->syms, curp->sym_symsize,
+                                   (char *)curp->syms + curp->sym_symsize,
+                                   curp->sym_size - curp->sym_symsize);
+                       }
                }
+
                if (error) {
                        /*
                         * Module may refuse loading or may have a
                         * version mismatch...
                         */
                        lkm_state = LKMS_UNLOADING;     /* for lkmunreserve */
-                       lkmunreserve();                 /* free memory */
+                       lkmunreserve(0);                /* free memory */
                        lkmfree();                      /* free slot */
 #ifdef DEBUG
                        if (lkmdebug & LKMDB_INFO)
@@ -550,7 +557,7 @@
                }
 
                lkm_state = LKMS_UNLOADING;     /* non-idle for lkmunreserve */
-               lkmunreserve();                 /* free memory */
+               lkmunreserve(1);                /* free memory */
                lkmfree();                      /* free slot */
                break;
 



Home | Main Index | Thread Index | Old Index