diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 1303d49080a..039f4a5faff 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.425 2025/11/13 12:30:05 sashan Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.426 2025/11/20 10:47:44 sashan Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1003,6 +1003,7 @@ pf_statelim_add(const struct pfioc_statelim *ioc) return (EINVAL); namelen = strnlen(ioc->name, sizeof(ioc->name)); + /* is the name from userland nul terminated? */ if (namelen == sizeof(ioc->name)) return (EINVAL); @@ -1011,7 +1012,11 @@ pf_statelim_add(const struct pfioc_statelim *ioc) return (ENOMEM); pfstlim->pfstlim_id = ioc->id; - memcpy(pfstlim->pfstlim_nm, ioc->name, namelen); + if (strlcpy(pfstlim->pfstlim_nm, ioc->name, + sizeof(pfstlim->pfstlim_nm)) >= sizeof(pfstlim->pfstlim_nm)) { + error = EINVAL; + goto free; + } pfstlim->pfstlim_limit = ioc->limit; pfstlim->pfstlim_rate.limit = ioc->rate.limit; pfstlim->pfstlim_rate.seconds = ioc->rate.seconds; @@ -1059,7 +1064,7 @@ pf_statelim_add(const struct pfioc_statelim *ioc) unlock: PF_UNLOCK(); NET_UNLOCK(); -/* free: */ +free: pool_put(&pf_statelim_pl, pfstlim); return (error); @@ -1257,7 +1262,7 @@ pf_sourcelim_check(void) continue; if (strcmp(npfsrlim->pfsrlim_overload.name, - pfsrlim->pfsrlim_overload.name) != 0) + pfsrlim->pfsrlim_overload.name) != 0) return (EBUSY); /* @@ -1417,7 +1422,7 @@ pf_statelim_rb_nfind(struct pf_statelim_id_tree *tree, int pf_statelim_get(struct pfioc_statelim *ioc, struct pf_statelim *(*rbt_op)(struct pf_statelim_id_tree *, - const struct pf_statelim *)) + const struct pf_statelim *)) { struct pf_statelim key = { .pfstlim_id = ioc->id }; struct pf_statelim *pfstlim; @@ -1479,24 +1484,19 @@ pf_sourcelim_add(const struct pfioc_sourcelim *ioc) return (EINVAL); namelen = strnlen(ioc->name, sizeof(ioc->name)); + /* is the name from userland nul terminated? */ if (namelen == sizeof(ioc->name)) return (EINVAL); tablelen = strnlen(ioc->overload_tblname, sizeof(ioc->overload_tblname)); + /* is the name from userland nul terminated? */ if (tablelen == sizeof(ioc->overload_tblname)) return (EINVAL); if (tablelen != 0) { if (ioc->overload_hwm == 0) return (EINVAL); - /* - * this is stupid, but not harmful? - * - * if (ioc->states < ioc->overload_hwm) - * return (EINVAL); - */ - if (ioc->overload_hwm < ioc->overload_lwm) return (EINVAL); } @@ -1512,10 +1512,20 @@ pf_sourcelim_add(const struct pfioc_sourcelim *ioc) pfsrlim->pfsrlim_ipv6_prefix = ioc->inet6_prefix; pfsrlim->pfsrlim_rate.limit = ioc->rate.limit; pfsrlim->pfsrlim_rate.seconds = ioc->rate.seconds; - memcpy(pfsrlim->pfsrlim_overload.name, ioc->overload_tblname, tablelen); + if (strlcpy(pfsrlim->pfsrlim_overload.name, ioc->overload_tblname, + sizeof(pfsrlim->pfsrlim_overload.name)) >= + sizeof(pfsrlim->pfsrlim_overload.name)) { + error = EINVAL; + goto free; + } pfsrlim->pfsrlim_overload.hwm = ioc->overload_hwm; pfsrlim->pfsrlim_overload.lwm = ioc->overload_lwm; memcpy(pfsrlim->pfsrlim_nm, ioc->name, namelen); + if (strlcpy(pfsrlim->pfsrlim_nm, ioc->name, + sizeof(pfsrlim->pfsrlim_nm)) >= sizeof(pfsrlim->pfsrlim_nm)) { + error = EINVAL; + goto free; + } if (pfsrlim->pfsrlim_rate.limit) { uint64_t bucket = pfsrlim->pfsrlim_rate.seconds * 1000000000ULL; @@ -1587,7 +1597,7 @@ pf_sourcelim_add(const struct pfioc_sourcelim *ioc) unlock: PF_UNLOCK(); NET_UNLOCK(); -/* free: */ +free: pool_put(&pf_sourcelim_pl, pfsrlim); return (error); @@ -1631,7 +1641,7 @@ pf_sourcelim_rb_nfind(struct pf_sourcelim_id_tree *tree, int pf_sourcelim_get(struct pfioc_sourcelim *ioc, struct pf_sourcelim *(*rbt_op)(struct pf_sourcelim_id_tree *, - const struct pf_sourcelim *)) + const struct pf_sourcelim *)) { struct pf_sourcelim key = { .pfsrlim_id = ioc->id }; struct pf_sourcelim *pfsrlim; @@ -1639,12 +1649,6 @@ pf_sourcelim_get(struct pfioc_sourcelim *ioc, NET_LOCK(); PF_LOCK(); -#if 0 - if (ioc->ticket != pf_main_ruleset.rules.active.ticket) { - error = EBUSY; - goto unlock; - } -#endif pfsrlim = (*rbt_op)(&pf_sourcelim_id_tree_active, &key); if (pfsrlim == NULL) { @@ -1706,7 +1710,7 @@ pf_source_rb_nfind(struct pf_source_ioc_tree *tree, int pf_source_get(struct pfioc_source *ioc, struct pf_source *(*rbt_op)(struct pf_source_ioc_tree *, - const struct pf_source *)) + const struct pf_source *)) { struct pf_sourcelim plkey = { .pfsrlim_id = ioc->id }; struct pfioc_source_entry e, *uentry; @@ -1727,12 +1731,6 @@ pf_source_get(struct pfioc_source *ioc, NET_LOCK(); PF_LOCK(); -#if 0 - if (ioc->ticket != pf_main_ruleset.rules.active.ticket) { - error = EBUSY; - goto unlock; - } -#endif pfsrlim = pf_sourcelim_rb_find(&pf_sourcelim_id_tree_active, &plkey); if (pfsrlim == NULL) { @@ -1821,12 +1819,6 @@ pf_source_clr(struct pfioc_source_kill *ioc) NET_LOCK(); PF_LOCK(); -#if 0 - if (ioc->ticket != pf_main_ruleset.rules.active.ticket) { - error = EBUSY; - goto unlock; - } -#endif pfsrlim = pf_sourcelim_rb_find(&pf_sourcelim_id_tree_active, &plkey); if (pfsrlim == NULL) { @@ -3642,7 +3634,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) case PF_TRANS_TABLE: rs = pf_find_ruleset(ioe->anchor); if (rs == NULL || !rs->topen || ioe->ticket != - rs->tticket) { + rs->tticket) { PF_UNLOCK(); NET_UNLOCK(); free(table, M_PF, sizeof(*table));