CC: | waoki [...] umnh.utah.edu |
Subject: | Segfaults when adding or deleting tainted values |
Hi, another bug reported by a Debian user (see http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=679343):
If Perl is run with taint checking and the 'add' or 'delete' methods on a
Net::LDAP::Entry object are given an attribute with a tainted value, Perl will
segfault when the 'update' method is used.
Simple example:
$ldapentry->add('memberUid' => $sometaintedvariable);
$ldapentry->update($ldaphandle);
print "This line is never reached because Perl crashes\n";
Observed behavior:
Perl interpreter segfaults. (In my testing, valgrind produces a "Conditional
jump or move depends on uninitialised value(s)" warning simply as a result of
'use Net::LDAP'.)
Expected behavior:
Perl interpreter does not segfault
Complicated example follows:
Show quoted text
------- BEGIN EXAMPLE -------
#!/usr/bin/perl -w -T
# This program requires two arguments, a user in LDAP and a group to remove
# that user from.
# This program assumes a Kerberized environment and must be modified to
# work in a different environment.
use Net::LDAP;
use Authen::SASL qw(Cyrus);
use strict;
my %conf;
$conf{'basedn'} = 'PUT YOUR DN HERE';
$conf{'groupsdn'} = 'ou=Groups,' . $conf{'basedn'};
$conf{'ldapserver'} = 'PUT YOUR SERVER HERE';
my $adminuserdn = 'uid=' . getpwuid($<) . "/admin";
sub foo($$$) {
my $lh = $_[0];
my $uid = $_[1];
my $gid = $_[2];
my $results = $lh->search(filter => '(&(objectClass=posixGroup)(cn=' . $gid . '))', base=>$conf{'basedn'});
die "Search returned multiple entries\n" if ($results->count() > 1);
return undef if ($results->count() < 1);
my $group = $results->pop_entry();
die "Got an entry for the wrong group" if ($group->dn ne 'cn=' . $gid . ',' . $conf{'groupsdn'});
$group->changetype('modify');
#$group->add('memberUid' => $uid);
$group->delete('memberUid' => $uid);
print "DEBUG: about to update\n";
print "DEBUG: ${uid}, ${gid}\n";
print $group->update($lh)->error_text(), "\n";
print "DEBUG: updated\n";
print "Removed ${uid} from ${gid} or added it instead\n";
}
my $err;
my $sh = Authen::SASL->new(mechanism=>'GSSAPI') or die "Can't get SASL handle\n";
my $lh = Net::LDAP->new($conf{'ldapserver'}, onerr=>sub{print('LDAP: ' . $_[0]);});
$err = $lh->start_tls(verify=>'require', capath=>'/etc/ssl/certs/');
$err->code && die 'LDAP start_tls: ' . $err->error;
unless ($lh->root_dse()->supported_sasl_mechanism('GSSAPI')) {
die "GSSAPI not supported for some reason\n";
} $err = $lh->bind($adminuserdn, sasl=>$sh, version=>3);
$err->code && die 'LDAP bind: ' . $err->error;
if ($#ARGV != 1) {
die "Usage: crashit3.pl USER GROUP\n";
}
my $user = shift @ARGV;
my $group = shift @ARGV;
$user =~ /(.*)/;
my $notaintuser = $1;
print "Running without tainted attr value\n";
foo($lh, $notaintuser, $group);
print "Running with tained attr value\n";
foo($lh, $user, $group);