diff options
author | Phil Elwell <phil@raspberrypi.org> | 2017-09-24 10:20:49 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-10-18 09:09:45 -0400 |
commit | c97d96b4e612c7dc1b37d7afc61b598a9a25994d (patch) | |
tree | 0e6b16525e082f13bf06a31c9a4fb5e09e9655a0 | |
parent | aa444bd230f832d4e75cfac826255cfd66f545c3 (diff) |
staging: bcm2835-audio: Fix memory corruption
The previous commit (0adbfd46) fixed a memory leak but also freed a
block in the success case, causing a stale pointer to be used with
potentially fatal results. Only free the vchi_instance block in the
case that vchi_connect fails; once connected, the instance is
retained for subsequent connections.
Simplifying the code by removing a bunch of gotos and returning errors
directly.
Signed-off-by: Phil Elwell <phil@raspberrypi.org>
Fixes: 0adbfd4694c2 ("staging: bcm2835-audio: fix memory leak in bcm2835_audio_open_connection()")
Cc: stable <stable@vger.kernel.org> # 4.12+
Tested-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | 19 |
1 files changed, 7 insertions, 12 deletions
diff --git a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c index 5f3d8f2339e3..4be864dbd41c 100644 --- a/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/vc04_services/bcm2835-audio/bcm2835-vchiq.c | |||
@@ -390,8 +390,7 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream | |||
390 | __func__, instance); | 390 | __func__, instance); |
391 | instance->alsa_stream = alsa_stream; | 391 | instance->alsa_stream = alsa_stream; |
392 | alsa_stream->instance = instance; | 392 | alsa_stream->instance = instance; |
393 | ret = 0; // xxx todo -1; | 393 | return 0; |
394 | goto err_free_mem; | ||
395 | } | 394 | } |
396 | 395 | ||
397 | /* Initialize and create a VCHI connection */ | 396 | /* Initialize and create a VCHI connection */ |
@@ -401,16 +400,15 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream | |||
401 | LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", | 400 | LOG_ERR("%s: failed to initialise VCHI instance (ret=%d)\n", |
402 | __func__, ret); | 401 | __func__, ret); |
403 | 402 | ||
404 | ret = -EIO; | 403 | return -EIO; |
405 | goto err_free_mem; | ||
406 | } | 404 | } |
407 | ret = vchi_connect(NULL, 0, vchi_instance); | 405 | ret = vchi_connect(NULL, 0, vchi_instance); |
408 | if (ret) { | 406 | if (ret) { |
409 | LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", | 407 | LOG_ERR("%s: failed to connect VCHI instance (ret=%d)\n", |
410 | __func__, ret); | 408 | __func__, ret); |
411 | 409 | ||
412 | ret = -EIO; | 410 | kfree(vchi_instance); |
413 | goto err_free_mem; | 411 | return -EIO; |
414 | } | 412 | } |
415 | initted = 1; | 413 | initted = 1; |
416 | } | 414 | } |
@@ -421,19 +419,16 @@ static int bcm2835_audio_open_connection(struct bcm2835_alsa_stream *alsa_stream | |||
421 | if (IS_ERR(instance)) { | 419 | if (IS_ERR(instance)) { |
422 | LOG_ERR("%s: failed to initialize audio service\n", __func__); | 420 | LOG_ERR("%s: failed to initialize audio service\n", __func__); |
423 | 421 | ||
424 | ret = PTR_ERR(instance); | 422 | /* vchi_instance is retained for use the next time. */ |
425 | goto err_free_mem; | 423 | return PTR_ERR(instance); |
426 | } | 424 | } |
427 | 425 | ||
428 | instance->alsa_stream = alsa_stream; | 426 | instance->alsa_stream = alsa_stream; |
429 | alsa_stream->instance = instance; | 427 | alsa_stream->instance = instance; |
430 | 428 | ||
431 | LOG_DBG(" success !\n"); | 429 | LOG_DBG(" success !\n"); |
432 | ret = 0; | ||
433 | err_free_mem: | ||
434 | kfree(vchi_instance); | ||
435 | 430 | ||
436 | return ret; | 431 | return 0; |
437 | } | 432 | } |
438 | 433 | ||
439 | int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) | 434 | int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) |