diff options
| author | Benjamin Marzinski <bmarzins@redhat.com> | 2026-04-29 16:21:03 -0400 |
|---|---|---|
| committer | Mikulas Patocka <mpatocka@redhat.com> | 2026-05-04 14:53:09 +0200 |
| commit | 5534cac9b56d8f51343718f71737a69d40cb2bb9 (patch) | |
| tree | 5e27bfd88e7d16bd15a135dc24e53cd2859f35aa /include/linux/timerqueue.h | |
| parent | f6de07611b4a4b31fd6a6f45e2056cc76eb79801 (diff) | |
dm-ima: Fix UAF errors and measuring incorrect context
the dm-ima code did not keep the dm_ima_measure_on_* functions from
running at the same time. This could lead to various errors. If two
processes were updating the device state, one could update the state
first, but the other could measure the state first, causing the the
current device state to appear incorrect. If a table load happened while
a device was resuming, the IMA measurement could report the wrong table
being active. And if two dm_ima_measure_on_* functions ran at the same
time, one of them could free data that the other was accessing, causing
a crash.
All the core dm functions that call a dm_ima_measure_on_* function
update the device state they want to measure under the _hash_lock,
except for do_resume(). But holding the _hash_lock is not a good way to
synchronize these functions. It's a global mutex, that is needed in many
dm operations, and the dm_ima_measure_* functions can sleep, blocking
any dm operation on any device that needs the _hash_lock.
To serialize and order the IMA measurement functions, the
dm_ima_measurements now has two counters, update_idx and measure_idx.
update_idx is incremented while holding the _hash_lock and saved, along
with the device name and uuid, in a dm_ima_context struct. Once the
_hash_lock is dropped, the dm_ima_measure_* function is called. It waits
until measure_idx matches the saved value of update_idx, ensuring that
the updates and measurements happen in the same order if there are
multiple processes changing the device at the same time. Then it
measures the device, updates measure_idx, and wakes up any other
process waiting to do a measurement. This makes sure that the
measurements are serialized and done in the order that the _hash_lock
was acquired in. But they only block other measurements for the same
device, which are unlikely to happen at the same time.
do_resume() is trickier, because it removes the inactive table while
holding the _hash_lock, but doesn't hold it while updating md->map. To
make sure it is also ordered, the IMA code grabs the _hash_lock after
md->map is updated. Then it makes sure that the device isn't being
removed and that another do_resume() hasn't already changed the active
table again, and serializes like the other functions do.
Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
Diffstat (limited to 'include/linux/timerqueue.h')
0 files changed, 0 insertions, 0 deletions
