diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-12-10 22:16:35 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:06:29 -0500 |
commit | 9f9e9b6477c4037372f871495abe7b81f15fb58c (patch) | |
tree | 21dce7965d26e0f785efa3dc598fab405556bac6 /source4/build/pidl/parser.pm | |
parent | 6fb61740076f49a6e0ac3eaff5c8002e316cfe90 (diff) | |
download | samba-9f9e9b6477c4037372f871495abe7b81f15fb58c.tar.gz samba-9f9e9b6477c4037372f871495abe7b81f15fb58c.tar.bz2 samba-9f9e9b6477c4037372f871495abe7b81f15fb58c.zip |
r4136: when we have a size or switch variable that is a pointer we need to check that the server
hasn't given us a null pointer, otherwise we can segv when we dereference it. For example:
[size_is(*size)] *x;
uint32 *size;
if a broken server gave us x != NULL and size == NULL then we would crash. I've added
a check_null_pointer() call in pidl to catch this.
(This used to be commit 8cbd3f47a95367e861c6b99c44416a9ccef3c9ca)
Diffstat (limited to 'source4/build/pidl/parser.pm')
-rw-r--r-- | source4/build/pidl/parser.pm | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/source4/build/pidl/parser.pm b/source4/build/pidl/parser.pm index 59912cecd4..375558e5dc 100644 --- a/source4/build/pidl/parser.pm +++ b/source4/build/pidl/parser.pm @@ -106,6 +106,17 @@ sub find_size_var($$$) die "invalid variable in $size for element $e->{NAME} in $fn->{NAME}\n"; } +##################################################################### +# check that a variable we get from find_size_var isn't a null pointer +sub check_null_pointer($) +{ + my $size = shift; + if ($size =~ /^\*/) { + my $size2 = substr($size, 1); + pidl "\tif ($size2 == NULL) return NT_STATUS_INVALID_PARAMETER_MIX;\n"; + } +} + ##################################################################### # work out is a parse function should be declared static or not @@ -277,11 +288,13 @@ sub CheckArraySizes($$) if (util::has_property($e, "size_is")) { my $size = find_size_var($e, util::array_size($e), $var_prefix); + check_null_pointer($size); pidl "\tNDR_CHECK(ndr_check_array_size(ndr, (void*)&$var_prefix$e->{NAME}, $size));\n"; } if (my $length = util::has_property($e, "length_is")) { $length = find_size_var($e, $length, $var_prefix); + check_null_pointer($length); pidl "\tNDR_CHECK(ndr_check_array_length(ndr, (void*)&$var_prefix$e->{NAME}, $length));\n"; } } @@ -302,7 +315,7 @@ sub ParseArrayPull($$$) # we allocate enough to pull the elements if (defined $e->{CONFORMANT_SIZE}) { $alloc_size = $e->{CONFORMANT_SIZE}; - + check_null_pointer($size); pidl "\tif ($size > $alloc_size) {\n"; pidl "\t\treturn ndr_pull_error(ndr, NDR_ERR_CONFORMANT_SIZE, \"Bad conformant size %u should be %u\", $alloc_size, $size);\n"; pidl "\t}\n"; @@ -337,6 +350,7 @@ sub ParseArrayPull($$$) $size = "ndr_get_array_length(ndr, &$var_prefix$e->{NAME})"; } + check_null_pointer($size); if (util::is_scalar_type($e->{TYPE})) { pidl "\t\tNDR_CHECK(ndr_pull_array_$e->{TYPE}(ndr, $ndr_flags, $var_prefix$e->{NAME}, $size));\n"; } else { @@ -431,6 +445,9 @@ sub ParseElementPullSwitch($$$$) my $cprefix = util::c_pull_prefix($e); my $utype = $structs{$e->{TYPE}}; + + check_null_pointer($switch_var); + if (!defined $utype || !util::has_property($utype->{DATA}, "nodiscriminant")) { my $e2 = find_sibling($e, $switch); @@ -473,6 +490,8 @@ sub ParseElementPushSwitch($$$$) my $switch_var = find_size_var($e, $switch, $var_prefix); my $cprefix = util::c_push_prefix($e); + check_null_pointer($switch_var); + my $utype = $structs{$e->{TYPE}}; if (!defined $utype || !util::has_property($utype->{DATA}, "nodiscriminant")) { @@ -502,6 +521,8 @@ sub ParseElementPrintSwitch($$$) my $switch_var = find_size_var($e, $switch, $var_prefix); my $cprefix = util::c_push_prefix($e); + check_null_pointer($switch_var); + pidl "\tndr_print_$e->{TYPE}(ndr, \"$e->{NAME}\", $switch_var, $cprefix$var_prefix$e->{NAME});\n"; } @@ -718,6 +739,7 @@ sub ParseStructPush($) if (defined $e->{ARRAY_LEN} && $e->{ARRAY_LEN} eq "*") { my $size = find_size_var($e, util::array_size($e), "r->"); $e->{CONFORMANT_SIZE} = $size; + check_null_pointer($size); pidl "\tNDR_CHECK(ndr_push_uint32(ndr, $size));\n"; } @@ -878,6 +900,7 @@ sub ParseStructNdrSize($) pidl "\tret = ndr_size_ptr(ret, &r->$e->{NAME}, flags); \n"; } elsif (util::is_inline_array($e)) { $sizevar = find_size_var($e, util::array_size($e), "r->"); + check_null_pointer($sizevar); pidl "\t{\n"; pidl "\t\tint i;\n"; pidl "\t\tfor(i = 0; i < $sizevar; i++) {\n"; @@ -1399,6 +1422,7 @@ sub AllocateRefVars($) # its an array my $size = find_size_var($e, $asize, "r->out."); + check_null_pointer($size); pidl "\tNDR_ALLOC_N(ndr, r->out.$e->{NAME}, $size);\n"; if (util::has_property($e, "in")) { pidl "\tmemcpy(r->out.$e->{NAME},r->in.$e->{NAME},$size * sizeof(*r->in.$e->{NAME}));\n"; |