The power-of-two validation did not reject size=0, since
(0 & (0-1)) == 0. With a zero size, the ring buffer mask wraps
to SIZE_MAX, causing out-of-bounds memory access. Use
is_power_of_2() which handles zero correctly.

Reported-by: Pavee Hui <[email protected]>
Fixes: bf51f62869f4 ("char: move ringbuf/memory to its own file")
Signed-off-by: Marc-André Lureau <[email protected]>
---
 chardev/char-ringbuf.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/chardev/char-ringbuf.c b/chardev/char-ringbuf.c
index 8f998d26a49f..a80519f8d65d 100644
--- a/chardev/char-ringbuf.c
+++ b/chardev/char-ringbuf.c
@@ -27,6 +27,7 @@
 #include "qapi/error.h"
 #include "qapi/qapi-commands-char.h"
 #include "qemu/base64.h"
+#include "qemu/host-utils.h"
 #include "qemu/module.h"
 #include "qemu/option.h"
 #include "qom/object.h"
@@ -102,7 +103,7 @@ static bool ringbuf_chr_open(Chardev *chr,
     d->size = opts->has_size ? opts->size : 65536;
 
     /* The size must be power of 2 */
-    if (d->size & (d->size - 1)) {
+    if (!is_power_of_2(d->size)) {
         error_setg(errp, "size of ringbuf chardev must be power of two");
         return false;
     }

-- 
2.56.0.rc0.29.g47ce80527c56


Reply via email to