From 66abd064cb8a8dbcd75311b89eddde7b4d5ac45e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Jul 2020 13:20:09 +0200 Subject: [PATCH 1/4] torture/ndr: make check functions typesafe BUG: https://bugzilla.samba.org/show_bug.cgi?id=14452 Signed-off-by: Stefan Metzmacher --- source4/torture/ndr/lsa.c | 3 +- source4/torture/ndr/ndr.h | 73 ++++++++++++++++++++++++++++++++++----- 2 files changed, 65 insertions(+), 11 deletions(-) diff --git a/source4/torture/ndr/lsa.c b/source4/torture/ndr/lsa.c index c83c5247d59d..6b9a5bcc53d9 100644 --- a/source4/torture/ndr/lsa.c +++ b/source4/torture/ndr/lsa.c @@ -1631,8 +1631,7 @@ static const uint8_t lsarlookupnames3_in_data[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; -static bool lsarlookupnames3_in_check(struct torture_context *tctx, - struct lsa_LookupNames2 *r) +static bool lsarlookupnames3_in_check(struct torture_context *tctx, struct lsa_LookupNames3 *r) { /* FIXME: Handle */ torture_assert_int_equal(tctx, r->in.num_names, 7, "num names"); diff --git a/source4/torture/ndr/ndr.h b/source4/torture/ndr/ndr.h index 0cc21825fb47..84d691e6ced8 100644 --- a/source4/torture/ndr/ndr.h +++ b/source4/torture/ndr/ndr.h @@ -59,6 +59,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( enum ndr_err_code ndr_err); #define torture_suite_add_ndr_pull_test(suite,name,data,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ NULL, \ @@ -67,7 +72,8 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_invalid_data_test(suite,name,data,ndr_err) \ _torture_suite_add_ndr_pull_invalid_data_test( \ @@ -80,6 +86,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( ndr_err); #define torture_suite_add_ndr_pull_fn_test(suite,name,data,flags,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name "_" #flags, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ NULL, \ @@ -88,9 +99,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, 0, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_fn_test_flags(suite,name,data,flags,flags2,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name "_" #flags "_" #flags2, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ NULL, \ @@ -99,9 +116,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, flags2, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_validate_test(suite,name,data,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name "_VALIDATE", \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_push_flags_fn_t)ndr_push_ ## name, \ @@ -110,9 +133,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_validate_test_blob(suite,name,data_blob,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name "_VALIDATE", \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_push_flags_fn_t)ndr_push_ ## name, \ @@ -121,9 +150,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob, \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_validate_test_b64(suite,name,tname,b64,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name "_" tname, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_push_flags_fn_t)ndr_push_ ## name, \ @@ -132,9 +167,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( base64_decode_data_blob_talloc(suite, b64), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pullpush_fn_test_flags(suite,name,data,flags,flags2,check_fn) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pullpush_test(suite, #name, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_push_flags_fn_t)ndr_push_ ## name, \ @@ -143,9 +184,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, flags2, \ - (bool (*) (struct torture_context *, void *)) check_fn); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_io_test(suite,name,data_in,data_out,check_fn_out) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn_out; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT", \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_print_function_t)ndr_print_ ## name, \ @@ -153,9 +200,15 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data_out, sizeof(data_out)), \ sizeof(struct name), \ 0, \ - (bool (*) (struct torture_context *, void *)) check_fn_out); + check_fn_anon); \ + } while(0) #define torture_suite_add_ndr_pull_io_test_flags(suite,name,data_in,data_out,flags,check_fn_out) \ + do { \ + bool (*check_fn_typed) (struct torture_context *, struct name *) = \ + check_fn_out; \ + bool (*check_fn_anon) (struct torture_context *, void *) = \ + (bool (*) (struct torture_context *, void *)) check_fn_typed; \ _torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT_" #flags, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_print_function_t)ndr_print_ ## name, \ @@ -163,5 +216,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( data_blob_const(data_out, sizeof(data_out)), \ sizeof(struct name), \ flags, \ - (bool (*) (struct torture_context *, void *)) check_fn_out); + check_fn_anon); \ + } while(0) + #endif /* __TORTURE_NDR_H__ */ -- 2.17.1 From 99a1338303663a61d2dddffd86d9a6eaeb58bd5c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Jul 2020 13:23:19 +0200 Subject: [PATCH 2/4] torture/ndr: add more details to the test names We can have more than one blob for a given idl function and we should avoid using the same name for all of them. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14452 Signed-off-by: Stefan Metzmacher --- source4/torture/ndr/ndr.c | 19 ++++++++++++++----- source4/torture/ndr/ndr.h | 27 +++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/source4/torture/ndr/ndr.c b/source4/torture/ndr/ndr.c index 690301f31b1d..e0120455f687 100644 --- a/source4/torture/ndr/ndr.c +++ b/source4/torture/ndr/ndr.c @@ -152,10 +152,12 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test( ndr_push_flags_fn_t push_fn, ndr_print_fn_t print_fn, ndr_print_function_t print_function, + const char *db_name, DATA_BLOB db, size_t struct_size, int ndr_flags, int flags, + const char *check_fn_name, bool (*check_fn) (struct torture_context *ctx, void *data)) { struct torture_test *test; @@ -166,8 +168,9 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test( test = talloc(tcase, struct torture_test); - test->name = talloc_strdup(test, name); - test->description = NULL; + test->name = talloc_strdup(test, check_fn_name); + test->description = talloc_asprintf(test, "db:%s", + db_name); test->run = wrap_ndr_pullpush_test; data = talloc_zero(test, struct ndr_pull_test_data); @@ -268,10 +271,13 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test( const char *name, ndr_pull_flags_fn_t pull_fn, ndr_print_function_t print_function, + const char *db_in_name, DATA_BLOB db_in, + const char *db_out_name, DATA_BLOB db_out, size_t struct_size, int flags, + const char *check_fn_name, bool (*check_fn) (struct torture_context *ctx, void *data)) { struct torture_test *test; @@ -282,8 +288,10 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test( test = talloc(tcase, struct torture_test); - test->name = talloc_strdup(test, name); - test->description = NULL; + test->name = talloc_strdup(test, check_fn_name); + test->description = talloc_asprintf(test, "db_in:%s db_out:%s", + db_in_name, + db_out_name); test->run = wrap_ndr_inout_pull_test; data = talloc_zero(test, struct ndr_pull_test_data); data->data = db_out; @@ -333,6 +341,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( struct torture_suite *suite, const char *name, ndr_pull_flags_fn_t pull_fn, + const char *db_name, DATA_BLOB db, size_t struct_size, int ndr_flags, @@ -347,7 +356,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( test = talloc(tcase, struct torture_test); - test->name = talloc_strdup(test, name); + test->name = talloc_strdup(test, db_name); test->description = NULL; test->run = wrap_ndr_pull_invalid_data_test; diff --git a/source4/torture/ndr/ndr.h b/source4/torture/ndr/ndr.h index 84d691e6ced8..8d553b80e15b 100644 --- a/source4/torture/ndr/ndr.h +++ b/source4/torture/ndr/ndr.h @@ -31,10 +31,12 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pullpush_test( ndr_push_flags_fn_t push_fn, ndr_print_fn_t print_fn, ndr_print_function_t print_function, + const char *db_name, DATA_BLOB db, size_t struct_size, int ndr_flags, int flags, + const char *check_fn_name, bool (*check_fn) (struct torture_context *, void *data)); _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test( @@ -42,16 +44,20 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_inout_test( const char *name, ndr_pull_flags_fn_t pull_fn, ndr_print_function_t print_fn, + const char *db_in_name, DATA_BLOB db_in, + const char *db_out_name, DATA_BLOB db_out, size_t struct_size, int flags, + const char *check_fn_name, bool (*check_fn) (struct torture_context *ctx, void *data)); _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( struct torture_suite *suite, const char *name, ndr_pull_flags_fn_t pull_fn, + const char *db_name, DATA_BLOB db, size_t struct_size, int ndr_flags, @@ -69,9 +75,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( NULL, \ (ndr_print_fn_t)ndr_print_ ## name, \ NULL, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -80,6 +88,7 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( suite, \ #name, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ @@ -96,9 +105,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( NULL, \ NULL, \ (ndr_print_function_t)ndr_print_ ## name, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, 0, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -113,9 +124,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( NULL, \ NULL, \ (ndr_print_function_t)ndr_print_ ## name, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, flags2, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -130,9 +143,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( (ndr_push_flags_fn_t)ndr_push_ ## name, \ (ndr_print_fn_t)ndr_print_ ## name, \ NULL, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -147,9 +162,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( (ndr_push_flags_fn_t)ndr_push_ ## name, \ (ndr_print_fn_t)ndr_print_ ## name, \ NULL, \ + #data_blob, \ data_blob, \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -164,9 +181,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( (ndr_push_flags_fn_t)ndr_push_ ## name, \ (ndr_print_fn_t)ndr_print_ ## name, \ NULL, \ + #b64, \ base64_decode_data_blob_talloc(suite, b64), \ sizeof(struct name), \ NDR_SCALARS|NDR_BUFFERS, 0, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -181,9 +200,11 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( (ndr_push_flags_fn_t)ndr_push_ ## name, \ NULL, \ (ndr_print_function_t)ndr_print_ ## name, \ + #data, \ data_blob_const(data, sizeof(data)), \ sizeof(struct name), \ flags, flags2, \ + #check_fn, \ check_fn_anon); \ } while(0) @@ -196,10 +217,13 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( _torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT", \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_print_function_t)ndr_print_ ## name, \ + #data_in, \ data_blob_const(data_in, sizeof(data_in)), \ + #data_out, \ data_blob_const(data_out, sizeof(data_out)), \ sizeof(struct name), \ 0, \ + #check_fn_out, \ check_fn_anon); \ } while(0) @@ -212,10 +236,13 @@ _PUBLIC_ struct torture_test *_torture_suite_add_ndr_pull_invalid_data_test( _torture_suite_add_ndr_pull_inout_test(suite, #name "_INOUT_" #flags, \ (ndr_pull_flags_fn_t)ndr_pull_ ## name, \ (ndr_print_function_t)ndr_print_ ## name, \ + #data_in, \ data_blob_const(data_in, sizeof(data_in)), \ + #data_out, \ data_blob_const(data_out, sizeof(data_out)), \ sizeof(struct name), \ flags, \ + #check_fn_out, \ check_fn_anon); \ } while(0) -- 2.17.1 From 50976e8493dbd7d2df1fdc2c76117ddd4ef1e6d3 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Jul 2020 11:27:10 +0200 Subject: [PATCH 3/4] torture/ndr: reproduce a problem with witness_AsyncNotify Credit Oss-Fuzz REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22175 REF: https://oss-fuzz.com/testcase-detail/5686294157197312 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14452 Signed-off-by: Stefan Metzmacher --- source4/torture/ndr/witness.c | 67 +++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/source4/torture/ndr/witness.c b/source4/torture/ndr/witness.c index 9ba97d3d9deb..9ded49071d89 100644 --- a/source4/torture/ndr/witness.c +++ b/source4/torture/ndr/witness.c @@ -304,6 +304,36 @@ static bool witness_AsyncNotify_check_move_OUT(struct torture_context *tctx, return true; } +static const uint8_t witness_AsyncNotify_data_fuzz1_OUT[] = { + 0x00, 0x00, 0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x02, 0x00, 0x0C, 0x00, 0x00, 0x00, + 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, +}; + +static bool witness_AsyncNotify_check_fuzz1_OUT(struct torture_context *tctx, + struct witness_AsyncNotify *r) +{ + struct witness_notifyResponse *n; + struct witness_IPaddrInfoList *i; + + torture_assert(tctx, r->out.response, "r->out.response"); + + n = *(r->out.response); + + torture_assert_int_equal(tctx, n->type, WITNESS_NOTIFY_CLIENT_MOVE, "type"); + torture_assert_int_equal(tctx, n->length, 12, "length"); + torture_assert_int_equal(tctx, n->num, 1, "num"); + + i = &n->messages[0].client_move; + + torture_assert_int_equal(tctx, i->length, 12, "i->length"); + torture_assert_int_equal(tctx, i->reserved, 0, "i->reserved"); + torture_assert_int_equal(tctx, i->num, 0, "i->num"); + + return true; +} + struct torture_suite *ndr_witness_suite(TALLOC_CTX *ctx) { struct torture_suite *suite = torture_suite_create(ctx, "witness"); @@ -364,5 +394,42 @@ struct torture_suite *ndr_witness_suite(TALLOC_CTX *ctx) 0, witness_AsyncNotify_check_move_OUT); + torture_suite_add_ndr_pull_fn_test(suite, + witness_AsyncNotify, + witness_AsyncNotify_data_fuzz1_OUT, + NDR_OUT, + witness_AsyncNotify_check_fuzz1_OUT); + +#if 0 + /* + * This crashed as ndr_push_witness_IPaddrInfoList->num is 0. + * + * BACKTRACE: + * #0 log_stack_trace + 0x37 [ip=0x7f06f174ae0d] [sp=0x7fff50a82b50] + * #1 smb_panic_log + 0x1c0 [ip=0x7f06f174ad66] [sp=0x7fff50a83440] + * #2 smb_panic + 0x27 [ip=0x7f06f174ada4] [sp=0x7fff50a83470] + * #3 fault_report + 0x8d [ip=0x7f06f174a8ce] [sp=0x7fff50a834a0] + * #4 sig_fault + 0x24 [ip=0x7f06f174a8f2] [sp=0x7fff50a83550] + * #5 funlockfile + 0x50 [ip=0x7f06efeb68a0] [sp=0x7fff50a83580] + * #6 __nss_passwd_lookup + 0x24861 [ip=0x7f06ef26f811] [sp=0x7fff50a83c18] + * #7 inet_pton + 0x2b [ip=0x7f06ef2246ab] [sp=0x7fff50a83c20] + * #8 is_ipaddress_v4 + 0x37 [ip=0x7f06f1758c37] [sp=0x7fff50a83c70] + * #9 is_ipaddress + 0x27 [ip=0x7f06f1758f4b] [sp=0x7fff50a83ca0] + * #10 ndr_push_ipv4address + 0x2e [ip=0x7f06f19fbe62] [sp=0x7fff50a83cd0] + * #11 ndr_push_witness_IPaddrInfo + 0x11b [ip=0x7f06f1222cd5] [sp=0x7fff50a83d10] + * #12 ndr_size_struct + 0x8d [ip=0x7f06f1a02820] [sp=0x7fff50a83d70] + * #13 ndr_size_witness_IPaddrInfo + 0x41 [ip=0x7f06f12230f8] [sp=0x7fff50a83dc0] + * #14 ndr_push_witness_IPaddrInfoList + 0xd9 [ip=0x7f06f12231e7] [sp=0x7fff50a83df0] + * #15 ndr_push_witness_notifyResponse_message + 0x15c [ip=0x7f06f1223a3a] [sp=0x7fff50a83e60] + * #16 ndr_push_witness_notifyResponse + 0x28b [ip=0x7f06f122964f] [sp=0x7fff50a83e + */ + torture_suite_add_ndr_pullpush_fn_test_flags(suite, + witness_AsyncNotify, + witness_AsyncNotify_data_fuzz1_OUT, + NDR_OUT, + 0, + witness_AsyncNotify_check_fuzz1_OUT); +#endif + return suite; } -- 2.17.1 From 2005e9eeefb48b84663e775d3b1367201094d99a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Fri, 31 Jul 2020 11:27:25 +0200 Subject: [PATCH 4/4] witness.idl: fix length calculation for witness_IPaddrInfoList If r->num is 0, we should not dereference r->addr. Using ndr_size_witness_IPaddrInfoList() also make this much simpler and avoids the magic 12. Credit Oss-Fuzz REF: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=22175 REF: https://oss-fuzz.com/testcase-detail/5686294157197312 BUG: https://bugzilla.samba.org/show_bug.cgi?id=14452 Signed-off-by: Stefan Metzmacher --- librpc/idl/witness.idl | 6 +++--- source4/torture/ndr/witness.c | 24 ------------------------ 2 files changed, 3 insertions(+), 27 deletions(-) diff --git a/librpc/idl/witness.idl b/librpc/idl/witness.idl index e230a5ea709b..652c0e9cb651 100644 --- a/librpc/idl/witness.idl +++ b/librpc/idl/witness.idl @@ -98,14 +98,14 @@ interface witness WITNESS_IPADDR_OFFLINE = 0x10 } witness_IPaddrInfo_flags; - typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN),gensize] struct { + typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct { witness_IPaddrInfo_flags flags; [flag(NDR_BIG_ENDIAN)] ipv4address ipv4; [flag(NDR_BIG_ENDIAN)] ipv6address ipv6; } witness_IPaddrInfo; - typedef [flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN)] struct { - [value(12+(r->num*ndr_size_witness_IPaddrInfo(r->addr, ndr->flags)))] uint32 length; + typedef [public,flag(NDR_NOALIGN|NDR_LITTLE_ENDIAN),gensize] struct { + [value(ndr_size_witness_IPaddrInfoList(r, ndr->flags))] uint32 length; [value(0)] uint32 reserved; uint32 num; witness_IPaddrInfo addr[num]; diff --git a/source4/torture/ndr/witness.c b/source4/torture/ndr/witness.c index 9ded49071d89..496d04570a91 100644 --- a/source4/torture/ndr/witness.c +++ b/source4/torture/ndr/witness.c @@ -400,36 +400,12 @@ struct torture_suite *ndr_witness_suite(TALLOC_CTX *ctx) NDR_OUT, witness_AsyncNotify_check_fuzz1_OUT); -#if 0 - /* - * This crashed as ndr_push_witness_IPaddrInfoList->num is 0. - * - * BACKTRACE: - * #0 log_stack_trace + 0x37 [ip=0x7f06f174ae0d] [sp=0x7fff50a82b50] - * #1 smb_panic_log + 0x1c0 [ip=0x7f06f174ad66] [sp=0x7fff50a83440] - * #2 smb_panic + 0x27 [ip=0x7f06f174ada4] [sp=0x7fff50a83470] - * #3 fault_report + 0x8d [ip=0x7f06f174a8ce] [sp=0x7fff50a834a0] - * #4 sig_fault + 0x24 [ip=0x7f06f174a8f2] [sp=0x7fff50a83550] - * #5 funlockfile + 0x50 [ip=0x7f06efeb68a0] [sp=0x7fff50a83580] - * #6 __nss_passwd_lookup + 0x24861 [ip=0x7f06ef26f811] [sp=0x7fff50a83c18] - * #7 inet_pton + 0x2b [ip=0x7f06ef2246ab] [sp=0x7fff50a83c20] - * #8 is_ipaddress_v4 + 0x37 [ip=0x7f06f1758c37] [sp=0x7fff50a83c70] - * #9 is_ipaddress + 0x27 [ip=0x7f06f1758f4b] [sp=0x7fff50a83ca0] - * #10 ndr_push_ipv4address + 0x2e [ip=0x7f06f19fbe62] [sp=0x7fff50a83cd0] - * #11 ndr_push_witness_IPaddrInfo + 0x11b [ip=0x7f06f1222cd5] [sp=0x7fff50a83d10] - * #12 ndr_size_struct + 0x8d [ip=0x7f06f1a02820] [sp=0x7fff50a83d70] - * #13 ndr_size_witness_IPaddrInfo + 0x41 [ip=0x7f06f12230f8] [sp=0x7fff50a83dc0] - * #14 ndr_push_witness_IPaddrInfoList + 0xd9 [ip=0x7f06f12231e7] [sp=0x7fff50a83df0] - * #15 ndr_push_witness_notifyResponse_message + 0x15c [ip=0x7f06f1223a3a] [sp=0x7fff50a83e60] - * #16 ndr_push_witness_notifyResponse + 0x28b [ip=0x7f06f122964f] [sp=0x7fff50a83e - */ torture_suite_add_ndr_pullpush_fn_test_flags(suite, witness_AsyncNotify, witness_AsyncNotify_data_fuzz1_OUT, NDR_OUT, 0, witness_AsyncNotify_check_fuzz1_OUT); -#endif return suite; } -- 2.17.1