diff --git a/sys/net/ipfw3_basic/ip_fw3_sync.c b/sys/net/ipfw3_basic/ip_fw3_sync.c --- a/sys/net/ipfw3_basic/ip_fw3_sync.c 2026-06-29 12:51:19.000000000 +0000 +++ b/sys/net/ipfw3_basic/ip_fw3_sync.c 2026-07-19 07:48:46.110916061 +0000 @@ -102,8 +102,15 @@ struct ipfw3_ioc_sync_context *tmp_sync_ctx; int size; + /* DF-0705 #3: count is a signed int; reject negatives to avoid + * (a) tiny `size` bypassing the sopt_valsize check, and + * (b) huge size_t bcopy length wrap-around. */ + if (fw3_sync_ctx.count < 0) { + bzero(sopt->sopt_val, sopt->sopt_valsize); + return EINVAL; + } size = 3 * sizeof(int) + fw3_sync_ctx.count * LEN_SYNC_EDGE; - if (sopt->sopt_valsize < size) { + if (sopt->sopt_valsize < (size_t)size) { /* sopt_val is not big enough */ bzero(sopt->sopt_val, sopt->sopt_valsize); return 0; @@ -140,6 +147,10 @@ int size; ioc_centre = sopt->sopt_val; + /* DF-0705: validate count is non-negative and reasonably bounded */ + if (ioc_centre->count < 0 || ioc_centre->count > MAX_EDGES) { + return EINVAL; + } size = ioc_centre->count * LEN_SYNC_EDGE; if (fw3_sync_ctx.count == 0) { fw3_sync_ctx.edges = kmalloc(size, M_IPFW3_SYNC, M_NOWAIT | M_ZERO); @@ -239,6 +250,11 @@ if (fw3_sync_ctx.running & 1) { return 0; } + /* DF-0705 #1: caller must have configured the edge socket first */ + if (fw3_sync_ctx.edge_sock == NULL) { + kprintf("ipfw3sync edge not configured\n"); + return EINVAL; + } td = curthread->td_proc ? curthread : &thread0; bzero(&sin, sizeof(struct sockaddr_in)); sin.sin_family = AF_INET; @@ -260,7 +276,10 @@ error = kthread_create(ip_fw3_sync_edge_socket_handler, NULL, &fw3_sync_ctx.edge_td, "sync_edge_thread"); if (error) { - panic("ip_fw3_sync_edge_socket_handler:error %d",error); + /* DF-0705 #2: don't panic; report error to caller */ + kprintf("ipfw3sync edge kthread_create: %d\n", error); + fw3_sync_ctx.running &= ~1; + return error; } return 0; }