[Crash-utility] Fix use after free in sial variable lists

Dave Anderson anderson at redhat.com
Tue Nov 29 13:55:55 UTC 2011



----- Original Message -----
> 
> I encountered a segfault in the sial module when repeatedly loading and unloading
> a sial script.  The bug is repeatable and it always segfaults on the 4th unload.
> The bug only triggers if a pathname is specified for the sial script too (just
> doing 'load test.sial, unload test.sial, ...' doesn't trigger the problem).
> 
> The cause of the problem is that sial_freefile() will free the memory used by the
> static and global variable lists but leaves the stale pointer in the fdata object.
> This stale pointer is then assumed to be allocated later by sial_inivars().
> 
> I've included a patch below to NULL out the static and global variable list
> pointers after they are deallocated and this fixes the problem for me although
> I'm not totally sure it's the best way to fix this.

Makes perfect sense to me -- unless Luc objects or has a better idea, 
consider it queued for crash-6.0.1.

Thanks,
  Dave

> 
> Lachlan
> 
> ...
> crash> extend /home/lmcilroy/bin/sial.so
> Core LINUX_RELEASE == '2.6.18-238.12.1.el5'
> < Sial interpreter version 3.0 >
> 	Loading sial commands from
> 	/usr/share/sial/crash:/home/lmcilroy/.sial .... Done.
> /home/lmcilroy/bin/sial.so: shared object loaded
> crash> load very_long_directory_name/test.sial
> crash> unload very_long_directory_name/test.sial
> crash> load very_long_directory_name/test.sial
> crash> unload very_long_directory_name/test.sial
> crash> load very_long_directory_name/test.sial
> crash> unload very_long_directory_name/test.sial
> crash> load very_long_directory_name/test.sial
> crash> unload very_long_directory_name/test.sial
> Segmentation fault
> 
> 
> Program received signal SIGSEGV, Segmentation fault.
> sial_inivars (sv=0x2cf4488) at sial_var.c:549
> 549			if(!v->ini && v->dv && v->dv->init) {
> Missing separate debuginfos, use: debuginfo-install
> crash-4.0.9-2.fc12.x86_64
> (gdb) bt
> #0  sial_inivars (sv=0x2cf4488) at sial_var.c:549
> #1  0x00007fffed6b1d24 in sial_addsvs (type=1, sv=<value optimized
> out>) at sial_var.c:821
> #2  0x00007fffed69f07d in sial_execmcfunc (f=<value optimized out>,
> vp=<value optimized out>) at sial_func.c:900
> #3  0x00007fffed6a026b in sial_exefunc (fname=0x7fffffffdc90
> "cciss_help", vp=0x0) at sial_func.c:968
> #4  0x00007fffed69cac2 in reg_callback (name=0x2c30538 "cciss",
> load=0) at sial.c:922
> #5  0x00007fffed69f72f in sial_docallback (fd=0x2f2ed58) at
> sial_func.c:264
> #6  sial_freefile (fd=0x2f2ed58) at sial_func.c:288
> #7  0x00007fffed69fe2a in sial_deletefile (name=0x7885a28
> "very_long_directory_name/test.sial") at sial_func.c:314
> #8  0x00007fffed6a5ce6 in sial_loadunload (load=0, name=<value
> optimized out>, silent=0) at sial_api.c:1289
> #9  0x00007fffed69c77d in unload_cmd () at sial.c:775
> #10 0x000000000045d334 in exec_command () at main.c:740
> #11 0x000000000045d57a in main_loop () at main.c:699
> #12 0x0000000000554d19 in captured_command_loop (data=<value
> optimized out>) at ./main.c:228
> #13 0x0000000000552feb in catch_errors (func=<value optimized out>,
> func_args=<value optimized out>, errstring=<value optimized out>,
> mask=<value optimized out>) at exceptions.c:531
> #14 0x0000000000554a26 in captured_main (data=<value optimized out>)
> at ./main.c:958
> #15 0x0000000000552feb in catch_errors (func=<value optimized out>,
> func_args=<value optimized out>, errstring=<value optimized out>,
> mask=<value optimized out>) at exceptions.c:531
> #16 0x0000000000553be4 in gdb_main (args=0x2cf4488) at ./main.c:973
> #17 0x0000000000553c1e in gdb_main_entry (argc=<value optimized out>,
> argv=<value optimized out>) at ./main.c:993
> #18 0x000000000045e0df in main (argc=<value optimized out>,
> argv=<value optimized out>) at main.c:603
> (gdb) p sv
> $1 = (var_t *) 0x2cf4488
> (gdb) p sv->next
> $2 = (struct var_s *) 0x7463657269645f67
> 
> 0x7463657269645f67 = "g-direct" which is part of the sial pathname
> (with the
> underscore converted) so the memory has been reallocated.
> 
> 
> diff -up crash-6.0.0/extensions/libsial/sial_func.c.orig
> crash-6.0.0/extensions/libsial/sial_func.c
> --- crash-6.0.0/extensions/libsial/sial_func.c.orig	2011-11-29
> 13:09:43.985631958 +1100
> +++ crash-6.0.0/extensions/libsial/sial_func.c	2011-11-29
> 13:10:31.930603477 +1100
> @@ -280,8 +280,14 @@ sial_freefile(fdata *fd)
>  		}
>  
>  		/* free the associated static and global variables */
> -		if(fd->fsvs) sial_freesvs(fd->fsvs);
> -		if(fd->fgvs) sial_freesvs(fd->fgvs);
> +		if(fd->fsvs) {
> +			sial_freesvs(fd->fsvs);
> +			fd->fsvs = NULL;
> +		}
> +		if(fd->fgvs) {
> +			sial_freesvs(fd->fgvs);
> +			fd->fgvs = NULL;
> +		}
>  
>  		/* free all function nodes */
>                  // let debugger know ...
> 
> --
> Crash-utility mailing list
> Crash-utility at redhat.com
> https://www.redhat.com/mailman/listinfo/crash-utility
> 




More information about the Crash-utility mailing list