Bug 217292 - ipfw lookup on fields other than IP source and destination address doesn't work for IPv6
Summary: ipfw lookup on fields other than IP source and destination address doesn't wo...
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: kern (show other bugs)
Version: 11.0-RELEASE
Hardware: Any Any
: --- Affects Many People
Assignee: Andrey V. Elsukov
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-02-22 12:03 UTC by Jan Bramkamp
Modified: 2017-03-19 07:36 UTC (History)
3 users (show)

See Also:


Attachments
Proposed patch (8.37 KB, patch)
2017-03-03 15:20 UTC, Andrey V. Elsukov
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Jan Bramkamp 2017-02-22 12:03:11 UTC
The ipfw lookup action allows ipfw to match the specified field in a packet against a table. I wanted to use this to dynamically allow/deny TCP and UDP ports without changing the ruleset itself.

A reduced version of the ipfw script looks like this:

    # Create the table
    ipfw table tcp_open create type number algo number:array
    
    # Apply existing state
    ipfw add check-state
    
    # Establish new state
    ipfw add allow tcp from any to any lookup dst-port tcp_open keep-state setup

    # Open port 22/tcp
    ipfw table tcp_open add 22

This works as expected for IPv4, but the IPv6 code path in sys/netpfil/ipfw/ip_fw2.c:1517 can't deal with anything other than lookups on the source/destination IPv6 address yet neither does the ipfw manpage mention this limitation nor does ipfw refuse to load rules which can match IPv6 packets against lookup actions on fields other than the IP addresses.

In my ruleset this "just" blocked all incoming IPv6 connections, but in other rulesets it could just as easily expose IPv6 services to attackers.
Comment 1 Andrey V. Elsukov freebsd_committer 2017-03-03 15:20:39 UTC
Created attachment 180465 [details]
Proposed patch

Hi, can you test the attached patch? I did only basic test, so if you are able to do a wider testing, please, report what you tried.
Comment 2 commit-hook freebsd_committer 2017-03-05 23:49:21 UTC
A commit references this bug:

Author: ae
Date: Sun Mar  5 23:48:24 UTC 2017
New revision: 314716
URL: https://svnweb.freebsd.org/changeset/base/314716

Log:
  Add IPv6 support to O_IP_DST_LOOKUP opcode.

  o check the size of O_IP_SRC_LOOKUP opcode, it can not exceed the size of
    ipfw_insn_u32;
  o rename ipfw_lookup_table_extended() function into ipfw_lookup_table() and
    remove old ipfw_lookup_table();
  o use args->f_id.flow_id6 that is in host byte order to get DSCP value;
  o add SCTP ports support to 'lookup src/dst-port' opcode;
  o add IPv6 support to 'lookup src/dst-ip' opcode.

  PR:		217292
  Reviewed by:	melifaro
  MFC after:	2 weeks
  Sponsored by:	Yandex LLC
  Differential Revision:	https://reviews.freebsd.org/D9873

Changes:
  head/sys/netpfil/ipfw/ip_fw2.c
  head/sys/netpfil/ipfw/ip_fw_private.h
  head/sys/netpfil/ipfw/ip_fw_sockopt.c
  head/sys/netpfil/ipfw/ip_fw_table.c
Comment 3 Jan Bramkamp 2017-03-06 10:06:36 UTC
Thank you for the patch. I will perform some testing later today.
Comment 4 commit-hook freebsd_committer 2017-03-19 07:35:21 UTC
A commit references this bug:

Author: ae
Date: Sun Mar 19 07:34:19 UTC 2017
New revision: 315532
URL: https://svnweb.freebsd.org/changeset/base/315532

Log:
  MFC r314716:
    Add IPv6 support to O_IP_DST_LOOKUP opcode.

    o check the size of O_IP_SRC_LOOKUP opcode, it can not exceed the size of
      ipfw_insn_u32;
    o rename ipfw_lookup_table_extended() function into ipfw_lookup_table() and
      remove old ipfw_lookup_table();
    o use args->f_id.flow_id6 that is in host byte order to get DSCP value;
    o add SCTP ports support to 'lookup src/dst-port' opcode;
    o add IPv6 support to 'lookup src/dst-ip' opcode.

    PR:		217292
    Sponsored by:	Yandex LLC
    Differential Revision:	https://reviews.freebsd.org/D9873

Changes:
_U  stable/11/
  stable/11/sys/netpfil/ipfw/ip_fw2.c
  stable/11/sys/netpfil/ipfw/ip_fw_private.h
  stable/11/sys/netpfil/ipfw/ip_fw_sockopt.c
  stable/11/sys/netpfil/ipfw/ip_fw_table.c