qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH] migration: Fix use-after-free during process ex


From: Yury Kotov
Subject: Re: [Qemu-devel] [PATCH] migration: Fix use-after-free during process exit
Date: Fri, 13 Sep 2019 17:42:53 +0300

Hi Vladimir!

13.09.2019, 16:43, "Vladimir Sementsov-Ogievskiy" <address@hidden>:
> Hi!
>
> 08.04.2019 14:33, Yury Kotov wrote:
>>  It fixes heap-use-after-free which was found by clang's ASAN.
>>
>>  Control flow of this use-after-free:
>>  main_thread:
>>       * Got SIGTERM and completes main loop
>>       * Calls migration_shutdown
>>         - migrate_fd_cancel (so, migration_thread begins to complete)
>>         - object_unref(OBJECT(current_migration));
>>
>>  migration_thread:
>>       * migration_iteration_finish -> schedule cleanup bh
>>       * object_unref(OBJECT(s)); (Now, current_migration is freed)
>>       * exits
>>
>>  main_thread:
>>       * Calls vm_shutdown -> drain bdrvs -> main loop
>>         -> cleanup_bh -> use after free
>
> [..]
>
>>  +static void migrate_fd_cleanup_schedule(MigrationState *s)
>>  +{
>>  + /* Ref the state for bh, because it may be called when
>>  + * there're already no other refs */
>>  + object_ref(OBJECT(s));
>>  + qemu_bh_schedule(s->cleanup_bh);
>>  +}
>
> so you ref on scheduling
>
>>  +
>>  +static void migrate_fd_cleanup_bh(void *opaque)
>>  +{
>>  + MigrationState *s = opaque;
>>  + migrate_fd_cleanup(s);
>>  + object_unref(OBJECT(s));
>>  +}
>
> and unref after execution of bh.
>
> but migration code has also call to qemu_bh_delete(s->cleanup_bh) from
> migrate_fd_cleanup(), in migrate_fd_cleanup() is called not only from
> migrate_fd_cleanup_bh..
>
> I mean, that if we call qemu_bh_delete after scheduling, we will not
> unref our new reference.
>
> Still, seems it's impossible, as all other calls to migrate_fd_cleanup
> are done before migration thread creation.
>
> Don't know, should something done around it or not, but decided to mention it.
>

Hmm.. It's very interesting, thanks! I need more time to understand
is there a problem or not, but after quick look I see one possibility
to achieve a leak: qmp_migrate after cleanup bh schedule and before bh call...

>>  +
>>    void migrate_set_error(MigrationState *s, const Error *error)
>>    {
>>        qemu_mutex_lock(&s->error_mutex);
>>  @@ -3144,7 +3157,7 @@ static void migration_iteration_finish(MigrationState 
>> *s)
>>            error_report("%s: Unknown ending state %d", __func__, s->state);
>>            break;
>>        }
>>  - qemu_bh_schedule(s->cleanup_bh);
>>  + migrate_fd_cleanup_schedule(s);
>>        qemu_mutex_unlock_iothread();
>>    }
>>
>>  @@ -3279,7 +3292,7 @@ void migrate_fd_connect(MigrationState *s, Error 
>> *error_in)
>>        bool resume = s->state == MIGRATION_STATUS_POSTCOPY_PAUSED;
>>
>>        s->expected_downtime = s->parameters.downtime_limit;
>>  - s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup, s);
>>  + s->cleanup_bh = qemu_bh_new(migrate_fd_cleanup_bh, s);
>>        if (error_in) {
>>            migrate_fd_error(s, error_in);
>>            migrate_fd_cleanup(s);
>
> --
> Best regards,
> Vladimir

Regards,
Yury



reply via email to

[Prev in Thread] Current Thread [Next in Thread]