[v5a,0/5] timers: Use timer_shutdown*() before freeing timers

Message ID 20221106054535.709068702@goodmis.org
Headers
Series timers: Use timer_shutdown*() before freeing timers |

Message

Steven Rostedt Nov. 6, 2022, 5:45 a.m. UTC
  del_timer_sync() is often called before the object that owns the timer is
freed. But sometimes there's a race that enables the timer again before it is
freed and causes a use after free when that timer triggers. This patch set
adds a new "shutdown" timer state, which is set on the new timer_shutdown()
API. Once a timer is in this state, it can not be re-armed and if it is, it
will warn.

The first three patches change existing timer_shutdown() functions used
locally in ARM and some drivers to better namespace names.

The fourth patch implements the new API.

The fifth patch is now a treewide patch that uses a coccinelle script to
convert the trivial locations where a del_timer*() is called on a timer of an
object that is freed immediately afterward (or at least in the same function).

Changes since v4a: https://lore.kernel.org/all/20221105060024.598488967@goodmis.org/

- Used more consistent names to rename the generic timer_shutdown() code
  (Guenter Roeck, Marc Zyngier)

- Remove del_singleshot_timer_sync() change and the fix that it required.

- Improved the coccinelle script such that the fifth patch is unmodified.



Steven Rostedt (Google) (5):
      ARM: spear: Do not use timer namespace for timer_shutdown() function
      clocksource/drivers/arm_arch_timer: Do not use timer namespace for timer_shutdown() function
      clocksource/drivers/sp804: Do not use timer namespace for timer_shutdown() function
      timers: Add timer_shutdown_sync() and timer_shutdown() to be called before freeing timers
      treewide: Convert del_timer*() to timer_shutdown*()

----
 .../RCU/Design/Requirements/Requirements.rst       |  2 +-
 Documentation/core-api/local_ops.rst               |  2 +-
 Documentation/kernel-hacking/locking.rst           |  5 ++
 arch/arm/mach-spear/time.c                         |  8 +--
 arch/sh/drivers/push-switch.c                      |  2 +-
 block/blk-iocost.c                                 |  2 +-
 block/blk-iolatency.c                              |  2 +-
 block/kyber-iosched.c                              |  2 +-
 drivers/acpi/apei/ghes.c                           |  2 +-
 drivers/atm/idt77252.c                             |  4 +-
 drivers/block/drbd/drbd_main.c                     |  2 +-
 drivers/block/loop.c                               |  2 +-
 drivers/bluetooth/hci_bcsp.c                       |  2 +-
 drivers/bluetooth/hci_qca.c                        |  4 +-
 drivers/clocksource/arm_arch_timer.c               | 12 ++--
 drivers/clocksource/timer-sp804.c                  |  6 +-
 drivers/gpu/drm/i915/i915_sw_fence.c               |  2 +-
 drivers/hid/hid-wiimote-core.c                     |  2 +-
 drivers/input/keyboard/locomokbd.c                 |  2 +-
 drivers/input/keyboard/omap-keypad.c               |  2 +-
 drivers/input/mouse/alps.c                         |  2 +-
 drivers/isdn/mISDN/l1oip_core.c                    |  4 +-
 drivers/isdn/mISDN/timerdev.c                      |  4 +-
 drivers/leds/trigger/ledtrig-activity.c            |  2 +-
 drivers/leds/trigger/ledtrig-heartbeat.c           |  2 +-
 drivers/leds/trigger/ledtrig-pattern.c             |  2 +-
 drivers/leds/trigger/ledtrig-transient.c           |  2 +-
 drivers/media/pci/ivtv/ivtv-driver.c               |  2 +-
 drivers/media/usb/pvrusb2/pvrusb2-hdw.c            | 16 +++---
 drivers/media/usb/s2255/s2255drv.c                 |  4 +-
 drivers/net/ethernet/intel/i40e/i40e_main.c        |  6 +-
 drivers/net/ethernet/marvell/sky2.c                |  2 +-
 drivers/net/ethernet/sun/sunvnet.c                 |  2 +-
 drivers/net/usb/sierra_net.c                       |  2 +-
 drivers/net/wireless/intel/iwlwifi/iwl-dbg-tlv.c   |  2 +-
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c       |  2 +-
 drivers/net/wireless/intersil/hostap/hostap_ap.c   |  2 +-
 drivers/net/wireless/marvell/mwifiex/main.c        |  2 +-
 drivers/net/wireless/microchip/wilc1000/hif.c      |  6 +-
 drivers/nfc/pn533/pn533.c                          |  2 +-
 drivers/nfc/pn533/uart.c                           |  2 +-
 drivers/pcmcia/bcm63xx_pcmcia.c                    |  2 +-
 drivers/pcmcia/electra_cf.c                        |  2 +-
 drivers/pcmcia/omap_cf.c                           |  2 +-
 drivers/pcmcia/pd6729.c                            |  4 +-
 drivers/pcmcia/yenta_socket.c                      |  4 +-
 drivers/scsi/qla2xxx/qla_edif.c                    |  4 +-
 drivers/staging/media/atomisp/i2c/atomisp-lm3554.c |  2 +-
 drivers/tty/n_gsm.c                                |  2 +-
 drivers/tty/sysrq.c                                |  2 +-
 drivers/usb/gadget/udc/m66592-udc.c                |  2 +-
 drivers/usb/serial/garmin_gps.c                    |  2 +-
 drivers/usb/serial/mos7840.c                       |  4 +-
 fs/ext4/super.c                                    |  2 +-
 fs/nilfs2/segment.c                                |  2 +-
 include/linux/timer.h                              | 62 +++++++++++++++++++--
 kernel/time/timer.c                                | 64 ++++++++++++----------
 net/802/garp.c                                     |  2 +-
 net/802/mrp.c                                      |  4 +-
 net/bridge/br_multicast.c                          |  8 +--
 net/bridge/br_multicast_eht.c                      |  4 +-
 net/core/gen_estimator.c                           |  2 +-
 net/ipv4/ipmr.c                                    |  2 +-
 net/ipv6/ip6mr.c                                   |  2 +-
 net/mac80211/mesh_pathtbl.c                        |  2 +-
 net/netfilter/ipset/ip_set_list_set.c              |  2 +-
 net/netfilter/ipvs/ip_vs_lblc.c                    |  2 +-
 net/netfilter/ipvs/ip_vs_lblcr.c                   |  2 +-
 net/netfilter/xt_LED.c                             |  2 +-
 net/rxrpc/conn_object.c                            |  2 +-
 net/sched/cls_flow.c                               |  2 +-
 net/sunrpc/svc.c                                   |  2 +-
 net/tipc/discover.c                                |  2 +-
 net/tipc/monitor.c                                 |  2 +-
 sound/i2c/other/ak4117.c                           |  2 +-
 sound/synth/emux/emux.c                            |  2 +-
 76 files changed, 203 insertions(+), 144 deletions(-)
  

