[Patch] fix IDL hang

Noel Power nopower at suse.com
Thu Aug 7 05:22:59 MDT 2014


Hi,

issuing

./pidl/pidl --header --ndr-parser -- foo.idl

will cause pidl to hang, the attached patch prevents the recursion that
triggers that. Note: I compared the contents of
bin/default/librpc/gen_ndr before and after the patch and the contents
are identical

Noel
-------------- next part --------------
>From f524baef07c27ea4aba1a7527fcda12cfcb5f247 Mon Sep 17 00:00:00 2001
From: Noel Power <noel.power at suse.com>
Date: Wed, 6 Aug 2014 11:32:19 +0100
Subject: [PATCH] detect and prevent recursions (that cause infinite loops)

add recusrion detection logic for can_contain_deferred & align_type
functions
---
 pidl/lib/Parse/Pidl/NDR.pm | 71 +++++++++++++++++++++++++++++++++++++---------
 1 file changed, 58 insertions(+), 13 deletions(-)

diff --git a/pidl/lib/Parse/Pidl/NDR.pm b/pidl/lib/Parse/Pidl/NDR.pm
index 6827152..95964b0 100644
--- a/pidl/lib/Parse/Pidl/NDR.pm
+++ b/pidl/lib/Parse/Pidl/NDR.pm
@@ -402,16 +402,37 @@ sub can_contain_deferred($)
 
 	return 0 if (Parse::Pidl::Typelist::is_scalar($type));
 
-	return can_contain_deferred($type->{DATA}) if ($type->{TYPE} eq "TYPEDEF");
+	if ( not defined($type->{INCANCONTAINDERRED})) {
+		$type->{INCANCONTAINDERRED} = 0;
+	}
+
+	my $res;
+
+	if ($type->{INCANCONTAINDERRED} == 1 ){
+		$res = 0;
+		goto out;
+	}
 
-	return 0 unless defined($type->{ELEMENTS});
+	$type->{INCANCONTAINDERRED} = 1;
+	if ($type->{TYPE} eq "TYPEDEF") {
+		$res = can_contain_deferred($type->{DATA});
+		goto out;
+	}
+
+	if (!defined($type->{ELEMENTS})) {
+		$res = 0;
+		goto out;
+	}
 
 	foreach (@{$type->{ELEMENTS}}) {
-		return 1 if ($_->{POINTERS});
-		return 1 if (can_contain_deferred ($_->{TYPE}));
+		if (($_->{POINTERS}) || can_contain_deferred ($_->{TYPE})) {
+			$res = 1;
+			goto out;
+		}
 	}
-	
-	return 0;
+out:
+	$type->{INCANCONTAINDERRED} = 0;
+	return $res;
 }
 
 sub pointer_type($)
@@ -481,23 +502,47 @@ sub align_type($)
 
 	my $dt = getType($e);
 
+	if ( not defined($dt->{INGETALIGNTYPE})) {
+		$dt->{INGETALIGNTYPE} = 0;
+	}
+
+	my $res;
+	if ($dt->{INGETALIGNTYPE} == 1 ){
+		# reset it
+		$res = 0;
+		goto out;
+	}
+
+	$dt->{INGETALIGNTYPE} = 1;
+
 	if ($dt->{TYPE} eq "TYPEDEF") {
-		return align_type($dt->{DATA});
+		$res = align_type($dt->{DATA});
+		goto out;
 	} elsif ($dt->{TYPE} eq "CONFORMANCE") {
-		return $dt->{DATA}->{ALIGN};
+		$res = $dt->{DATA}->{ALIGN};
+		goto out;
 	} elsif ($dt->{TYPE} eq "ENUM") {
-		return align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+		$res = align_type(Parse::Pidl::Typelist::enum_type_fn($dt));
+		goto out;
 	} elsif ($dt->{TYPE} eq "BITMAP") {
-		return align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+		$res = align_type(Parse::Pidl::Typelist::bitmap_type_fn($dt));
+		goto out;
 	} elsif (($dt->{TYPE} eq "STRUCT") or ($dt->{TYPE} eq "UNION")) {
 		# Struct/union without body: assume 4
-		return 4 unless (defined($dt->{ELEMENTS}));
-		return find_largest_alignment($dt);
+		$res = 4;
+		if (defined($dt->{ELEMENTS})) {
+			$res = find_largest_alignment($dt);
+		}
+		goto out;
 	} elsif (($dt->{TYPE} eq "PIPE")) {
-		return 5;
+		$res = 5;
+		goto out;
 	}
 
 	die("Unknown data type type $dt->{TYPE}");
+out:
+	$dt->{INGETALIGNTYPE} = 0;
+	return $res;
 }
 
 sub ParseElement($$$)
-- 
1.8.4.5

-------------- next part --------------
A non-text attachment was scrubbed...
Name: foo.idl
Type: text/x-idl
Size: 240 bytes
Desc: not available
URL: <http://lists.samba.org/pipermail/samba-technical/attachments/20140807/c27fadc6/attachment.bin>


More information about the samba-technical mailing list