Data race trên data.IpDb.r khi refresh DB #10

Closed
opened 2026-07-22 11:20:59 +07:00 by claudecode · 0 comments
Owner

Vấn đề

Query() đọc d.r không giữ lock, trong khi Reload() ghi d.rđóng reader cũ dưới write-lock. Mỗi ngày (@daily) service tải DB mới → gọi Reload(). Nếu có request đang query cùng lúc → data race + reader bị close khi đang dùng.

Bằng chứng (đã xác nhận bằng -race)

WARNING: DATA RACE
Write at ...(*IpDb).Reload()          // ghi d.r (ipdb.go:92) + tmpR.Close() (line 95)
  ... maxminddb-golang.(*Reader).LookupNetwork()   // đọc reader đang bị Close (query.go:15)

Tệp: internal/data/query.go:15, internal/data/ipdb.go:71-104

Hậu quả

Có thể panic hoặc trả kết quả sai khi refresh DB dưới tải. sync.RWMutex (d.mu) đã có sẵn nhưng chưa được dùng ở phía đọc.

Fix đề xuất

func (d *IpDb) Query(ipArg string) (...) {
    ip := net.ParseIP(ipArg)
    if ip == nil { return nil, nil, fmt.Errorf("invalid IP: %s", ipArg) }
    d.mu.RLock()
    defer d.mu.RUnlock()
    if d.r == nil { return nil, nil, fmt.Errorf("db not loaded") }
    ...d.r.LookupNetwork(ip, &anyData)
}

Làm tương tự cho IsLoaded(). Thêm test -race regression.

## Vấn đề `Query()` đọc `d.r` **không giữ lock**, trong khi `Reload()` ghi `d.r` và **đóng reader cũ** dưới write-lock. Mỗi ngày (`@daily`) service tải DB mới → gọi `Reload()`. Nếu có request đang query cùng lúc → data race + reader bị close khi đang dùng. ## Bằng chứng (đã xác nhận bằng `-race`) ``` WARNING: DATA RACE Write at ...(*IpDb).Reload() // ghi d.r (ipdb.go:92) + tmpR.Close() (line 95) ... maxminddb-golang.(*Reader).LookupNetwork() // đọc reader đang bị Close (query.go:15) ``` Tệp: `internal/data/query.go:15`, `internal/data/ipdb.go:71-104` ## Hậu quả Có thể panic hoặc trả kết quả sai khi refresh DB dưới tải. `sync.RWMutex` (`d.mu`) đã có sẵn nhưng chưa được dùng ở phía đọc. ## Fix đề xuất ```go func (d *IpDb) Query(ipArg string) (...) { ip := net.ParseIP(ipArg) if ip == nil { return nil, nil, fmt.Errorf("invalid IP: %s", ipArg) } d.mu.RLock() defer d.mu.RUnlock() if d.r == nil { return nil, nil, fmt.Errorf("db not loaded") } ...d.r.LookupNetwork(ip, &anyData) } ``` Làm tương tự cho `IsLoaded()`. Thêm test `-race` regression.
claudecode added the bug label 2026-07-22 11:20:59 +07:00
This repo is archived. You cannot comment on issues.
1 Participants
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: public/ip-info#10