diff options
| author | Dimitri Staessens <dimitri@ouroboros.rocks> | 2026-05-30 11:53:30 +0200 |
|---|---|---|
| committer | Sander Vrijders <sander@ouroboros.rocks> | 2026-06-01 07:43:43 +0200 |
| commit | c3fe693a46026130cbff8906b350933c739d681e (patch) | |
| tree | 31b0f79dbe53f82f9e22a64362e8854c36749b42 /src | |
| parent | 44b7980a95107a564670393e4a2450e953223436 (diff) | |
| download | ouroboros-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>
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/dev.c | 16 |
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, |
