]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/commit
Save the last callout function executed on each CPU
authorvangyzen <vangyzen@FreeBSD.org>
Wed, 3 Jul 2019 19:22:44 +0000 (19:22 +0000)
committervangyzen <vangyzen@FreeBSD.org>
Wed, 3 Jul 2019 19:22:44 +0000 (19:22 +0000)
commit6e00d86b09c0bee950f3dc48908d49b441955206
tree535f10674ec735e1b14f8b64dc269b1239ea0b08
parent06e97e4aa591f9fccd30a2bb6fa3df6ce878e12e
Save the last callout function executed on each CPU

Save the last callout function pointer (and its argument) executed
on each CPU for inspection by a debugger.  Add a ddb `show callout_last`
command to show these pointers.  Add a kernel module that I used
for testing that command.

Relocate `ce_migration_cpu` to reduce padding and therefore preserve
the size of `struct callout_cpu` (320 bytes on amd64) despite the
added members.

This should help diagnose reference-after-free bugs where the
callout's mutex has already been freed when `softclock_call_cc`
tries to unlock it.

You might hope that the pointer would still be available, but it
isn't.  The argument to that function is on the stack (because
`softclock_call_cc` uses it later), and that might be enough in
some cases, but even then, it's very laborious.  A pointer to the
callout is saved right before these newly added fields, but that
callout might have been freed.  We still have the pointer to its
associated mutex, and the name within might be enough, but it might
also have been freed.

Reviewed by: markj jhb
MFC after: 2 weeks
Sponsored by: Dell EMC Isilon
Differential Revision: https://reviews.freebsd.org/D20794
sys/kern/kern_timeout.c
tools/test/callout_free/Makefile [new file with mode: 0644]
tools/test/callout_free/callout_free.c [new file with mode: 0644]