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)