fuzz:fuzz_conditional_ace_blob lets long generated SDDL fail
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 20 Mar 2024 04:29:52 +0000 (17:29 +1300)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 22 Mar 2024 05:03:35 +0000 (05:03 +0000)
This can legitimately fail, due to e.g. integers being interpreted as
local attributes due to their position (the original data is complete
nonsense, bravely decompiled by sddl_from_conditional_ace).

In the example found the original begins like

00000000  61 72 74 78 02 00 00 00  00 00 00 00 00 03 01 02 |artx............|
00000010  f7 ff ff ff ff ff ff ff  03 01 a1 02 00 3b 00 00 |.............;..|
00000020  00 00 00 00 03 01 a1 02  00 3b 00 00 00 00 00 00 |.........;......|
00000030  03 01 02 a5 ff ff ff ff  ff ff ff 03 01 a1 02 78 |...............x|
00000040  00 00 00 00 00 00 00 03  01 85 02 00 3b 00 00 00 |............;...|
00000050  00 00 00 03 01 a1 02 00  3b 00 00 00 00 00 00 03 |........;.......|
00000060  01 02 a5 00 00 00 00 00  00 00 03 01 81 02 00 00 |................|
00000070  00 00 00 00 00 00 03 01  81 02 00 3b 00 00 00 00 |...........;....|

while the SDDL cycled version looks like

00000000  61 72 74 78 f8 04 00 00  00 30 00 30 00 f8 2e 00 |artx.....0.0....|
00000010  00 00 30 00 31 00 37 00  37 00 37 00 37 00 37 00 |..0.1.7.7.7.7.7.|
00000020  37 00 37 00 37 00 37 00  37 00 37 00 37 00 37 00 |7.7.7.7.7.7.7.7.|
00000030  37 00 37 00 37 00 37 00  37 00 37 00 36 00 37 00 |7.7.7.7.7.7.6.7.|
00000040  a1 f8 0c 00 00 00 30 00  33 00 35 00 34 00 30 00 |......0.3.5.4.0.|
00000050  30 00 a1 f8 0c 00 00 00  30 00 33 00 35 00 34 00 |0.......0.3.5.4.|
00000060  30 00 30 00 f8 2e 00 00  00 30 00 31 00 37 00 37 |0.0......0.1.7.7|
00000070  00 37 00 37 00 37 00 37  00 37 00 37 00 37 00 37 |.7.7.7.7.7.7.7.7|

and this new interpretation ends up being more than 10000 bytes long,
so the conversion fails.

The SDDL ends up looking like this:

  (((((((((((00) || (01777777777777777777767)) || (035400)) || \
  (((((((((((((((((((((((((((((((((((035400) || (01777777777777777777645)) \
  >= 0170) || (035400)) || (((((((((((((((((((((((((((((((035400 != 0245)
  [...]

where all the octal digits on the left hand side of operators are
UTF-16 strings.

REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65322

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/fuzzing/fuzz_conditional_ace_blob.c

index ebbd90883aa8e8bec56f1831cb4dab5dabfabbe7..504ed2e14a1a94c1eabd6699104a0b906ac1a9ce 100644 (file)
@@ -124,7 +124,18 @@ int LLVMFuzzerTestOneInput(const uint8_t *input, size_t len)
 
        ok = conditional_ace_encode_binary(mem_ctx, s2, &e2);
        if (! ok) {
-               abort();
+               if (len < CONDITIONAL_ACE_MAX_LENGTH / 4) {
+                       /*
+                        * long invalid ACEs can easily result in SDDL that
+                        * would compile to an over-long ACE, which fail
+                        * accordingly.
+                        *
+                        * But if the original ACE less than a few thousand
+                        * bytes, and it has been serialised into SDDL, that
+                        * SDDL should be parsable.
+                        */
+                       abort();
+               }
        }
 
        /*