On Tue, Sep 29, 2026 at 08:23:20PM +0300, Andrey Drobyshev wrote:
> In its current form, the mechanism for saving CPR FDs into hash table
> has flaws.
> 
> The CPR fd hash table uses the same CprFd for both key and value, and
> is created with a key destroy function.  Inserting a second element
> with the same (name, id) key leads to a use after free.  According to
> GLib docs [1], g_hash_table_insert() keeps the old key, replaces the
> value with the new element, and destroys the new key.  Thus when
> inserting 2 CprFd elements fd1 and fd2 with equal keys we get:
> 
>   g_hash_table_insert(table, fd1, fd1);  /* table has fd1 -> fd1 */
>   g_hash_table_insert(table, fd2, fd2);  /* table has fd1 -> fd2, fd2 freed */
> 
> Any subsequent cpr_find_fd() for that key then returns freed memory.
> 
> This is reachable whenever two CPR-aware objects register fds under the
> same name, and it happens long before an actual CPR, since cpr_save_fd()
> is typically called from .realize(), i.e. at boot time.
> 
> Apart from the UAF itself, when the user decides to perform CPR migration,
> on CPR target we'd get corrupted FD from the hash table and fail somewhere
> in .realize() for affected devices.
> 
> As a solution, let's altogether prohibit adding CprFds with duplicate
> keys.  Since FDs are being registered for a subsequent CPR right at the
> startup in .realize(), that'll allow us to error out and exit QEMU (or
> fail a device hotplug op) gracefully instead of delaying potential
> problems for later.  To do so, let's make cpr_save_fd() return 'bool'
> instead of 'void' and provide an 'errp' argument to it.  That way caller
> becomes responsible for checking the return value and propagating the
> error.
> 
> Also update all the callers to use the adjusted interface to keep things
> compilable and bisectable.
> 
> [1] https://docs.gtk.org/glib/type_func.HashTable.insert.html
> 
> Fixes: a181df93bb3 ("migration/cpr: use hashtable for cpr fds")
> Signed-off-by: Andrey Drobyshev <[email protected]>

Reviewed-by: Peter Xu <[email protected]>

-- 
Peter Xu


Reply via email to