NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/59279: npfctl(8): missing null checks in variable lookups
>Number: 59279
>Category: bin
>Synopsis: npfctl(8): missing null checks in variable lookups
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Fri Apr 11 14:00:01 +0000 2025
>Originator: Taylor R Campbell
>Release: current, 10, 9, ...
>Organization:
The NpfBSD Undefinedation
>Environment:
>Description:
npfvar_lookup returns null for undefined variables, but doesn't give feedback about where they happened.
### filt_addr_element
This case _does_ give feedback but it's not immediately obvious to a reader where -- it happens a couple dozen lines later:
773 filt_addr_element
...
784 | VAR_ID
785 {
786 npfvar_t *vp = npfvar_lookup($1);
787 int type = npfvar_get_type(vp, 0);
788 ifnet_addr_t *ifna;
789 again:
790 switch (type) {
...
808 case -1:
809 yyerror("undefined variable '%s'", $1);
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_parse.y?r=1.52#773
### port_range
In the syntax of port ranges, there is a null pointer dereference marked by => below:
841 port_range
...
850 | VAR_ID
851 {
852 npfvar_t *vp = npfvar_lookup($1);
853 $$ = npfctl_parse_port_range_variable($1, vp);
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_parse.y?r=1.52#841
285 npfvar_t *
286 npfctl_parse_port_range_variable(const char *v, npfvar_t *vp)
287 {
288 size_t count = npfvar_get_count(vp);
289 npfvar_t *pvp = npfvar_create();
290 port_range_t *pr;
291
292 for (size_t i = 0; i < count; i++) {
293 int type = npfvar_get_type(vp, i);
294 void *data = npfvar_get_data(vp, type, i);
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_data.c?r=1.30#285
238 void *
239 npfvar_get_data(const npfvar_t *vp, unsigned type, size_t idx)
240 {
241 npf_element_t *el = npfvar_get_element(vp, idx, 0);
242
243 if (el && NPFVAR_TYPE(el->e_type) != NPFVAR_TYPE(type)) {
244 yyerror("variable '%s' element %zu "
245 "is of type '%s' rather than '%s'", vp->v_key,
246 idx, npfvar_type(el->e_type), npfvar_type(type));
247 return NULL;
248 }
=> 249 return el->e_data;
250 }
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_var.c?r=1.13#238
### icmp_type_and_code
Null pointer dereference marked by `=>':
863 icmp_type_and_code
...
877 | ICMPTYPE icmp_type CODE VAR_ID
878 {
879 char *s = npfvar_expand_string(npfvar_lookup($4));
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_parse.y?r=1.52#863
176 char *
177 npfvar_expand_string(const npfvar_t *vp)
178 {
179 if (npfvar_get_count(vp) != 1) {
=> 180 yyerror("variable '%s' has multiple elements", vp->v_key);
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_var.c?r=1.13#176
Note that npfvar_get_count(NULL) returns 0:
186 size_t
187 npfvar_get_count(const npfvar_t *vp)
188 {
189 return vp ? vp->v_count : 0;
190 }
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_var.c?r=1.13#186
### icmp_type
Same deal as above:
907 icmp_type
...
910 | VAR_ID
911 {
912 char *s = npfvar_expand_string(npfvar_lookup($1));
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_parse.y?r=1.52#907
### ifname
Looks fine but the npfvar_lookup call and the error report are again separated by dozens of lines:
917 ifname
...
923 | VAR_ID
924 {
925 npfvar_t *vp = npfvar_lookup($1);
926 const int type = npfvar_get_type(vp, 0);
...
954 case -1:
955 yyerror("undefined variable '%s' for interface", $1);
https://nxr.netbsd.org/xref/src/usr.sbin/npf/npfctl/npf_parse.y?r=1.52#917
>How-To-Repeat:
write an npf.conf that exercises these cases with undefined variables
>Fix:
1. Add xfail test cases that exercise these issues.
2. Add null checks in appropriate places.
Part of (2) is done already:
Module Name: src
Committed By: joe
Date: Thu Apr 10 18:53:29 UTC 2025
Modified Files:
src/usr.sbin/npf/npfctl: npf_parse.y
Log Message:
notify us when we use undefined port variable
To generate a diff of this commit:
cvs rdiff -u -r1.52 -r1.53 src/usr.sbin/npf/npfctl/npf_parse.y
Home |
Main Index |
Thread Index |
Old Index