背景
最近移植TI电量计芯片bq40z50的驱动,移植完毕后,能正常读取电池信息了,但是无意中发现驱动卸载会导致Linux卡死,死前终端闪过大量打印,将putty的缓冲区都耗尽了,必须启用syslog转发并用visual syslog server接收才能全部看到:
虽然实际应用中一般不会卸载此类驱动,但考虑到后果严重,还是想解决一下。
问题根因
其实,这是一个double free
BUG。
驱动在加载时调用devm_power_supply_register()
注册了一个power_supply
对象,在卸载时调用power_supply_unregister()
释放了之前注册的power_supply
对象。
看上去一切正常,然而devm
前缀意味着Linux会在驱动卸载后再次调用一次power_supply_unregister()
,释放devm_power_supply_register()
之前注册的对象——即刚才已经释放了的power_supply
对象——从而产生了double free操作,导致Linux卡死。