aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPhil Elwell <phil@raspberrypi.org>2017-09-24 10:20:49 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-10-18 09:09:45 -0400
commitc97d96b4e612c7dc1b37d7afc61b598a9a25994d (patch)
tree0e6b16525e082f13bf06a31c9a4fb5e09e9655a0
parentaa444bd230f832d4e75cfac826255cfd66f545c3 (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.c19
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;
433err_free_mem:
434 kfree(vchi_instance);
435 430
436 return ret; 431 return 0;
437} 432}
438 433
439int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream) 434int bcm2835_audio_open(struct bcm2835_alsa_stream *alsa_stream)