summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2015-06-11 09:01:24 +0200
committerStefan Metzmacher <metze@samba.org>2015-06-12 17:08:20 +0200
commitcf7e1c7597dac52c4efd37da1d8130899bfd7509 (patch)
treecfb1ee803f5619ef5d0ae8161e217dca8345a540
parent3c97bfe9de538d9f551f2c3d77ee3ab820a39b4a (diff)
downloadsamba-cf7e1c7597dac52c4efd37da1d8130899bfd7509.tar.gz
pidl:NDR/Parser: check [ref] pointers before pushing anything else
This was reported by Coverity as CID 1288527: Null pointer dereferences (REVERSE_INULL) Signed-off-by: Stefan Metzmacher <metze@samba.org> Reviewed-by: Michael Adam <obnox@samba.org>
-rw-r--r--pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm52
1 files changed, 45 insertions, 7 deletions
diff --git a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
index fe5f3900cee..a267fb1680b 100644
--- a/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
+++ b/pidl/lib/Parse/Pidl/Samba4/NDR/Parser.pm
@@ -737,13 +737,15 @@ sub ParsePtrPush($$$$$)
my ($self,$e,$l,$ndr,$var_name) = @_;
if ($l->{POINTER_TYPE} eq "ref") {
- $self->pidl("if ($var_name == NULL) {");
- $self->indent;
- $self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
- $self->deindent;
- $self->pidl("}");
+ if ($l->{LEVEL_INDEX} > 0) {
+ $self->pidl("if ($var_name == NULL) {");
+ $self->indent;
+ $self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
+ $self->deindent;
+ $self->pidl("}");
+ }
if ($l->{LEVEL} eq "EMBEDDED") {
- $self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr));");
+ $self->pidl("NDR_CHECK(ndr_push_ref_ptr(ndr)); /* $var_name */");
}
} elsif ($l->{POINTER_TYPE} eq "relative") {
$self->pidl("NDR_CHECK(ndr_push_relative_ptr1($ndr, $var_name));");
@@ -1331,10 +1333,30 @@ sub ParsePtrPull($$$$$)
$self->pidl("}");
}
+sub CheckRefPtrs($$$$)
+{
+ my ($self,$e,$ndr,$env) = @_;
+
+ return if ContainsPipe($e, $e->{LEVELS}[0]);
+ return if ($e->{LEVELS}[0]->{TYPE} ne "POINTER");
+ return if ($e->{LEVELS}[0]->{POINTER_TYPE} ne "ref");
+
+ my $var_name = $env->{$e->{NAME}};
+ $var_name = append_prefix($e, $var_name);
+
+ $self->pidl("if ($var_name == NULL) {");
+ $self->indent;
+ $self->pidl("return ndr_push_error($ndr, NDR_ERR_INVALID_POINTER, \"NULL [ref] pointer\");");
+ $self->deindent;
+ $self->pidl("}");
+}
+
sub ParseStructPushPrimitives($$$$$)
{
my ($self, $struct, $ndr, $varname, $env) = @_;
+ $self->CheckRefPtrs($_, $ndr, $env) foreach (@{$struct->{ELEMENTS}});
+
# see if the structure contains a conformant array. If it
# does, then it must be the last element of the structure, and
# we need to push the conformant length early, as it fits on
@@ -1834,7 +1856,9 @@ sub ParseUnionPushPrimitives($$$$)
$self->pidl("NDR_CHECK(ndr_push_setup_relative_base_offset1($ndr, $varname, $ndr->offset));");
}
$self->DeclareArrayVariables($el);
- $self->ParseElementPush($el, $ndr, {$el->{NAME} => "$varname->$el->{NAME}"}, 1, 0);
+ my $el_env = {$el->{NAME} => "$varname->$el->{NAME}"};
+ $self->CheckRefPtrs($el, $ndr, $el_env);
+ $self->ParseElementPush($el, $ndr, $el_env, 1, 0);
$self->deindent;
}
$self->pidl("break; }");
@@ -2365,6 +2389,12 @@ sub ParseFunctionPush($$)
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/in/,@{$e->{DIRECTION}})) {
+ $self->CheckRefPtrs($e, $ndr, $env);
+ }
+ }
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (grep(/in/,@{$e->{DIRECTION}})) {
$self->ParseElementPush($e, $ndr, $env, 1, 1);
}
}
@@ -2376,6 +2406,14 @@ sub ParseFunctionPush($$)
$self->indent;
$env = GenerateFunctionOutEnv($fn);
+ EnvSubstituteValue($env, $fn);
+
+ foreach my $e (@{$fn->{ELEMENTS}}) {
+ if (grep(/out/,@{$e->{DIRECTION}})) {
+ $self->CheckRefPtrs($e, $ndr, $env);
+ }
+ }
+
foreach my $e (@{$fn->{ELEMENTS}}) {
if (grep(/out/,@{$e->{DIRECTION}})) {
$self->ParseElementPush($e, $ndr, $env, 1, 1);