fix: resolve deadlock, data races and path traversal vulnerabilities
- task.go: fix deadlock in ToStatusUpdate() — calling Percent() (which RLocks) while already holding RLock caused deadlock when a writer was waiting; compute percent inline instead - usenet.go: fix data race in Cancel() — tracker and taskDir were read without the mutex while Download() writes them under it; read all fields under the same lock - upnp.go: fix UPnP Remove() blocking shutdown — run cleanup in goroutine with 10s deadline (removeNATPMP worst case is 3s dial + 5s deadline) - daemon.go: add path traversal protection for stream requests — validate sr.FilePath is within configured directories before os.Stat; defends against compromised API server sending arbitrary paths - client.go: add wakeClient without timeout for long-poll wake endpoint where context controls cancellation - sync.go: trigger immediate sync when entering watching mode so stream requests are picked up without waiting for the next scheduled interval
This commit is contained in:
parent
78c16c295e
commit
ef4f38d324
6 changed files with 146 additions and 13 deletions
|
|
@ -300,8 +300,16 @@ func (u *UsenetDownloader) Pause(taskID string) error {
|
|||
|
||||
// Cancel aborts an in-progress download and removes partial files + resume state.
|
||||
func (u *UsenetDownloader) Cancel(taskID string) error {
|
||||
// Read all fields under the lock — Download() writes tracker and taskDir under
|
||||
// the same lock, so we must hold it while reading to avoid a data race.
|
||||
u.mu.Lock()
|
||||
dl := u.active[taskID]
|
||||
var tracker *download.ProgressTracker
|
||||
var taskDir string
|
||||
if dl != nil {
|
||||
tracker = dl.tracker
|
||||
taskDir = dl.taskDir
|
||||
}
|
||||
u.mu.Unlock()
|
||||
|
||||
if dl == nil {
|
||||
|
|
@ -312,13 +320,13 @@ func (u *UsenetDownloader) Cancel(taskID string) error {
|
|||
dl.cancel()
|
||||
|
||||
// Remove resume state (best-effort)
|
||||
if dl.tracker != nil {
|
||||
dl.tracker.Remove()
|
||||
if tracker != nil {
|
||||
tracker.Remove()
|
||||
}
|
||||
|
||||
// Remove partial download directory in background (can be slow for large dirs)
|
||||
if dl.taskDir != "" {
|
||||
go os.RemoveAll(dl.taskDir)
|
||||
if taskDir != "" {
|
||||
go os.RemoveAll(taskDir)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue