Hi Linted,

The buffer overflow occurs when the positional arguments are used.

In the attached example (hello_world.c), the use of positional arguments is deliberate to trigger the buffer overflow; I don't have a real-world example where positional arguments are really necessary and used without taking the format string from an untrusted source. In the attached example, it would be much more natural to use "%s" instead of "%1$s", and this would have avoided entering the problematic code path. The effect of the buffer overflow is not observable externally; it can however be confirmed by applying patch 'uclibc-_vfprintf.c.patch'.


Best regards,
Diego Dias

On 24/10/2023 17:06, linted wrote:
Very nice work Diego!

Is there a POC showing the overflow, as that would make writing unit tests easier?

Also is this vulnerability in the same class as other printf vulnerabilities, where it requires a developer to pass untrusted input as the format string to print?

Thank you!
Linted

On Tue, Oct 24, 2023, 7:16 AM Diego Dias <diego.d...@kernkonzept.com> wrote:

    Dear uclibc-ng developers,

    We have run a static analysis tool (Klocwork) in uclibc and one of
    its
    checkers (ABV.GENERAL) indicates a potential buffer overflow in
    uclibc-ng/src/master/libc/stdio/_vfprintf.c:1045

    The problem occurs as an out-of-bounds access to array 'argtype',
    which
    is a member of 'ppfs_t'. This array has length 'MAX_ARGS'.
    According to
    the static analysis tool, the array can be accessed using index
    'n' of
    value '-1' and '9..254' in the conditional shown below:

    // File: uclibc-ng/src/master/libc/stdio/_vfprintf.c:1045
       if (_is_equal_or_bigger_arg(ppfs->argtype[n], argtype[i])) {
         ppfs->argtype[n] = argtype[i];
       }

    Triggering an out-of-bounds access for 'n=-1' is relatively simply
    when
    using printf or similar functions (e.g. vfprintf). Such out-of-bounds
    access occurs when positional arguments are specified, as in the
    following statement:

       printf("%1$s", "Hello world!");

    Although Klocwork claims that the array might be accessed using
    indexes
    '9..254', we were not able to trigger an out-of-bounds access for
    indexes in this range.

    Kind regards,
    Diego Dias

-- Diego M. Dias, Systems Verification Engineer at Kernkonzept,
    diego.d...@kernkonzept.com
    Phone: +49 351 41883231

    Kernkonzept GmbH at Dresden, Germany, HRB 31129, CEO Dr.-Ing.
    Michael Hohmuth

    _______________________________________________
    devel mailing list -- devel@uclibc-ng.org
    To unsubscribe send an email to devel-le...@uclibc-ng.org


_______________________________________________
devel mailing list --devel@uclibc-ng.org
To unsubscribe send an email todevel-le...@uclibc-ng.org

--
Diego M. Dias, Systems Verification Engineer at 
Kernkonzept,diego.d...@kernkonzept.com
Phone: +49 351 41883231

Kernkonzept GmbH at Dresden, Germany, HRB 31129, CEO Dr.-Ing. Michael Hohmuth
#include <stdio.h>

 int main()
 {
   printf("%1$s", "Hello world!\n");
   return 0;
 }
diff --git a/libc/stdio/_vfprintf.c b/libc/stdio/_vfprintf.c
index fc5d3ff68..2605f6682 100644
--- a/libc/stdio/_vfprintf.c
+++ b/libc/stdio/_vfprintf.c
@@ -1042,6 +1042,15 @@ int attribute_hidden _ppfs_parsespec(ppfs_t *ppfs)
 			}
 			--n;
 			/* Record argtype with largest size (current, new). */
+			if (!(n>=0 && n<9))
+			{
+				if (n==-1)
+					puts("## Buffer-overflow ## [-1]");
+				else if (n==9)
+					puts("## Buffer-overflow ## [9]");
+				else
+					puts("## Buffer-overflow ## [?]");
+			}
 			if (_is_equal_or_bigger_arg(ppfs->argtype[n], argtype[i])) {
 				ppfs->argtype[n] = argtype[i];
 			}
_______________________________________________
devel mailing list -- devel@uclibc-ng.org
To unsubscribe send an email to devel-le...@uclibc-ng.org

Reply via email to