Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pcmcia Some additional sanity checks to keep this co...



details:   https://anonhg.NetBSD.org/src/rev/0000480a8774
branches:  trunk
changeset: 480535:0000480a8774
user:      cgd <cgd%NetBSD.org@localhost>
date:      Fri Jan 14 23:09:53 2000 +0000

description:
Some additional sanity checks to keep this code from bursting into
flame if presented with bad CIS data (e.g. because of a memory space
conflict):
* more sanity checking on LONGLINK_MFC CIS tuples (exact length check, sanity
  check on size vs. size of array we allocated for them), to avoid various
  missteps which could cause this code to complete trash the kernel stack.
* clear the entire contents of the state structure before processing, so
  things like uninitted pointers will actually have a known value!
* be more careful with CISTPL_CFTABLE_ENTRY: check to see that the current
  state's default_entry isn't NULL before dereferencing it.

diffstat:

 sys/dev/pcmcia/pcmcia_cis.c |  52 +++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 46 insertions(+), 6 deletions(-)

diffs (88 lines):

diff -r dd82f925fdb7 -r 0000480a8774 sys/dev/pcmcia/pcmcia_cis.c
--- a/sys/dev/pcmcia/pcmcia_cis.c       Fri Jan 14 22:55:46 2000 +0000
+++ b/sys/dev/pcmcia/pcmcia_cis.c       Fri Jan 14 23:09:53 2000 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: pcmcia_cis.c,v 1.13 1999/11/07 07:44:21 enami Exp $    */
+/*     $NetBSD: pcmcia_cis.c,v 1.14 2000/01/14 23:09:53 cgd Exp $      */
 
 #define        PCMCIACISDEBUG
 
@@ -67,8 +67,7 @@
 {
        struct cis_state state;
 
-       state.count = 0;
-       state.gotmfc = 0;
+       memset(&state, 0, sizeof state);
 
        state.card = &sc->card;
 
@@ -267,17 +266,53 @@
                                            "short %d\n", tuple.length));
                                        break;
                                }
+                               if (((tuple.length - 1) % 5) != 0) {
+                                       DPRINTF(("CISTPL_LONGLINK_MFC bogus "
+                                           "length %d\n", tuple.length));
+                                       break;
+                               }
                                /*
                                 * this is kind of ad hoc, as I don't have
                                 * any real documentation
                                 */
                                {
-                                       int i;
+                                       int i, tmp_count;
 
-                                       mfc_count =
+                                       /*
+                                        * put count into tmp var so that
+                                        * if we have to bail (because it's
+                                        * a bogus count) it won't be
+                                        * remembered for later use.
+                                        */
+                                       tmp_count =
                                            pcmcia_tuple_read_1(&tuple, 0);
                                        DPRINTF(("CISTPL_LONGLINK_MFC %d",
-                                           mfc_count));
+                                           tmp_count));
+
+                                       /*
+                                        * make _sure_ it's the right size;
+                                        * if too short, it may be a weird
+                                        * (unknown/undefined) format
+                                        */
+                                       if (tuple.length != (tmp_count*5 + 1)) {
+                                               DPRINTF((" bogus length %d\n",
+                                                   tuple.length));
+                                               break;
+                                       }
+
+#ifdef PCMCIACISDEBUG  /* maybe enable all the time? */
+                                       /*
+                                        * sanity check for a programming
+                                        * error which is difficult to find
+                                        * when debugging.
+                                        */
+                                       if (tmp_count >
+                                           howmany(sizeof mfc, sizeof mfc[0]))
+                                               panic("CISTPL_LONGLINK_MFC mfc "
+                                                   "count would blow stack");
+#endif
+
+                                       mfc_count = tmp_count;
                                        for (i = 0; i < mfc_count; i++) {
                                                mfc[i].common =
                                                    (pcmcia_tuple_read_1(&tuple,
@@ -880,6 +915,11 @@
                         * cis, create new entry in the queue and start it
                         * with the current default
                         */
+                       if (state->default_cfe == NULL) {
+                               DPRINTF(("CISTPL_CFTABLE_ENTRY with no "
+                                   "default\n"));
+                               break;
+                       }
                        if (num != state->default_cfe->number) {
                                cfe = (struct pcmcia_config_entry *)
                                    malloc(sizeof(*cfe), M_DEVBUF, M_NOWAIT);



Home | Main Index | Thread Index | Old Index