Bug 1200167

Summary: Socket::getnameinfo() refuses tainted value with "addr is not a string" exception
Product: Red Hat Enterprise Linux 7 Reporter: Peter Robinson <pbrobinson>
Component: perl-SocketAssignee: Jitka Plesnikova <jplesnik>
Status: CLOSED ERRATA QA Contact: David Kutálek <dkutalek>
Severity: high Docs Contact: Marc Muehlfeld <mmuehlfe>
Priority: high    
Version: 7.1CC: almond27579, brian, centos, conathan, dkutalek, info, isenfeld, jan, jcasale, joakim, jplesnik, mail, mmuehlfe, ovasik, pbrobinson, pekkas, ppisar, qguo, rocketraman, zpytela
Target Milestone: rcKeywords: Patch, Reopened
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: perl-Socket-2.010-4.el7 Doc Type: Bug Fix
Doc Text:
The "Socket::getnameinfo" module now works correctly with tainted values Previously, the Perl "Socket::getnameinfo" module failed to process tainted values. This update applies a patch and as a result, the module now works correctly with tainted values.
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-04 00:19:47 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1203710, 1289025, 1295829, 1313485    
Attachments:
Description Flags
Upstream fix ported to 2.010 none

Description Peter Robinson 2015-03-09 21:50:07 UTC
perl-Mail-DKIM is used Sign and verify Internet mail with DKIM/DomainKey but the version shipped (0.39) with el7 is broken with the version of perl-Net-DNS (0.72) shipped with el7 (in fact broken with anything >= 0.69)

The errors you get when running spamassassin is:
Mar  9 21:23:33 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.


Details are in upstream bug https://rt.cpan.org/Public/Bug/Display.html?id=83170

There's a number of other improvements/fixes in the upstream 0.40 release:

