iter_scrub.c File Reference

This file has routine(s) for cleaning up incoming DNS messages from possible useless or malicious junk in it. More...

#include "config.h"
#include "iterator/iter_scrub.h"
#include "iterator/iterator.h"
#include "iterator/iter_priv.h"
#include "services/cache/rrset.h"
#include "util/log.h"
#include "util/net_help.h"
#include "util/regional.h"
#include "util/config_file.h"
#include "util/module.h"
#include "util/data/msgparse.h"
#include "util/data/dname.h"
#include "util/data/msgreply.h"
#include "util/alloc.h"
#include "sldns/sbuffer.h"

Macros

#define RRSET_SCRUB_OK   0x80
 RRset flag used during scrubbing. More...
 

Functions

static void remove_rrset (const char *str, sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *prev, struct rrset_parse **rrset)
 remove rrset, update loop variables
 
static int has_additional (uint16_t t)
 return true if rr type has additional names in it
 
static int get_additional_name (struct rrset_parse *rrset, struct rr_parse *rr, uint8_t **nm, size_t *nmlen, sldns_buffer *pkt)
 get additional name from rrset RR, return false if no name present
 
static void mark_additional_rrset (sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *rrset)
 Place mark on rrsets in additional section they are OK.
 
static int parse_get_cname_target (struct rrset_parse *rrset, uint8_t **sname, size_t *snamelen, sldns_buffer *pkt)
 Get target name of a CNAME.
 
static int synth_cname (uint8_t *qname, size_t qnamelen, struct rrset_parse *dname_rrset, uint8_t *alias, size_t *aliaslen, sldns_buffer *pkt)
 Synthesize CNAME from DNAME, false if too long.
 
static struct rrset_parsesynth_cname_rrset (uint8_t **sname, size_t *snamelen, uint8_t *alias, size_t aliaslen, struct regional *region, struct msg_parse *msg, struct rrset_parse *rrset, struct rrset_parse *prev, struct rrset_parse *nx, sldns_buffer *pkt)
 synthesize a CNAME rrset
 
static int pkt_strict_sub (sldns_buffer *pkt, uint8_t *sname, uint8_t *dr)
 check if DNAME applies to a name
 
static int pkt_sub (sldns_buffer *pkt, uint8_t *comprname, uint8_t *zone)
 check subdomain with decompression
 
static int sub_of_pkt (sldns_buffer *pkt, uint8_t *zone, uint8_t *comprname)
 check subdomain with decompression, compressed is parent
 
static int soa_in_auth (struct msg_parse *msg)
 Check if there are SOA records in the authority section (negative)
 
static int type_allowed_in_authority_section (uint16_t tp)
 Check if type is allowed in the authority section.
 
static int type_allowed_in_additional_section (uint16_t tp)
 Check if type is allowed in the additional section.
 
static void shorten_rrset (sldns_buffer *pkt, struct rrset_parse *rrset, int count)
 Shorten RRset.
 
static int scrub_normalize (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, struct regional *region, struct module_env *env)
 This routine normalizes a response. More...
 
static void store_rrset (sldns_buffer *pkt, struct msg_parse *msg, struct module_env *env, struct rrset_parse *rrset)
 Store potential poison in the cache (only if hardening disabled). More...
 
static int sanitize_nsec_is_overreach (sldns_buffer *pkt, struct rrset_parse *rrset, uint8_t *zonename)
 Check if right hand name in NSEC is within zone. More...
 
static int scrub_sanitize_rr_length (sldns_buffer *pkt, struct msg_parse *msg, struct rrset_parse *prev, struct rrset_parse **rrset, int *added_ede, struct module_qstate *qstate)
 Remove individual RRs, if the length is wrong. More...
 
static int scrub_sanitize (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, uint8_t *zonename, struct module_env *env, struct iter_env *ie, struct module_qstate *qstate)
 Given a response event, remove suspect RRsets from the response. More...
 
int scrub_message (sldns_buffer *pkt, struct msg_parse *msg, struct query_info *qinfo, uint8_t *zonename, struct regional *region, struct module_env *env, struct module_qstate *qstate, struct iter_env *ie)
 Cleanup the passed dns message. More...
 

Detailed Description

This file has routine(s) for cleaning up incoming DNS messages from possible useless or malicious junk in it.

Macro Definition Documentation

◆ RRSET_SCRUB_OK

