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: Vladimir Sementsov-Ogievskiy
Subject: Re: [Qemu-devel] [PATCH] migration: Fix use-after-free during process exit
Date: Fri, 13 Sep 2019 13:43:16 +0000

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.


> +
>   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

reply via email to

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