mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 23:58:50 +00:00
Merge pull request #4872 from haesbaert/dns-spoof
Fix multiple vulnerabilities in the resolver
This commit is contained in:
+17
-5
@@ -11,6 +11,7 @@ package net
|
|||||||
Copyright 2022 Colin Davidson <colrdavidson@gmail.com>
|
Copyright 2022 Colin Davidson <colrdavidson@gmail.com>
|
||||||
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
|
Copyright 2022 Jeroen van Rijn <nom@duclavier.com>.
|
||||||
Copyright 2024 Feoramund <rune@swevencraft.org>.
|
Copyright 2024 Feoramund <rune@swevencraft.org>.
|
||||||
|
Copyright 2025 Christiano Haesbaert <haesbaert@haesbaert.org>.
|
||||||
Made available under Odin's BSD-3 license.
|
Made available under Odin's BSD-3 license.
|
||||||
|
|
||||||
List of contributors:
|
List of contributors:
|
||||||
@@ -18,12 +19,14 @@ package net
|
|||||||
Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
|
Colin Davidson: Linux platform code, OSX platform code, Odin-native DNS resolver
|
||||||
Jeroen van Rijn: Cross platform unification, code style, documentation
|
Jeroen van Rijn: Cross platform unification, code style, documentation
|
||||||
Feoramund: FreeBSD platform code
|
Feoramund: FreeBSD platform code
|
||||||
|
Haesbaert: Security fixes
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import "core:mem"
|
import "core:mem"
|
||||||
import "core:strings"
|
import "core:strings"
|
||||||
import "core:time"
|
import "core:time"
|
||||||
import "core:os"
|
import "core:os"
|
||||||
|
import "core:math/rand"
|
||||||
/*
|
/*
|
||||||
Default configuration for DNS resolution.
|
Default configuration for DNS resolution.
|
||||||
*/
|
*/
|
||||||
@@ -227,7 +230,7 @@ get_dns_records_from_nameservers :: proc(hostname: string, type: DNS_Record_Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
hdr := DNS_Header{
|
hdr := DNS_Header{
|
||||||
id = 0,
|
id = u16be(rand.uint32()),
|
||||||
is_response = false,
|
is_response = false,
|
||||||
opcode = 0,
|
opcode = 0,
|
||||||
is_authoritative = false,
|
is_authoritative = false,
|
||||||
@@ -272,17 +275,23 @@ get_dns_records_from_nameservers :: proc(hostname: string, type: DNS_Record_Type
|
|||||||
return nil, .Connection_Error
|
return nil, .Connection_Error
|
||||||
}
|
}
|
||||||
|
|
||||||
recv_sz, _ := recv_udp(conn, dns_response_buf[:]) or_continue
|
recv_sz, src := recv_udp(conn, dns_response_buf[:]) or_continue
|
||||||
if recv_sz == 0 {
|
if recv_sz == 0 {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
if src != name_server {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
dns_response = dns_response_buf[:recv_sz]
|
dns_response = dns_response_buf[:recv_sz]
|
||||||
|
|
||||||
rsp, _ok := parse_response(dns_response, type)
|
rsp, xid, _ok := parse_response(dns_response, type)
|
||||||
if !_ok {
|
if !_ok {
|
||||||
return nil, .Server_Error
|
return nil, .Server_Error
|
||||||
}
|
}
|
||||||
|
if id != xid {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if len(rsp) == 0 {
|
if len(rsp) == 0 {
|
||||||
continue
|
continue
|
||||||
@@ -803,7 +812,7 @@ parse_record :: proc(packet: []u8, cur_off: ^int, filter: DNS_Record_Type = nil)
|
|||||||
- Data[]
|
- Data[]
|
||||||
*/
|
*/
|
||||||
|
|
||||||
parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator := context.allocator) -> (records: []DNS_Record, ok: bool) {
|
parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator := context.allocator) -> (records: []DNS_Record, xid: u16be, ok: bool) {
|
||||||
context.allocator = allocator
|
context.allocator = allocator
|
||||||
|
|
||||||
HEADER_SIZE_BYTES :: 12
|
HEADER_SIZE_BYTES :: 12
|
||||||
@@ -816,11 +825,13 @@ parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator
|
|||||||
dns_hdr_chunks := mem.slice_data_cast([]u16be, response[:HEADER_SIZE_BYTES])
|
dns_hdr_chunks := mem.slice_data_cast([]u16be, response[:HEADER_SIZE_BYTES])
|
||||||
hdr := unpack_dns_header(dns_hdr_chunks[0], dns_hdr_chunks[1])
|
hdr := unpack_dns_header(dns_hdr_chunks[0], dns_hdr_chunks[1])
|
||||||
if !hdr.is_response {
|
if !hdr.is_response {
|
||||||
|
delete(_records)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
question_count := int(dns_hdr_chunks[2])
|
question_count := int(dns_hdr_chunks[2])
|
||||||
if question_count != 1 {
|
if question_count != 1 {
|
||||||
|
delete(_records)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
answer_count := int(dns_hdr_chunks[3])
|
answer_count := int(dns_hdr_chunks[3])
|
||||||
@@ -872,6 +883,7 @@ parse_response :: proc(response: []u8, filter: DNS_Record_Type = nil, allocator
|
|||||||
append(&_records, rec)
|
append(&_records, rec)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
xid = hdr.id
|
||||||
|
|
||||||
return _records[:], true
|
return _records[:], xid, true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user