Signal Notify Unbuffered

ID

go.signal_notify_unbuffered

Severity

high

Remediation Complexity

simple

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

Go

Tags

CWE:662, correctness, reliability

Description

Reports a signal.Notify(c, …​) whose channel c is unbuffered. signal.Notify delivers signals with a non-blocking send, so a signal that arrives while no goroutine is ready to receive on an unbuffered channel is silently dropped.

Rationale

An unbuffered channel is ready to receive only while a goroutine is actively blocked in a receive on it. Because signal.Notify never blocks waiting for the receiver, any signal that arrives at another moment is lost. The standard library documentation explicitly recommends a buffered channel; a capacity of one is enough to hold a pending signal until the program gets around to reading it.

To stay free of false positives the rule fires only when the channel argument is a bare identifier whose declaration initialises it with make(chan T) or make(chan T, 0). When the channel comes from an alias, a parameter, or any source whose buffer size cannot be read off a single make call, nothing is reported.

c := make(chan os.Signal)      // FLAW — unbuffered, signals can be dropped
signal.Notify(c, os.Interrupt)

c := make(chan os.Signal, 1)   // OK — buffered
signal.Notify(c, os.Interrupt)

Remediation

Create the channel with a buffer of at least one: make(chan os.Signal, 1).