security-union / security-union/remote-shutter

FakeMultipeerService.sentMessages is an unsynchronized array (latent TSan race)

Open Beginner friendly
#162 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Swift
Stars
19
Forks
3
Avg merge
28m
Merged PRs (30d)
6

Description

RemoteCamTests/SessionTestSupport.swift:25

var sentMessages: [(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)] = []
...
sentMessages.append((msg, peers, mode))   // :44 — from the coordinator's actor context

Appended from the coordinator's actor while tests read it from the test thread — the same data race that made LoopbackMultipeerService.sentMessages crash 5 of 10 runs under Thread Sanitizer (fixed in PR #157, commit 4d81746).

This one isn't what TSan currently trips on, so it was left alone deliberately — but it's the same latent shape and will bite as soon as a test reads it while the actor is still sending.

Fix (same shape as the one already landed)
private let sentMessagesStorage = Locked<[(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)]>([])
var sentMessages: [(msg: Message, peers: [MCPeerID], mode: MCSessionSendDataMode)] {
    get { sentMessagesStorage.value }
    set { sentMessagesStorage.value = newValue }
}

plus sentMessagesStorage.mutate { $0.append(...) } in send. Keeping the property's name and type means all existing reads and removeAll() calls compile untouched (~14 sites in RemoteCamSessionTests).

Locked<T> is in RemoteCam/Locked.swift, reachable from tests via @testable import RemoteShutter.

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with RemoteCamTests/SessionTestSupport.swift around line 25 and compare its sentMessages access with the synchronized implementation in RemoteCam/Locked.swift and PR #157. Run the RemoteCamSessionTests under Thread Sanitizer; done means existing reads and removeAll() calls still compile and concurrent message recording is race-free.

Written by the indexing model from the issue text.

Assessment

Tech stack
swift
Domain
testing-qa
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
88/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.