summaryrefslogtreecommitdiff
path: root/pidl
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2021-05-22 18:40:13 +1200
committerDouglas Bagnall <dbagnall@samba.org>2021-06-02 03:56:36 +0000
commit3bc680c1e38bef75d5b212992e15f094c523923b (patch)
treee49d92cfa4079786a243329868a80d86a7916ad0 /pidl
parenta7d4f93cfdee0a2005be11880f8dd31f55149369 (diff)
downloadsamba-3bc680c1e38bef75d5b212992e15f094c523923b.tar.gz
pidl: Avoid leaving array_size NDR tokens around
In many cases these can and should be consumed as soon as they are used. This is not a complete fix, we don't clean up the array_size token after using it split between an NDR_SCALARS and an NDR_BUFFERS pass, but it is much better than it was and helps the winbind case with a large number of groups (eg 100,000) as otherwise we hit the 65535 NDR token limit. (This is an arbitary Samba-only limit to avoid DoS conditions) BUG: https://bugzilla.samba.org/show_bug.cgi?id=14710 Signed-off-by: Andrew Bartlett <abartlet@samba.org> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Diffstat (limited to 'pidl')
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm17
1 files changed, 15 insertions, 2 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index 5927e973c32..db992aa9e47 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -342,11 +342,17 @@ sub ParseArrayPullGetSize($$$$$$)
my $array_size = "size_$e->{NAME}_$l->{LEVEL_INDEX}";
- if ($l->{IS_CONFORMANT}) {
+ if ($l->{IS_CONFORMANT} and (defined($l->{SIZE_IS}) or not $l->{IS_ZERO_TERMINATED})) {
$self->pidl("NDR_CHECK(ndr_get_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
+ } elsif ($l->{IS_CONFORMANT}) {
+ # This will be the last use of the array_size token
+ $self->pidl("NDR_CHECK(ndr_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", &$array_size));");
+
} elsif ($l->{IS_ZERO_TERMINATED} and $l->{SIZE_IS} == 0 and $l->{LENGTH_IS} == 0) { # Noheader arrays
$size = "ndr_get_string_size($ndr, sizeof(*$var_name))";
$self->pidl("$array_size = $size;");
+
} else {
$size = ParseExprExt($l->{SIZE_IS}, $env, $e->{ORIGINAL},
check_null_pointer($e, $env, sub { $self->pidl(shift); },
@@ -443,7 +449,14 @@ sub ParseArrayPullHeader($$$$$$)
check_null_pointer($e, $env, sub { $self->defer(shift); },
"return ndr_pull_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL Pointer for size_is()\");"),
check_fully_dereferenced($e, $env));
- $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ if (ContainsDeferred($e, $l)) {
+ # We will be needing the array_size token in
+ # the NDR_BUFFERS call, so don't steal it now
+ $self->defer("NDR_CHECK(ndr_check_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ } else {
+ # This will be deferred until after the last ndr_get_array_size()
+ $self->defer("NDR_CHECK(ndr_check_steal_array_size($ndr, (void*)" . get_pointer_to($var_name) . ", $size));");
+ }
$self->defer_deindent;
$self->defer("}");
}