https://bz.apache.org/SpamAssassin/show_bug.cgi?id=8432

            Bug ID: 8432
           Summary: TCP fallback for truncated UDP replies ignores the
                    port from dns_server [ip]:port; retries go to port 53
                    and fail
           Product: Spamassassin
           Version: SVN Trunk (Latest Devel Version)
          Hardware: PC
                OS: Linux
            Status: NEW
          Severity: major
          Priority: P2
         Component: spamassassin
          Assignee: [email protected]
          Reporter: [email protected]
  Target Milestone: Undefined

`Mail::SpamAssassin::DnsResolver::load_resolver()` strips the port from
`dns_server` entries when configuring the underlying Net::DNS::Resolver object:
                                                                               
                                                                               
                                                                               
                                                            ```perl            
                                                                               
                                                                               
                                              my @ns_addr_port =
$self->available_nameservers();                                                
                                                                               
                                               # drop port numbers,
Net::DNS::Resolver can't take them                                             
                                                                               
                                             @ns_addr_port =
map(/^\[(.*)\]:(\d+)\z/ ? $1 : $_, @ns_addr_port);                             
                                                                               
                                                 
$res->nameservers(@ns_addr_port);                                              
                                                                               
                                                                  ```          
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                      This is fine for SA's own async query
engine (which honors `[ip]:port`), but the bug 8225 TCP-fallback code
(DnsResolver.pm, ~line 846, `# bug 8225 - Do TCP fallback ... by retrying using
Net::DNS::Resolver bgsend and bgread`) retries through that same port-stripped
resolver. With a resolver configured on a nonstandard port (e.g. `dns_server
127.0.0.1:5352` for a local unbound), the retry is sent to port 53, where
nothing listens. The retry times out after the hardcoded `udp_timeout(3)` and
`bgread()` returns undef without setting `$!` or `$@`, producing the low-signal
error:                                                                         
                                                                               
                                                                               
                                                                               
        ```                                                                    
                                                                               
                                                                          info:
dns: bad dns tcp fallback reply: errno=                                        
                                                                               
                                                            ```                
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
                                Consequences: every lookup whose reply exceeds
the UDP payload size silently fails. Most visibly this breaks SPF:
`T_SPF_TEMPERROR` for any sender domain with a large TXT record set (e.g.
github.com, TXT currently 1928 bytes), and raises scan times from ~8 s to ~36 s
because SPF burns its full timeout budget waiting for the fallback that never
returns.                                                                       
                                                                               
                                                                               
                                                                               
            ## Steps to reproduce                                              
                                                                               
                                                                               
                                                                               
                                                                               
                                                                1. Run a local
recursive resolver on a nonstandard port; configure `dns_server
127.0.0.1:5352`. Nothing must listen on 127.0.0.1:53.                          
                                                                   2. Scan a
message from a domain whose TXT answer exceeds the UDP payload size:           
                                                                               
                                                           `spamassassin -D
dns,spf < message.eml`                                                         
                                                                               
                                              3. Observed (SA 4.0.2, Net::DNS
1.54):                                                                         
                                                                               
                                                                               
                                                                               
                                                                               
                    ```                                                        
                                                                               
                                                                               
      dbg: dns: bgsend, DNS servers: [127.0.0.1]:5352                          
                                                                               
                                                                        dbg:
dns: bgread: received 39 bytes from 127.0.0.1      # truncated UDP reply, TC
set                                                                            
                                                                dbg: dns: TCP
fallback retry with github.com, TXT, IN                                        
                                                                               
                                                    info: dns: bad dns tcp
fallback reply: errno=           # after ~3 s                                  
                                                                               
                                           dbg: spf: ... result: temperror ...
Time-out on DNS 'TXT' lookup of 'github.com'                                   
                                                                               
                              ```
                                                                               
                                                                               
                                                                  Control: with
the same resolver reachable on port 53 and `dns_server 127.0.0.1`, the fallback
succeeds and SPF returns pass. A plain Net::DNS::Resolver created with `port =>
5352` performs the identical UDP-truncation → TCP retry sequence correctly,
which isolates the failure to SA's port stripping.                             
                                                                               
                                                                               
                                                                               
                                                                               
                            ## Current status in trunk                         
                                                                               
                                                                               
                                                                               
                                                                               
                                                                               
Both the port-stripping in `load_resolver()` and the fallback delegating to
`get_resolver()` are unchanged in trunk HEAD (checked in the GitHub mirror,
lib/Mail/SpamAssassin/DnsResolver.pm as of commit 67445fc, 2025-01-16). The
related recent commit 67445fc only switches Plugin/DKIM.pm to SA's custom
resolver; it does not address the reopened 8225 issue.

-- 
You are receiving this mail because:
You are the assignee for the bug.

Reply via email to