libcam: NULL out freed ccb.cdm.matches and ccb.cdm.patterns pointers
to avoid double frees
MFC after: 1 week
Sponsored by: Dell EMC Isilon
Differential D9970
libcam: NULL out freed `ccb.cdm.matches` and `ccb.cdm.patterns` pointers to avoid double frees ngie on Mar 12 2017, 6:05 AM. Authored by Tags None Referenced Files
Subscribers
Details libcam: NULL out freed ccb.cdm.matches and ccb.cdm.patterns pointers MFC after: 1 week $ sudo ln -sfh 'abort:true,junk:true' /etc/malloc.conf $ (cd lib/libcam/; make; sudo make install; cd tests; sudo make check) ===> tests (all) (cd /usr/src/lib/libcam/tests && DEPENDFILE=.depend.libcam_test NO_SUBDIR=1 make -f /usr/src/lib/libcam/tests/Makefile _RECURSING_PROGS=t PROG=libcam_test ) install -C -o root -g wheel -m 444 libcam.a /usr/lib/ install -C -o root -g wheel -m 444 libcam_p.a /usr/lib/ install -s -o root -g wheel -m 444 libcam.so.7 /lib/ install -o root -g wheel -m 444 libcam.so.7.debug /usr/lib/debug/lib/ install -l rs /lib/libcam.so.7 /usr/lib/libcam.so install -C -o root -g wheel -m 444 /usr/src/lib/libcam/camlib.h /usr/include/ install -o root -g wheel -m 444 cam.3.gz /usr/share/man/man3/ install -o root -g wheel -m 444 cam_cdbparse.3.gz /usr/share/man/man3/ rm -f /usr/share/man/man3/cam_open_device.3 /usr/share/man/man3/cam_open_device.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_open_device.3.gz rm -f /usr/share/man/man3/cam_open_spec_device.3 /usr/share/man/man3/cam_open_spec_device.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_open_spec_device.3.gz rm -f /usr/share/man/man3/cam_open_btl.3 /usr/share/man/man3/cam_open_btl.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_open_btl.3.gz rm -f /usr/share/man/man3/cam_open_pass.3 /usr/share/man/man3/cam_open_pass.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_open_pass.3.gz rm -f /usr/share/man/man3/cam_close_device.3 /usr/share/man/man3/cam_close_device.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_close_device.3.gz rm -f /usr/share/man/man3/cam_close_spec_device.3 /usr/share/man/man3/cam_close_spec_device.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_close_spec_device.3.gz rm -f /usr/share/man/man3/cam_getccb.3 /usr/share/man/man3/cam_getccb.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_getccb.3.gz rm -f /usr/share/man/man3/cam_send_ccb.3 /usr/share/man/man3/cam_send_ccb.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_send_ccb.3.gz rm -f /usr/share/man/man3/cam_freeccb.3 /usr/share/man/man3/cam_freeccb.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_freeccb.3.gz rm -f /usr/share/man/man3/cam_path_string.3 /usr/share/man/man3/cam_path_string.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_path_string.3.gz rm -f /usr/share/man/man3/cam_device_dup.3 /usr/share/man/man3/cam_device_dup.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_device_dup.3.gz rm -f /usr/share/man/man3/cam_device_copy.3 /usr/share/man/man3/cam_device_copy.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_device_copy.3.gz rm -f /usr/share/man/man3/cam_get_device.3 /usr/share/man/man3/cam_get_device.3.gz; install -l h /usr/share/man/man3/cam.3.gz /usr/share/man/man3/cam_get_device.3.gz rm -f /usr/share/man/man3/csio_build.3 /usr/share/man/man3/csio_build.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_build.3.gz rm -f /usr/share/man/man3/csio_build_visit.3 /usr/share/man/man3/csio_build_visit.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_build_visit.3.gz rm -f /usr/share/man/man3/csio_decode.3 /usr/share/man/man3/csio_decode.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_decode.3.gz rm -f /usr/share/man/man3/csio_decode_visit.3 /usr/share/man/man3/csio_decode_visit.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_decode_visit.3.gz rm -f /usr/share/man/man3/buff_decode.3 /usr/share/man/man3/buff_decode.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/buff_decode.3.gz rm -f /usr/share/man/man3/buff_decode_visit.3 /usr/share/man/man3/buff_decode_visit.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/buff_decode_visit.3.gz rm -f /usr/share/man/man3/csio_encode.3 /usr/share/man/man3/csio_encode.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_encode.3.gz rm -f /usr/share/man/man3/csio_encode_visit.3 /usr/share/man/man3/csio_encode_visit.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/csio_encode_visit.3.gz rm -f /usr/share/man/man3/buff_encode_visit.3 /usr/share/man/man3/buff_encode_visit.3.gz; install -l h /usr/share/man/man3/cam_cdbparse.3.gz /usr/share/man/man3/buff_encode_visit.3.gz ===> tests (install) install -o root -g wheel -m 444 Kyuafile /usr/tests/lib/libcam/Kyuafile (cd /usr/src/lib/libcam/tests && DEPENDFILE=.depend.libcam_test NO_SUBDIR=1 make -f /usr/src/lib/libcam/tests/Makefile _RECURSING_PROGS=t PROG=libcam_test install) install -s -o root -g wheel -m 555 libcam_test /usr/tests/lib/libcam/libcam_test install -o root -g wheel -m 444 libcam_test.debug /usr/lib/debug/usr/tests/lib/libcam/libcam_test.debug libcam_test:cam_close_device_negative_test_NULL -> passed [0.003s] libcam_test:cam_freeccb_negative_test_NULL -> passed [0.003s] libcam_test:cam_getccb_positive_test -> passed [0.004s] libcam_test:cam_open_device_negative_test_O_RDONLY -> passed [0.003s] libcam_test:cam_open_device_negative_test_nonexistent -> passed [0.003s] libcam_test:cam_open_device_negative_test_unprivileged -> passed [0.003s] libcam_test:cam_open_device_positive_test -> passed [0.003s] Results file id is usr_tests_lib_libcam.20170312-060125-145326 Results saved to /root/.kyua/store/results.usr_tests_lib_libcam.20170312-060125-145326.db 7/7 passed (0 failed) $ sudo camcontrol devlist <VMware, VMware Virtual S 1.0> at scbus2 target 0 lun 0 (da0,pass0) <VMware, Virtual CD-ROM 1.0> at scbus2 target 1 lun 0 (pass1,cd0) $
Diff Detail
Event TimelineComment Actions I like setting persistent things to NULL after free, but setting local variables to NULL after free on the 'exit' path of the function is actually harmful: Either the compiler will generate code that wastes cycles in what could be a critical path, or it will optimize it away and maybe issue a warning.... Neither outcome is good, and there's no benefit to doing this.
Comment Actions I forgot to reply to this portion of the comment: could you please provide an example of this? I know that running free/munmap on a large collection of memory pages can eat up a lot of time unnecessarily on exit, but I'm not quite sure I understand the negative effects you're mentioning above. Comment Actions Right. The variables you set are local variables. This doesn't affect the caller. As such, setting them is totally useless. It's a write to a variable that's subsequently not used. Compilers will warn about that. If you were setting it in the caller somehow, I'd agree with you. But these are useless. In other words foo(char *ptr) { free(ptr); ptr=NULL); bar(...) At /*here*/ p will still contain the return value of stuff() because ptr is local to foo(). setting it in foo won't prevent a subsequent foo() call from freeing it again. So it can't possibly prevent anything. And compiler technology has started warning for this sort of thing (though maybe not this exact thing). See gcc's -Wunused-but-set-variable and -Wunused-but-set-parameter warnings.
Comment Actions Remove useless variable NULLing after free for values. As noted by imp, the values are local to the function and not pointers of This is a reminder to me to pay attention to types more before just making |