#define RRSET_SCRUB_OK   0x80

RRset flag used during scrubbing.

The RRset is OK.

Function Documentation

◆ scrub_normalize()

static int scrub_normalize ( sldns_buffer pkt,
struct msg_parse msg,
struct query_info qinfo,
struct regional region,
struct module_env env 
)
static

This routine normalizes a response.

This includes removing "irrelevant" records from the answer and additional sections and (re)synthesizing CNAMEs from DNAMEs, if present.

Parameters
pktpacket.
msgmsg to normalize.
qinfooriginal query.
regionwhere to allocate synthesized CNAMEs.
envmodule env with config options.
Returns
0 on error.

References msg_parse::flags, FLAGS_GET_RCODE, query_info::qname, and query_info::qname_len.

◆ store_rrset()

static void store_rrset ( sldns_buffer pkt,
struct msg_parse msg,
struct module_env env,
struct rrset_parse rrset 
)
static

Store potential poison in the cache (only if hardening disabled).

The rrset is stored in the cache but removed from the message. So that it will be used for infrastructure purposes, but not be returned to the client.

Parameters
pktpacket
msgmessage parsed
envenvironment with cache
rrsetto store.

References module_env::alloc, alloc_special_obtain(), alloc_special_release(), lruhash_entry::data, ub_packed_rrset_key::entry, rrset_ref::id, ub_packed_rrset_key::id, rrset_ref::key, module_env::now, packed_rrset_ttl_add(), parse_copy_decompress_rrset(), module_env::rrset_cache, and rrset_cache_update().

◆ sanitize_nsec_is_overreach()

static int sanitize_nsec_is_overreach ( sldns_buffer pkt,
struct rrset_parse rrset,
uint8_t *  zonename 
)
static

Check if right hand name in NSEC is within zone.

Parameters
pktthe packet buffer for decompression.
rrsetthe NSEC rrset
zonenamethe zone name.
Returns
true if BAD.

References log_assert, and rrset_parse::type.

◆ scrub_sanitize_rr_length()

static int scrub_sanitize_rr_length ( sldns_buffer pkt,
struct msg_parse msg,
struct rrset_parse prev,
struct rrset_parse **  rrset,
int *  added_ede,
struct module_qstate qstate 
)
static

Remove individual RRs, if the length is wrong.

Returns true if the RRset has been removed.

References LDNS_RR_TYPE_A, rr_parse::next, and rr_parse::size.

◆ scrub_sanitize()

static int scrub_sanitize ( sldns_buffer pkt,
struct msg_parse msg,
struct query_info qinfo,
uint8_t *  zonename,
struct module_env env,
struct iter_env ie,
struct module_qstate qstate 
)
static

Given a response event, remove suspect RRsets from the response.

"Suspect" rrsets are potentially poison. Note that this routine expects the response to be in a "normalized" state – that is, all "irrelevant" RRsets have already been removed, CNAMEs are in order, etc.

Parameters
pktpacket.
msgmsg to normalize.
qinfothe question originally asked.
zonenamename of server zone.
envmodule environment with config and cache.
ieiterator environment with private address data.
qstatefor setting errinf for EDE error messages.
Returns
0 on error.

References LDNS_RR_TYPE_DNAME, msg_parse::rrset_first, rrset_parse::section, and rrset_parse::type.

◆ scrub_message()

int scrub_message ( struct sldns_buffer pkt,
struct msg_parse msg,
struct query_info qinfo,
uint8_t *  zonename,
struct regional regional,
struct module_env env,
struct module_qstate qstate,
struct iter_env ie 
)

Cleanup the passed dns message.

Parameters
pktthe packet itself, for resolving name compression pointers. the packet buffer is unaltered.
msgthe parsed packet, this structure is cleaned up.
qinfothe query info that was sent to the server. Checked.
zonenamethe name of the last delegation point. Used to determine out of bailiwick information.
regionalwhere to allocate (new) parts of the message.
envmodule environment with config settings and cache.
qstatefor setting errinf for EDE error messages.
ieiterator module environment data.
Returns
: false if the message is total waste. true if scrubbed with success.

References BIT_AD, BIT_QR, BIT_Z, msg_parse::flags, FLAGS_GET_RCODE, LDNS_RR_TYPE_NS, log_nametypeclass(), query_info::qclass, msg_parse::qdcount, and VERB_ALGO.