NetBSD-Bugs archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
bin/60037: Const data storage type in npf reads unmapped memory
>Number: 60037
>Category: bin
>Synopsis: Const data storage type in npf reads unmapped memory
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Feb 25 07:45:00 +0000 2026
>Originator: ocb
>Release: NetBSD 10.1
>Organization:
>Environment:
NetBSD server 10.1 NetBSD 10.1 (GENERIC) #0: Mon Dec 16 13:08:11 UTC 2024 mkrepro%mkrepro.NetBSD.org@localhost:/usr/src/sys/arch/amd64/compile/GENERIC amd64
>Description:
I started testing the const database because npf table with iplist type does not accept loading large ip lists from file. The alternative was to iterate the list and insert with npfctl table "table" add command, but is inneficient. I tried loading a file with single ip address to const database but returned ENOMEM on npfctl reload. I somewhat started in the wrong direction but mlelstv pointed me to '_npf_table_build_const' which maps the cdb file from /tmp to memory but immediately does munmap() without copying data with memcpy(). The code was trying to access memory that was already unmapped. Once this was solved, npfctl reload would return EINVAL around ioctl(IOC_NPF_LOAD) which from my understanding sends nvlist to kernel, the npf_mk_table() receives cdb data blob, the npf_table_create() calls cdbr_open_mem() on blob and now the lookups are done using cdbr_find(). The reason for the EINVAL appeared because the "entries" array was still present in memory from the time cdb was compi
led in memory and output to /tmp, so the npf_set.c in npf_mk_table_entries() proceeded to iterate ips still existing in memory and called npf_table_insert() for each one, but since npf_tableset.c as has NPF_TABLE_CONST set only to EINVAL because const are immutable, we simply got EINVAL. So we added nvlist_free() to free the memory where the ips were help at the time cdb file was compiled. After patching I have tested loading file to const table, reloading npf and that the table actually works for allowing/blocking ips. I am not experienced so please verify this carefully.
>How-To-Repeat:
# cat /etc/npf.conf | grep const
table <sshbl> type const file "/root/ssh.short.txt"
# npfctl reload
npfctl: Cannot allocate memory
# wc -l /root/ssh.short
1 /root/ssh.short.txt
>Fix:
--- src/lib/libnpf/npf.c.orig
+++ src/lib/libnpf/npf.c
@@ -1227,6 +1227,7 @@
free(buf);
goto out;
}
+ memcpy(buf, cdb, len);
munmap(cdb, len);
/*
@@ -1234,6 +1235,9 @@
*/
nvlist_move_binary(tl->table_dict, "data", buf, len);
error = nvlist_error(tl->table_dict);
+ if (!error) {
+ nvlist_free(tl->table_dict, "entries");
+ }
out:
if (fd != -1) {
close(fd);
Home |
Main Index |
Thread Index |
Old Index