Comments

Guenter Roeck Nov. 6, 2022, 5:08 p.m. UTC | #1
On Sun, Nov 06, 2022 at 01:45:35AM -0400, Steven Rostedt wrote:
> 
> del_timer_sync() is often called before the object that owns the timer is
> freed. But sometimes there's a race that enables the timer again before it is
> freed and causes a use after free when that timer triggers. This patch set
> adds a new "shutdown" timer state, which is set on the new timer_shutdown()
> API. Once a timer is in this state, it can not be re-armed and if it is, it
> will warn.
> 
> The first three patches change existing timer_shutdown() functions used
> locally in ARM and some drivers to better namespace names.
> 
> The fourth patch implements the new API.
> 
> The fifth patch is now a treewide patch that uses a coccinelle script to
> convert the trivial locations where a del_timer*() is called on a timer of an
> object that is freed immediately afterward (or at least in the same function).
> 

Series looks good in my testbed.

Build results:
	total: 152 pass: 152 fail: 0
Qemu test results:
	total: 500 pass: 500 fail: 0

No runtime warnings reported.

For the series:

Tested-by: Guenter Roeck <linux@roeck-us.net>

Guenter
  
Steven Rostedt Nov. 6, 2022, 6:25 p.m. UTC | #2
On Sun, 6 Nov 2022 09:08:11 -0800
Guenter Roeck <linux@roeck-us.net> wrote:

> For the series:
> 
> Tested-by: Guenter Roeck <linux@roeck-us.net>

Thanks Guenter!

Now I guess the question is, is this good enough, and if so, who's
going to take it?

-- Steve
  
Viresh Kumar Nov. 7, 2022, 5:47 a.m. UTC | #3
On 06-11-22, 01:45, Steven Rostedt wrote:
> From: "Steven Rostedt (Google)" <rostedt@goodmis.org>
> 
> A new "shutdown" timer state is being added to the generic timer code. One
> of the functions to change the timer into the state is called
> "timer_shutdown()". This means that there can not be other functions
> called "timer_shutdown()" as the timer code owns the "timer_*" name space.
> 
> Rename timer_shutdown() to spear_timer_shutdown() to avoid this conflict.
> 
> Link: https://lore.kernel.org/all/20221105060155.228348078@goodmis.org/
> 
> Cc: Viresh Kumar <vireshk@kernel.org>
> Cc: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: soc@kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Acked-by: Arnd Bergmann <arnd@arndb.de>
> Reviewed-by: Guenter Roeck <linux@roeck-us.net>
> Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>

I just replied to the previous version, ignore that now :)

Acked-by: Viresh Kumar <viresh.kumar@linaro.org>

Thanks.