Fix maplist entries being used after they were freed; thanks to Benjamin
authorMichel Daenzer <michel@daenzer.net>
Wed, 6 Aug 2003 11:46:21 +0000 (11:46 +0000)
committerMichel Daenzer <michel@daenzer.net>
Wed, 6 Aug 2003 11:46:21 +0000 (11:46 +0000)
    Herrenschmidt for tracking this down

linux-core/drm_drv.c
linux/drm_drv.h

index 016f919..5f3eebe 100644 (file)
@@ -453,51 +453,49 @@ static int DRM(takedown)( drm_device_t *dev )
        }
 
        if( dev->maplist ) {
-               for(list = dev->maplist->head.next;
-                   list != &dev->maplist->head;
-                   list = list_next) {
-                       list_next = list->next;
+               list_for_each_safe( list, list_next, &dev->maplist->head ) {
                        r_list = (drm_map_list_t *)list;
-                       map = r_list->map;
-                       DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
-                       if(!map) continue;
 
-                       switch ( map->type ) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
+                       if ( ( map = r_list->map ) ) {
+                               switch ( map->type ) {
+                               case _DRM_REGISTERS:
+                               case _DRM_FRAME_BUFFER:
 #if __REALLY_HAVE_MTRR
-                               if ( map->mtrr >= 0 ) {
-                                       int retcode;
-                                       retcode = mtrr_del( map->mtrr,
-                                                           map->offset,
-                                                           map->size );
-                                       DRM_DEBUG( "mtrr_del=%d\n", retcode );
-                               }
-#endif
-                               DRM(ioremapfree)( map->handle, map->size, dev );
-                               break;
-                       case _DRM_SHM:
-                               vfree(map->handle);
-                               break;
-
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                * handled in the AGP/GART driver.
-                                */
-                               break;
-                       case _DRM_SCATTER_GATHER:
-                               /* Handle it, but do nothing, if HAVE_SG
-                                * isn't defined.
-                                */
+                                       if ( map->mtrr >= 0 ) {
+                                               int retcode;
+                                               retcode = mtrr_del( map->mtrr,
+                                                                   map->offset,
+                                                                   map->size );
+                                               DRM_DEBUG( "mtrr_del=%d\n", retcode );
+                                       }
+#endif
+                                       DRM(ioremapfree)( map->handle, map->size, dev );
+                                       break;
+                               case _DRM_SHM:
+                                       vfree(map->handle);
+                                       break;
+
+                               case _DRM_AGP:
+                                       /* Do nothing here, because this is all
+                                        * handled in the AGP/GART driver.
+                                        */
+                                       break;
+                               case _DRM_SCATTER_GATHER:
+                                       /* Handle it, but do nothing, if HAVE_SG
+                                        * isn't defined.
+                                        */
 #if __HAVE_SG
-                               if(dev->sg) {
-                                       DRM(sg_cleanup)(dev->sg);
-                                       dev->sg = NULL;
-                               }
+                                       if(dev->sg) {
+                                               DRM(sg_cleanup)(dev->sg);
+                                               dev->sg = NULL;
+                                       }
 #endif
-                               break;
+                                       break;
+                               }
+                               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
                        }
-                       DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+                       list_del( list );
+                       DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
                }
                DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
                dev->maplist = NULL;
index 016f919..5f3eebe 100644 (file)
@@ -453,51 +453,49 @@ static int DRM(takedown)( drm_device_t *dev )
        }
 
        if( dev->maplist ) {
-               for(list = dev->maplist->head.next;
-                   list != &dev->maplist->head;
-                   list = list_next) {
-                       list_next = list->next;
+               list_for_each_safe( list, list_next, &dev->maplist->head ) {
                        r_list = (drm_map_list_t *)list;
-                       map = r_list->map;
-                       DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
-                       if(!map) continue;
 
-                       switch ( map->type ) {
-                       case _DRM_REGISTERS:
-                       case _DRM_FRAME_BUFFER:
+                       if ( ( map = r_list->map ) ) {
+                               switch ( map->type ) {
+                               case _DRM_REGISTERS:
+                               case _DRM_FRAME_BUFFER:
 #if __REALLY_HAVE_MTRR
-                               if ( map->mtrr >= 0 ) {
-                                       int retcode;
-                                       retcode = mtrr_del( map->mtrr,
-                                                           map->offset,
-                                                           map->size );
-                                       DRM_DEBUG( "mtrr_del=%d\n", retcode );
-                               }
-#endif
-                               DRM(ioremapfree)( map->handle, map->size, dev );
-                               break;
-                       case _DRM_SHM:
-                               vfree(map->handle);
-                               break;
-
-                       case _DRM_AGP:
-                               /* Do nothing here, because this is all
-                                * handled in the AGP/GART driver.
-                                */
-                               break;
-                       case _DRM_SCATTER_GATHER:
-                               /* Handle it, but do nothing, if HAVE_SG
-                                * isn't defined.
-                                */
+                                       if ( map->mtrr >= 0 ) {
+                                               int retcode;
+                                               retcode = mtrr_del( map->mtrr,
+                                                                   map->offset,
+                                                                   map->size );
+                                               DRM_DEBUG( "mtrr_del=%d\n", retcode );
+                                       }
+#endif
+                                       DRM(ioremapfree)( map->handle, map->size, dev );
+                                       break;
+                               case _DRM_SHM:
+                                       vfree(map->handle);
+                                       break;
+
+                               case _DRM_AGP:
+                                       /* Do nothing here, because this is all
+                                        * handled in the AGP/GART driver.
+                                        */
+                                       break;
+                               case _DRM_SCATTER_GATHER:
+                                       /* Handle it, but do nothing, if HAVE_SG
+                                        * isn't defined.
+                                        */
 #if __HAVE_SG
-                               if(dev->sg) {
-                                       DRM(sg_cleanup)(dev->sg);
-                                       dev->sg = NULL;
-                               }
+                                       if(dev->sg) {
+                                               DRM(sg_cleanup)(dev->sg);
+                                               dev->sg = NULL;
+                                       }
 #endif
-                               break;
+                                       break;
+                               }
+                               DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
                        }
-                       DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
+                       list_del( list );
+                       DRM(free)(r_list, sizeof(*r_list), DRM_MEM_MAPS);
                }
                DRM(free)(dev->maplist, sizeof(*dev->maplist), DRM_MEM_MAPS);
                dev->maplist = NULL;