diff options
| author | Cy Schubert <cy@FreeBSD.org> | 2026-01-08 17:41:53 +0000 |
|---|---|---|
| committer | Cy Schubert <cy@FreeBSD.org> | 2026-02-20 02:24:26 +0000 |
| commit | bdf97b8f056fcb842d4a4feb8c36008aa897cb62 (patch) | |
| tree | 2d6db02a6ee25b29a5a255418ee5364cf6982ef5 | |
| parent | 15c33b64ac2d6a6201cb819da184d0f4028d7632 (diff) | |
ipfilter: Interface name must not extend beyond end of bufferstable/13
sifpidx (an interface name) cannot extend beyond the end of the
fr_names buffer.
We do the validation for fr_sifpidx here because it is a union that
contains an offset only when fr_sifpidx points to an interface name,
an offset into fr_names. The union is an offset into fr_names in this
case only.
interr_tbl now becomes a static variable outside a function to facilitate
its use by two functions within fil.c
Note that sifpidx is only used in ipf_sync() which implments ipf -y.
Reported by: Ilja Van Sprundel <ivansprundel@ioactive.com>
MFC after: 1 week
(cherry picked from commit 47fb51847fdea3f1cce841b5f2bbbcd6f8a04ee0)
| -rw-r--r-- | sys/netpfil/ipfilter/netinet/fil.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/sys/netpfil/ipfilter/netinet/fil.c b/sys/netpfil/ipfilter/netinet/fil.c index cf21c68b7b46..2b81af276cb9 100644 --- a/sys/netpfil/ipfilter/netinet/fil.c +++ b/sys/netpfil/ipfilter/netinet/fil.c @@ -240,6 +240,11 @@ static const struct optlist secopt[] = { { IPSO_CLASS_RES1, 0x80 } }; +/* + * Internal errors set by ipf_check_names_string(). + */ +static const int interr_tbl[3] = { 152, 156, 153 }; + char ipfilter_version[] = IPL_VERSION; int ipf_features = 0 @@ -3910,7 +3915,7 @@ ipf_synclist(ipf_main_softc_t *softc, frentry_t *fr, void *ifp) frentry_t *frt, *start = fr; frdest_t *fdp; char *name; - int error; + int error, interr; void *ifa; int v, i; @@ -3937,6 +3942,21 @@ ipf_synclist(ipf_main_softc_t *softc, frentry_t *fr, void *ifp) } if ((fr->fr_type & ~FR_T_BUILTIN) == FR_T_IPF) { + /* + * We do the validation for fr_sifpidx here because + * it is a union that contains an offset only when + * fr_sifpidx points to an interface name, an offset + * into fr_names. The union is an offset into + * fr_names in this case only. + * + * Note that sifpidx is only used in ipf_sync() which + * implments ipf -y. + */ + if ((interr = ipf_check_names_string(fr->fr_names, fr->fr_namelen, fr->fr_sifpidx)) != 0) { + IPFERROR(interr_tbl[interr-1]); + error = EINVAL; + goto unwind; + } if (fr->fr_satype != FRI_NORMAL && fr->fr_satype != FRI_LOOKUP) { ifa = ipf_resolvenic(softc, fr->fr_names + @@ -4408,7 +4428,6 @@ frrequest(ipf_main_softc_t *softc, int unit, ioctlcmd_t req, caddr_t data, int set, int makecopy) { int error = 0, in, family, need_free = 0, interr, i; - int interr_tbl[3] = { 152, 156, 153}; enum { OP_ADD, /* add rule */ OP_REM, /* remove rule */ OP_ZERO /* zero statistics and counters */ } |
