|
Hi Hyunwoo,
I reviewed the change and the reasoning looks correct to me.
nfqnl_recv_verdict() dequeues the entry using find_dequeue_entry(), which
transfers ownership of the nf_queue_entry to this function. After that point
the function becomes responsible for either reinjecting or freeing the entry.
In the PF_BRIDGE path the code calls nfqa_parse_bridge() to parse the VLAN
attributes coming from userspace. If the attribute set is malformed (for
example NFQA_VLAN present but NFQA_VLAN_TCI missing), nfqa_parse_bridge()
returns an error. Before this patch, the function would return immediately in
that situation.
Because the entry had already been dequeued, returning directly means the
nf_queue_entry object and its associated sk_buff are never released. That also
leaves any held references such as net_device and struct net references alive.
If a userspace program repeatedly sends malformed verdict messages, this path
could leak queue entries and eventually exhaust kernel memory.
Your change fixes this by calling nfqnl_reinject(entry, NF_DROP) before
returning. This matches the error handling pattern used elsewhere in the file:
once the entry is owned by the verdict handler, it must be reinjected or
dropped so the resources are released correctly.
So the logic now becomes:
1. dequeue the entry
2. attempt bridge attribute parsing
3. if parsing fails, explicitly drop the packet via nfqnl_reinject()
4. return the error to the caller
That ensures the queue entry and skb are properly handled even in the malformed
attribute case.
The Fixes tag also makes sense since the leak path was introduced when bridge
verdict handling started using NFQA_VLAN/NFQA_L2HDR.
Overall the change is small, consistent with the existing reinjection model,
and addresses a clear ownership leak in the error path.
Reviewed by : David Dull
|