#754·vegeta

DNSCaching 中的数据竞争:共享缓存片的变异和不安全的 rand.Rand

作者: queelius创建于 2026年3月25日更新于 2026年3月25日

□ 错误描述

" DNSCaching " 选项有两个数据竞赛,在同时负载下被触发(即正常的植被操作):

  1. 共享 DNS 缓存切片就位变异

resolver. LookupHost()' 返回对缓存的[]字符串'切片的直接引用。 `电话连接 ' 关闭后,** 将这个共享的片段** 通过:

  • `rng.Shuffle(len(ips),.)' -- -- 在原地重新排列元素
  • FirstOf EachIP Family(ips)' -- -- 使用ips [:0]'的附加伎俩,覆盖后置阵列

当多个goroutines同时解析同一个主机时,它们都会得到相同的切片并比赛其元素. 这可能会腐蚀DNS缓存条目,导致连接错误的IP.

  1. 不安全的`兰得'。 漫游各行各业

私人的rand.New(rand.New source (.))'在DialContext'关闭中被创建并使用。 兰地。 (https://pkg.go.dev/math/rand#Rand)。 在同时拨号的尝试下,这是一个数据竞赛.

□再现.

开始 func TestDNSCaching 同流合污(t *testing.T){ srv: = httptest. NewServer(http.HandlerFunc (func (w http.ResponseWriter, r *http. request)-). 延迟 srv. Close () u, :=url.Parse(srv.URL) (中文(简体) ). 目标 := “http://localhost:” + u.Port()

atk := NewAttacker(DNSCaching (0)) tr := NewStaticTalgeter(目标{方法:"GET",URL:目标}) a:= 攻击{名:"dns-race-test",开始:时间. 现在( ) ]

var wg 同步 。 等待组 对于i:=0;i < 20;i++ { (单位:千美元) 开始 func () { 推迟时间。 完成( ) atk.hit(tr, a) (中文(简体) ). • () {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢? w. 等待( ) {\fn黑体\fs22\bord1\shad0\3aHBE\4aH00\fscx67\fscy66\2cHFFFFFF\3cH808080}你觉得呢?


使用“去测试-种族”触发器运行:

警告:数据丢失 在... firstOf EachIP Family () 攻击时读取. go: 419 前作于. firstOf EachIP Family () 攻击. go: 426


□ 修补

1. 在变异前复制 " ips " 片段
2. 利用全球`主动性'。 (c) 货币安全(Shuffle),而不是私人的`兰得'。 兰德

公关即将到来.