The branch main has been updated by pouria:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=ea4888e63f6ac89c38982ffee693f89a5927e9c9

commit ea4888e63f6ac89c38982ffee693f89a5927e9c9
Author:     Teddy Engel <[email protected]>
AuthorDate: 2026-06-01 16:42:56 +0000
Commit:     Pouria Mousavizadeh Tehrani <[email protected]>
CommitDate: 2026-06-02 09:14:26 +0000

    nat64lsn: Fix type confusion panic when using wrong NAT64 instance type
    
    When an ipfw rule references a NAT64 instance by name using
    'nat64lsn', the kernel looks up the instance in the shared
    srvstate[] array without verifying the instance type.
    If the named instance is actually a nat64clat or nat64stl
    instance (created with 'nat64clat' or 'nat64stl'), the code
    incorrectly casts the instance to nat64lsn_instance and
    dereferences the ->cfg pointer, which causes a kernel panic.
    
    The root cause is that all NAT64 instance types share the same
    srvstate[] array but have different struct layouts.
    For nat64lsn_instance, the field after 'no' is a pointer to nat64lsn_cfg.
    For nat64clat_cfg, the same offset contains an embedded nat64_config struct.
    
    Fix by adding a type check after NAT64_LOOKUP() to verify that the
    instance's etlv matches IPFW_TLV_NAT64LSN_NAME before proceeding.
    If the type doesn't match, return IP_FW_DENY to reject the packet
    safely rather than crashing.
    
    Signed-off-by:  Teddy Engel <[email protected]>
    PR:             292023
    Reported by:    pouria
    Reviewed by:    ae
    Pull-Request:   https://github.com/freebsd/freebsd-src/pull/2249
---
 sys/netpfil/ipfw/nat64/nat64lsn.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sys/netpfil/ipfw/nat64/nat64lsn.c 
b/sys/netpfil/ipfw/nat64/nat64lsn.c
index 1bac425afc30..9d2ee5e650df 100644
--- a/sys/netpfil/ipfw/nat64/nat64lsn.c
+++ b/sys/netpfil/ipfw/nat64/nat64lsn.c
@@ -1731,7 +1731,8 @@ ipfw_nat64lsn(struct ip_fw_chain *ch, struct ip_fw_args 
*args,
        if (cmd->opcode != O_EXTERNAL_ACTION ||
            insntod(cmd, kidx)->kidx != V_nat64lsn_eid ||
            icmd->opcode != O_EXTERNAL_INSTANCE ||
-           (i = NAT64_LOOKUP(ch, icmd)) == NULL)
+           (i = NAT64_LOOKUP(ch, icmd)) == NULL ||
+           i->no.etlv != IPFW_TLV_NAT64LSN_NAME)
                return (IP_FW_DENY);
 
        *done = 1;      /* terminate the search */

Reply via email to