summaryrefslogtreecommitdiff
path: root/src/lib/dev.c
diff options
context:
space:
mode:
authorDimitri Staessens <dimitri@ouroboros.rocks>2026-05-01 12:25:37 +0200
committerSander Vrijders <sander@ouroboros.rocks>2026-05-06 09:05:58 +0200
commitc83fa890a0ac583959d9b7791333739b055c932c (patch)
tree9fb20b185e0e3fc56caa5db1f91c7bc60dde96c3 /src/lib/dev.c
parent146ba945e23c2266d5e31035135b5d158d1256e8 (diff)
downloadouroboros-c83fa890a0ac583959d9b7791333739b055c932c.tar.gz
ouroboros-c83fa890a0ac583959d9b7791333739b055c932c.zip
lib: Fix pool_copy_spb and np1_flow_write
The pool_copy_spb function was consuming the packet buffer on error, causing double free errors. Signed-off-by: Dimitri Staessens <dimitri@ouroboros.rocks> Signed-off-by: Sander Vrijders <sander@ouroboros.rocks>
Diffstat (limited to 'src/lib/dev.c')
-rw-r--r--src/lib/dev.c34
1 files changed, 19 insertions, 15 deletions
diff --git a/src/lib/dev.c b/src/lib/dev.c
index 9cfc24ee..53266648 100644
--- a/src/lib/dev.c
+++ b/src/lib/dev.c
@@ -2047,10 +2047,8 @@ static int pool_copy_spb(struct ssm_pool * src_pool,
src = ssm_pool_get(src_pool, src_idx);
len = ssm_pk_buff_len(src);
- if (ssm_pool_alloc(dst_pool, len, &ptr, dst_spb) < 0) {
- ssm_pool_remove(src_pool, src_idx);
+ if (ssm_pool_alloc(dst_pool, len, &ptr, dst_spb) < 0)
return -ENOMEM;
- }
memcpy(ptr, ssm_pk_buff_head(src), len);
ssm_pool_remove(src_pool, src_idx);
@@ -2086,8 +2084,10 @@ int np1_flow_read(int fd,
*spb = ssm_pool_get(proc.pool, idx);
} else {
/* Cross-pool copy: PUP -> GSPP */
- if (pool_copy_spb(pool, idx, proc.pool, spb) < 0)
+ if (pool_copy_spb(pool, idx, proc.pool, spb) < 0) {
+ ssm_pool_remove(pool, idx);
return -ENOMEM;
+ }
}
return 0;
@@ -2101,6 +2101,7 @@ int np1_flow_write(int fd,
struct ssm_pk_buff * dst;
int ret;
ssize_t idx;
+ ssize_t dst_idx;
assert(fd >= 0 && fd < SYS_MAX_FLOWS);
assert(spb);
@@ -2126,22 +2127,23 @@ int np1_flow_write(int fd,
if (pool == NULL) {
ret = ssm_rbuff_write_b(flow->tx_rb, idx, NULL);
if (ret < 0)
- ssm_pool_remove(proc.pool, idx);
- else
- ssm_flow_set_notify(flow->set, flow->info.id, FLOW_PKT);
+ return ret;
+ ssm_flow_set_notify(flow->set, flow->info.id, FLOW_PKT);
} else {
/* Cross-pool copy: GSPP -> PUP */
if (pool_copy_spb(proc.pool, idx, pool, &dst) < 0)
return -ENOMEM;
- idx = ssm_pk_buff_get_idx(dst);
- ret = ssm_rbuff_write_b(flow->tx_rb, idx, NULL);
- if (ret < 0)
- ssm_pool_remove(pool, idx);
- else
- ssm_flow_set_notify(flow->set, flow->info.id, FLOW_PKT);
+ dst_idx = ssm_pk_buff_get_idx(dst);
+ ret = ssm_rbuff_write_b(flow->tx_rb, dst_idx, NULL);
+ if (ret < 0) {
+ ssm_pool_remove(pool, dst_idx);
+ return ret;
+ }
+ ssm_flow_set_notify(flow->set, flow->info.id, FLOW_PKT);
+ ssm_pool_remove(proc.pool, idx);
}
- return ret;
+ return 0;
}
int ipcp_spb_reserve(struct ssm_pk_buff ** spb,
@@ -2265,8 +2267,10 @@ int local_flow_transfer(int src_fd,
dst_flow->info.id, FLOW_PKT);
} else {
/* Different pools: single copy */
- if (pool_copy_spb(sp, idx, dp, &dst_spb) < 0)
+ if (pool_copy_spb(sp, idx, dp, &dst_spb) < 0) {
+ ssm_pool_remove(sp, idx);
return -ENOMEM;
+ }
idx = ssm_pk_buff_get_idx(dst_spb);
ret = ssm_rbuff_write_b(dst_flow->tx_rb, idx, NULL);