[vlc-commits] picture_pool: fix potentially invalid allocation size

Rémi Denis-Courmont git at videolan.org
Sat Jun 17 15:29:22 CEST 2017


vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sat Jun 17 16:27:38 2017 +0300| [620501199d418559c151a2d45f62a25578fa576f] | committer: Rémi Denis-Courmont

picture_pool: fix potentially invalid allocation size

Aligned allocation size must be a multiple of its alignment.
In practice, the code worked fine on 64-bits systems. But it failed on
32-bits systems *if* the pool's picture count was odd.

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=620501199d418559c151a2d45f62a25578fa576f
---

 src/misc/picture_pool.c | 21 +++++++++++++--------
 1 file changed, 13 insertions(+), 8 deletions(-)

diff --git a/src/misc/picture_pool.c b/src/misc/picture_pool.c
index fce7dc1c61..0c5ea39822 100644
--- a/src/misc/picture_pool.c
+++ b/src/misc/picture_pool.c
@@ -34,7 +34,9 @@
 #include <vlc_atomic.h>
 #include "picture.h"
 
-static const uintptr_t pool_max = CHAR_BIT * sizeof (unsigned long long);
+#define POOL_MAX (CHAR_BIT * sizeof (unsigned long long))
+
+static_assert ((POOL_MAX & (POOL_MAX - 1)) == 0, "Not a power of two");
 
 struct picture_pool_t {
     int       (*pic_lock)(picture_t *);
@@ -56,7 +58,7 @@ static void picture_pool_Destroy(picture_pool_t *pool)
 
     vlc_cond_destroy(&pool->wait);
     vlc_mutex_destroy(&pool->lock);
-    vlc_free(pool);
+    free(pool);
 }
 
 void picture_pool_Release(picture_pool_t *pool)
@@ -70,8 +72,8 @@ static void picture_pool_ReleasePicture(picture_t *clone)
 {
     picture_priv_t *priv = (picture_priv_t *)clone;
     uintptr_t sys = (uintptr_t)priv->gc.opaque;
-    picture_pool_t *pool = (void *)(sys & ~(pool_max - 1));
-    unsigned offset = sys & (pool_max - 1);
+    picture_pool_t *pool = (void *)(sys & ~(POOL_MAX - 1));
+    unsigned offset = sys & (POOL_MAX - 1);
     picture_t *picture = pool->picture[offset];
 
     free(clone);
@@ -115,11 +117,14 @@ static picture_t *picture_pool_ClonePicture(picture_pool_t *pool,
 
 picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg)
 {
-    if (unlikely(cfg->picture_count > pool_max))
+    if (unlikely(cfg->picture_count > POOL_MAX))
         return NULL;
 
-    picture_pool_t *pool = vlc_memalign(pool_max,
-        sizeof (*pool) + cfg->picture_count * sizeof (picture_t *));
+    picture_pool_t *pool;
+    size_t size = sizeof (*pool) + cfg->picture_count * sizeof (picture_t *);
+
+    size += (-size) & (POOL_MAX - 1);
+    pool = aligned_alloc(POOL_MAX, size);
     if (unlikely(pool == NULL))
         return NULL;
 
@@ -127,7 +132,7 @@ picture_pool_t *picture_pool_NewExtended(const picture_pool_configuration_t *cfg
     pool->pic_unlock = cfg->unlock;
     vlc_mutex_init(&pool->lock);
     vlc_cond_init(&pool->wait);
-    if (cfg->picture_count == pool_max)
+    if (cfg->picture_count == POOL_MAX)
         pool->available = ~0ULL;
     else
         pool->available = (1ULL << cfg->picture_count) - 1;



More information about the vlc-commits mailing list