summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-05-30 11:53:30 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-06-01 07:43:43 +0200
commitc3fe693a46026130cbff8906b350933c739d681e (patch)
tree31b0f79dbe53f82f9e22a64362e8854c36749b42
parent44b7980a95107a564670393e4a2450e953223436 (diff)
downloadouroboros-c3fe693a46026130cbff8906b350933c739d681e.tar.gz
ouroboros-c3fe693a46026130cbff8906b350933c739d681e.zip
lib: Fix double pool_remove on tx-path failure
The flow_tx_spb function consumed the spb on every failure path via ssm_pool_remove, while its caller ipcp_flow_write left the spb to its caller on early outs, causing ssm_pool_remove to be called twice. In Debug builds this aborts at the old_ref == 0 check. This aligns flow_tx_spb with np1_flow_write and dt_write_packet: spb consumed on success, retained on failure. External callers already release on failure, so no caller-side changes outside of dev.c are needed. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
-rw-r--r--src/lib/dev.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/lib/dev.c b/src/lib/dev.c
index ae0401b7..ce358ac4 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -1509,16 +1509,13 @@ static int flow_tx_spb(struct flow * flow,
else
ret = ssm_rbuff_write_b(flow->tx_rb, idx, abstime);
- if (ret < 0) {
- ssm_pool_remove(proc.pool, idx);
+ if (ret < 0)
return ret;
- }
ssm_flow_set_notify(flow->set, flow->info.id, FLOW_PKT);
return 0;
enomem:
- ssm_pool_remove(proc.pool, idx);
return -ENOMEM;
}
@@ -1581,8 +1578,10 @@ static ssize_t flow_write_stream(struct flow * flow,
memcpy(ptr, src + off, clen);
ret = flow_tx_spb(flow, spb, 0, block, dl);
- if (ret < 0)
+ if (ret < 0) {
+ ssm_pool_remove(proc.pool, idx);
return off > 0 ? (ssize_t) off : (ssize_t) ret;
+ }
off += clen;
}
@@ -1651,6 +1650,7 @@ static ssize_t flow_write_frag(struct flow * flow,
ret = flow_tx_spb(flow, spb, flow_frag_role(i, n),
block, dl);
if (ret < 0) {
+ ssm_pool_remove(proc.pool, idx);
if (off > 0)
STAT_BUMP(flow->frcti, sdu_snd_tx);
return off > 0 ? (ssize_t) off : (ssize_t) ret;
@@ -1736,8 +1736,12 @@ ssize_t flow_write(int fd,
ret = flow_tx_spb(flow, spb, FRCT_FR_SOLE,
!(flags & FLOWFWNOBLOCK), dl);
+ if (ret < 0) {
+ ssm_pool_remove(proc.pool, idx);
+ return (ssize_t) ret;
+ }
- return ret < 0 ? (ssize_t) ret : (ssize_t) count;
+ return (ssize_t) count;
}
static ssize_t flow_rx_spb(struct flow * flow,