Version 0.40 - released 2013-02-07

  * New/changed functionality:
    * a single DNS resolver is created for the lifetime of the program,
      rather than reinitializing the resolver for each new query.

  * bugfixes:
    * fix the error message given when an invalid algorithm is
      specified in the construction of Mail::DKIM::Signer.
    * avoid Perl warning about use of an undefined value in several
      places (rt.cpan.org issue #82913).
    * speed- improved performance of parsing the message into lines
      (rt.cpan.org issue #77902). Patch by Mark Martinec.
    * fix DNS queries to use the correct method (txtdata) of Net::DNS
      (rt.cpan.org issue #83170). Patch by Mark Martinec.

  * API changes:
    * global subroutines resolver() or enable_EDNS0() in module
      Mail::DKIM::DNS can be called to specify non-default options
      to Net::DNS::Resolver (see also rt.cpan.org issue #80425).

Latest version is at http://www.cpan.org/authors/id/J/JA/JASLONG/

Comment 1 Peter Robinson 2015-03-09 21:51:02 UTC
Exact NVR is perl-Mail-DKIM-0.39-8.el7.noarch on RHEL 7.1

Comment 2 Petr Pisar 2015-03-10 08:01:32 UTC
We will not rebase to 0.40 because it changes API. We can try to port to fix back to 0.39. However to prioritize your request properly, please contact Red Hat support.

Comment 3 Petr Pisar 2015-03-10 08:32:51 UTC
Could you provide a pure Mail::DKIM reproducer? I could not reproduce it with /usr/share/doc/perl-Mail-DKIM-0.39/scripts/dkimverify.pl script on any of the e-mails from corpus directory in the Mail-DKIM sources. I could see some warning about undefined value, but no error about bad usage of IO::Socket::IP::_get_host_service().

Comment 4 Peter Robinson 2015-03-10 12:56:57 UTC
(In reply to Petr Pisar from comment #3)
> Could you provide a pure Mail::DKIM reproducer? I could not reproduce it

It's easily reproducible with spamassassin. Basically every time it tries to look up a SPF record in DNS it fails with:

Mar  9 22:07:40 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:07:40 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:12:19 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:13:18 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:13:18 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:20:51 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:20:51 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:24:52 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Mar  9 22:24:52 mail spamd[3263]: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.

I don't have a local reproducer, I'm not a perl coder and it was easier to take the Fedora version and rebuild it and put it in place. 

It's well documented in the upstream bug reports

https://rt.cpan.org/Public/Bug/Display.html?id=83170
https://bz.apache.org/SpamAssassin/show_bug.cgi?id=6872

The newer version works fine with spamassassin 3.4 which is the only package in RHEL that depends on it. Not tested amavisd-new but that's in EPEL

repoquery --whatrequires perl-Mail-DKIM
amavisd-new-0:2.9.1-5.el7.noarch
spamassassin-0:3.3.2-18.el7.x86_64
spamassassin-0:3.4.0-1.el7.x86_64

Comment 5 Peter Robinson 2015-03-10 13:01:18 UTC
(In reply to Petr Pisar from comment #2)
> We will not rebase to 0.40 because it changes API. We can try to port to fix
> back to 0.39. However to prioritize your request properly, please contact
> Red Hat support.

Ultimately you as the maintainer need to make that decision, it's badly broken with spamassassin when using some DNS situations (google for the string from the logs above) which is a core part of it's functionality because both public domain keys and SPF records are stored in DNS.

Comment 6 Petr Pisar 2015-03-10 13:06:37 UTC
(In reply to Peter Robinson from comment #4)
> (In reply to Petr Pisar from comment #3)
> > Could you provide a pure Mail::DKIM reproducer? I could not reproduce it
> 
> It's easily reproducible with spamassassin. Basically every time it tries to
> look up a SPF record in DNS it fails with:
> 
> Mar  9 22:07:40 mail spamd[3263]: spf: lookup failed: addr is not a string
> at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
[...]
> 
> I don't have a local reproducer, I'm not a perl coder and it was easier to
> take the Fedora version and rebuild it and put it in place. 
> 
I'm sorry. If you blame Mail::DKIM, you have to provide Mail::DKIM reproducer. Please contact Red Hat support to help you with it.

Comment 7 Peter Robinson 2015-03-10 13:16:52 UTC
> I'm sorry. If you blame Mail::DKIM, you have to provide Mail::DKIM
> reproducer. Please contact Red Hat support to help you with it.

Err, no, please don't close it. All the details are in the upstream bug report with all the details on how to reproduce it.

I'm not a perl coder, it's not my job to slim down a reproducer, all the details of the problem are in the two upstream BZ. Please go and read them!

Comment 9 Petr Pisar 2015-03-11 09:08:22 UTC
(In reply to Peter Robinson from comment #7)
> > I'm sorry. If you blame Mail::DKIM, you have to provide Mail::DKIM
> > reproducer. Please contact Red Hat support to help you with it.
> 
> Err, no, please don't close it. All the details are in the upstream bug
> report with all the details on how to reproduce it.
>
The upstream report does not provide any reproducer. I really recommend you to   contact Red Hat support team. Bugzilla is not a support channel for Red Hat Enterprise Linux customers.

Comment 10 Petr Pisar 2015-03-11 09:44:44 UTC
Provided your only reproducer is "using spamd", I reassign the issue to spamassassin component. It's maintainer could now more how spamd uses Mail::DKIM.

Comment 11 Jakub Jelen 2015-03-24 14:52:46 UTC
Sorry, but even I can't reproduce your issue. Can you provide at least
1) versions you are using (spamassassin 3.3 or 3.4 -- there was rebase!)
2) special configuration?
when you can't provide any reproducer? I was going through the spamassassin code and how it is handling DKIM and I don't see anything strange.

Can you try to run example verifier from
https://metacpan.org/pod/Mail::DKIM::Verifier
on some of your messages on your system, if it will result in same error?
(Ex. $ cat signed.mail | perl verifier.pl )

Everything I tried ended up without any problem nor messages in journal. Both with plain DKIM and through spamc ( Ex. $ cat signed.mail | spamc -R ).

Comment 12 Pekka Savola 2015-04-02 07:54:48 UTC
I was seeing the same thing until I disabled SPF plugin in init.pre.

But I would suspect this is rather an issue in perl-Mail-SPF. I don't understand why this would be a DKIM problem when SPF validation fails.

Comment 13 Jan Middelkoop 2015-04-06 09:26:14 UTC
More useful information about the relation between spamassassin and perl-Mail-DKIM is here:
http://www.gossamer-threads.com/lists/spamassassin/users/189013#189013

According to that post, it is not a DKIM problem, but rather a bug with perl.  perl >= 5.18 fixes the issue.  Upgrading to a newer DKIM is a suggested fix because that seems to work around the issue, which might be easier to do than upgrade perl.

I am having the same issue.  SPF lookup in spamassassin seems to be broken after recent upgrade, I have clients complaining about receiving a lot of spam in their inbox.  This is a real problem for EL7 servers, which should be addressed quickly IMVHO.

My versions:
perl-5.16.3-285.el7.x86_64
perl-Mail-DKIM-0.39-8.el7.noarch
spamassassin-3.4.0-1.el7.x86_64

Comment 14 Jan Middelkoop 2015-04-06 10:06:49 UTC
Meanwhile, on my system it seems to fixed after obtaining Fedora 19 package "perl-Mail-DKIM-0.40-1.fc19.noarch.rpm" and using yum to install it and its dependencies.  People desperate for a solution might want to try that.

Comment 15 Jakub Jelen 2015-04-07 06:23:37 UTC
same question. Do you have a reproducer? If none of us can reproduce it, we don't know what to fix, especially when the messages are from one component, bug in the second and reproducer is with the third.

Comment 16 Pedro Miguel 2015-04-18 15:06:50 UTC
I also have this bug on a fresh 7.1 machine and can confirm installing "perl-Mail-DKIM-0.40-1.fc19.noarch.rpm" via yum fixed the error's.

Comment 17 Jan Middelkoop 2015-04-19 08:28:13 UTC
Jakub, perhaps it would be best if you gave us some suggestions on how we can create a reproducer.  I'm not a spamassassin developer and not the slighest versed in perl.  In the thread I linked to in comment #13 there is a reproducer for the perl bug, I'm not sure how to create a reproducer for the effects it has on spamassassin, other than to install spamassassin on an EL7 machine and look for errors in the maillog.

Comment 18 Jakub Jelen 2015-04-20 09:48:28 UTC
Jan, reproducer is list of all actions you need to do from fresh rhel7 installation to the error message in maillog. For sure there was missing some point that you should add some message to parse by spamd/spamc, to attach such message, or the use of specific dns resolver.

I have several rhel7 machines and reproducer "Install spamassassin and the logs will show up" doesn't work for me. I have this configuration for long, but no messages in maillog so there is probably something missing. I have all the same versions as you wrote.

Discussion linked in comment #13 gives little bit more clue about the problem (probably the best one for now), it looks like the important thing is using dns resolver 156.154.70.1, but I still have no luck with reproducing. Also it looks like problem with combination of perl version, Net::DNS version and Mail::DKIM version and some of these components will need to take some steps.

Only thing I managed to reproduce was error with pure perl code from [1].


Petr, what do you think about this now? As I browse through the code, I see there is compatibility fix for DNS in PublicKey.pl and Policy.pl in perl-Mail-DKIM-0.40, which should fix this issue.


@@ -105,9 +105,17 @@
 			}
 
 			my $strn;
-			foreach my $ans (@resp) {
-				next unless $ans->type eq "TXT";
-				$strn = join "", $ans->char_str_list;
+			foreach my $rr (@resp) {
+				next unless $rr->type eq "TXT";
+
+				# join with no intervening spaces, RFC 6376
+				if (Net::DNS->VERSION >= 0.69) {
+					# must call txtdata() in a list context
+					$strn = join "", $rr->txtdata;
+				} else {
+					# char_str_list method is 'historical'
+					$strn = join "", $rr->char_str_list;
+				}
 				last;
 			}


[1] http://www.gossamer-threads.com/lists/spamassassin/users/189005#189005

Comment 19 Peter Robinson 2015-04-20 10:31:43 UTC
> logs will show up" doesn't work for me. I have this configuration for long,
> but no messages in maillog so there is probably something missing. I have
> all the same versions as you wrote.

What DNS servers are you using? I've not had time to dig further as I've been busy with $dayjob and updating to 0.40 fixed it for me, but it appears if you use opendns or google DNS (8.8.8.8 etc) that it works, and if you use something else (I use IPA/bind with upstream ISP forwarders) it seems to cause issues although I've not tested straight to google because I need internal IPA infra

Comment 20 Raman Gupta 2015-04-20 13:19:42 UTC
I use CentOS 7.1 rather than RHEL, so take the following for whatever its worth.

I see these error messages in my logs every time a mail is processed by amavisd-new 2.9.1 which comes from the EPEL repository:

Apr 20 13:12:42 linode1 amavis[32133]: (32133-13) _WARN: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.
Apr 20 13:12:42 linode1 amavis[32133]: (32133-13) _WARN: spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.

As shown by Peter's repoquery, amavisd-new seems to be using perl-Mail-DKIM internally.

Like Peter, my DNS server is a local caching DNS server (bind) which recurses to my ISP. I have IPV6 enabled.

Comment 21 Petr Pisar 2015-04-20 15:23:46 UTC
(In reply to Jakub Jelen from comment #18)
> Discussion linked in comment #13 gives little bit more clue about the
> problem (probably the best one for now), it looks like the important thing
> is using dns resolver 156.154.70.1, but I still have no luck with
> reproducing. Also it looks like problem with combination of perl version,
> Net::DNS version and Mail::DKIM version and some of these components will
> need to take some steps.
> 
> Only thing I managed to reproduce was error with pure perl code from [1].
>
> [1] http://www.gossamer-threads.com/lists/spamassassin/users/189005#189005

This looks like the real reason (besides changes in perl interpreter). Socket upstream applied two compatibility fixes <http://cpansearch.perl.org/src/PEVANS/Socket-2.018/Changes> two months ago both discussed in <https://rt.cpan.org/Public/Bug/Display.html?id=79557>:

2.018   2015/02/12 13:42:41
        [BUGFIXES]
         * Fix for "addr is not a string" test to use SvPOKp() before 5.18

2.017   2015/02/10 12:05:14
[...]
        [BUGFIXES]
         * Remember to SvGETMAGIC in getnameinfo() (RT79557)

I can try to isolate and apply them to RHEL-7's perl-Socket package. I can reproduce the "addr is not a string" error message from the Socket::getnameinfo(). However I cannot reproduce the Net::DNS or Mail::DKIM issue, so I cannot say if helps to the reporter.

> Petr, what do you think about this now? As I browse through the code, I see
> there is compatibility fix for DNS in PublicKey.pl and Policy.pl in
> perl-Mail-DKIM-0.40, which should fix this issue.
> 
> 
> @@ -105,9 +105,17 @@
>  			}
>  
>  			my $strn;
> -			foreach my $ans (@resp) {
> -				next unless $ans->type eq "TXT";
> -				$strn = join "", $ans->char_str_list;
> +			foreach my $rr (@resp) {
> +				next unless $rr->type eq "TXT";
> +
> +				# join with no intervening spaces, RFC 6376
> +				if (Net::DNS->VERSION >= 0.69) {
> +					# must call txtdata() in a list context
> +					$strn = join "", $rr->txtdata;
> +				} else {
> +					# char_str_list method is 'historical'
> +					$strn = join "", $rr->char_str_list;
> +				}
>  				last;
>  			}
> 
> 
This does not do anything important. It only prefers txtdata() over char_str_list() with recent Net::DNS. However the code in RHEL-7 Net::DNS only passes the call from char_str_list() to txtdata():

sub txtdata {
    my $self = shift;

    @{$self}{txtdata} = [map Net::DNS::Text->new($_), @_] if scalar @_;

    my $txtdata = $self->{txtdata} || [];

    return ( map $_->value, @$txtdata ) if wantarray;

    join ' ', map $_->value, @$txtdata if defined wantarray;
}


sub char_str_list {         ## historical
    return (&txtdata);
}

In other words, I don't believe that the quoted patch fixes the reported spamassassin issue.

Comment 22 Petr Pisar 2015-04-20 16:22:58 UTC
(In reply to Petr Pisar from comment #21)
> This looks like the real reason (besides changes in perl interpreter).
> Socket upstream applied two compatibility fixes
> <http://cpansearch.perl.org/src/PEVANS/Socket-2.018/Changes> two months ago
> both discussed in <https://rt.cpan.org/Public/Bug/Display.html?id=79557>:
> 
> 2.018   2015/02/12 13:42:41
>         [BUGFIXES]
>          * Fix for "addr is not a string" test to use SvPOKp() before 5.18
> 
> 2.017   2015/02/10 12:05:14
> [...]
>         [BUGFIXES]
>          * Remember to SvGETMAGIC in getnameinfo() (RT79557)
> 
> I can try to isolate and apply them to RHEL-7's perl-Socket package. I can
> reproduce the "addr is not a string" error message from the
> Socket::getnameinfo(). However I cannot reproduce the Net::DNS or Mail::DKIM
> issue, so I cannot say if helps to the reporter.
> 
Here is a testing (i.e. not supported) build of RHEL-7's perl-Socket package with the deemed fix. Could reporter or other affected person test it whether it resolves the spamassassin issue?

Comment 23 Petr Pisar 2015-04-20 16:23:37 UTC
(In reply to Petr Pisar from comment #22)
> Here is a testing (i.e. not supported) build of RHEL-7's perl-Socket package
> with the deemed fix. Could reporter or other affected person test it whether
> it resolves the spamassassin issue?

There <http://people.redhat.com/~ppisar/perl-Socket-2.010-4.el7/>.

Comment 24 Raman Gupta 2015-04-20 17:05:41 UTC
(In reply to Petr Pisar from comment #22)
> Here is a testing (i.e. not supported) build of RHEL-7's perl-Socket package
> with the deemed fix. Could reporter or other affected person test it whether
> it resolves the spamassassin issue?

Petr, http://people.redhat.com/~ppisar/perl-Socket-2.010-4.el7/ fixes the problem I was seeing with "lookup failed: addr is not a string" reported from amavisd-new on CentOS 7.1.

Comment 25 Pekka Savola 2015-04-20 17:25:49 UTC
With that fix, I also no longer see the errors from spamassassin.

Comment 26 Petr Pisar 2015-04-21 06:09:28 UTC
Thank you for the confirmation.

Comment 27 Petr Pisar 2015-04-21 06:10:05 UTC
Created attachment 1016689 [details]
Upstream fix ported to 2.010

Comment 28 Petr Pisar 2015-04-21 06:46:16 UTC
How to test:

(1) Execute:
$ perl -Te 'use Socket; $s=$ENV{PATH}; $s=qq{2\0\0005\301\2\4\367\0\0\0\0\0\0\0\0}; Socket::getnameinfo($s,Socket::NI_NUMERICHOST|Socket::NI_NUMERICSERV)'
(2) Check exit code:
  Before: The command fails, exit code is non-zero, "addr is not a string at -e line 1." is printed on error output.
  After: The command passes, exit code is zero, no error is printed.

Please note that the test fails only with Perl 5.16.

Comment 29 7stars 2015-06-11 20:15:13 UTC
yes, I can confirm that
perl-Socket-2.010-4.el7_1.x86_64.rpm solves this issue.

So:
wget http://people.redhat.com/ppisar/perl-Socket-2.010-4.el7/perl-Socket-2.010-4.el7_1.x86_64.rpm

AND

yum update perl-Socket-2.010-4.el7_1.x86_64.rpm

automatically replaces the old perl-Socket-2.010-3.el7.x86_64

bye bye ;-)

Comment 32 Dimitris 2016-02-15 06:49:07 UTC
Hello,

any news on the progress of this bug please?

Comment 34 Jitka Plesnikova 2016-03-03 16:12:54 UTC
How to test:
1) Install perl, perl(Socket) and perl(Devel::Peek)
2) Run command

perl -Te 'use Socket; use Devel::Peek; $s=$ENV{PATH}; $s=0; $s="\2\0\0005\301\2\4\367\0\0\0\0\0\0\0\0"; Devel::Peek::Dump($s); Socket::getnameinfo($s,0)' 

Output should not contains any error like "addr is not a string at"

Comment 37 joakim 2016-07-07 08:49:19 UTC
I can confirm that

http://people.redhat.com/ppisar/perl-Socket-2.010-4.el7/perl-Socket-2.010-4.el7_1.x86_64.rpm

Solved the problem on my Centos 7.2.1511 installation with error:

spf: lookup failed: addr is not a string at /usr/share/perl5/vendor_perl/IO/Socket/IP.pm line 662.

Comment 38 Dimitris 2016-07-07 09:42:19 UTC
Since its taking years to fix this problem, I "fixed" it by running SPF checks under Postfix instead of SpamAssassin. Postfix is not a perl application, thus not encumbered by this bug.

Comment 39 Brian J. Murrell 2016-09-30 20:28:42 UTC
I can also confirm that http://people.redhat.com/ppisar/perl-Socket-2.010-4.el7/perl-Socket-2.010-4.el7_1.x86_64.rpm fixes the problem on 7.2.

Can we get this pushed along?

Comment 42 Jitka Plesnikova 2016-10-21 12:02:29 UTC
It looks good to me.

Comment 44 errata-xmlrpc 2016-11-04 00:19:47 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory, and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://rhn.redhat.com/errata/RHBA-2016-2196.html