Bug 57492

Summary: Firewall can be disabled in securelevel 3
Product: Base System Reporter: Bernd Luevelsmeyer <bernd>
Component: kernAssignee: Bruce M Simpson <bms>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 4.9-PRERELEASE   
Hardware: Any   
OS: Any   

Description Bernd Luevelsmeyer 2003-10-02 12:40:09 UTC
    init(8) says, you cannot change ipfw rules in securelevel 3.
    It is possible, though, to disable the entire firewall,
    effectively deleting all rules and adding a rule "pass all
    from any to any".

Fix: 

unknown
How-To-Repeat:     On a machine that has a firewall and runs in securelevel 3,
    as root enter
      sysctl net.inet.ip.fw.enable=0
    You can now send and receive packets that otherwise would
    be rejected by the firewall.
Comment 1 ru freebsd_committer freebsd_triage 2003-10-02 13:05:26 UTC
State Changed
From-To: open->closed

# uname -r 
4.9-PRERELEASE 
# sysctl kern.securelevel 
kern.securelevel: -1 
# sysctl net.inet.ip.fw.enable=0 
net.inet.ip.fw.enable: 1 -> 0 
# sysctl net.inet.ip.fw.enable=1 
net.inet.ip.fw.enable: 0 -> 1 
# sysctl kern.securelevel=3 
kern.securelevel: -1 -> 3 
# sysctl net.inet.ip.fw.enable=0 
net.inet.ip.fw.enable: 1 
sysctl: net.inet.ip.fw.enable: Operation not permitted
Comment 2 ru freebsd_committer freebsd_triage 2003-10-02 13:09:03 UTC
On Thu, Oct 02, 2003 at 05:06:02AM -0700, Ruslan Ermilov wrote:
> Synopsis: Firewall can be disabled in securelevel 3
> 
> State-Changed-From-To: open->closed
> State-Changed-By: ru
> State-Changed-When: Thu Oct 2 05:05:26 PDT 2003
> State-Changed-Why: 
> # uname -r
> 4.9-PRERELEASE
> # sysctl kern.securelevel
> kern.securelevel: -1
> # sysctl net.inet.ip.fw.enable=0
> net.inet.ip.fw.enable: 1 -> 0
> # sysctl net.inet.ip.fw.enable=1
> net.inet.ip.fw.enable: 0 -> 1
> # sysctl kern.securelevel=3
> kern.securelevel: -1 -> 3
> # sysctl net.inet.ip.fw.enable=0
> net.inet.ip.fw.enable: 1
> sysctl: net.inet.ip.fw.enable: Operation not permitted
> 
My apologies, I forgot that I have this problem fixed locally,
but it's not in the FreeBSD repository.  I will re-open the
bug.  The patch, FWIW, is as follows:

%%%
Index: ip_fw.c
===================================================================
RCS file: /home/ncvs/src/sys/netinet/Attic/ip_fw.c,v
retrieving revision 1.131.2.39
diff -u -p -r1.131.2.39 ip_fw.c
--- ip_fw.c	20 Jan 2003 02:23:07 -0000	1.131.2.39
+++ ip_fw.c	2 Oct 2003 12:07:35 -0000
@@ -94,11 +94,21 @@ LIST_HEAD (ip_fw_head, ip_fw) ip_fw_chai
 MALLOC_DEFINE(M_IPFW, "IpFw/IpAcct", "IpFw/IpAcct chain's");
 
 #ifdef SYSCTL_NODE
+
+static int
+sysctl_fw_securelevel_check(SYSCTL_HANDLER_ARGS)
+{
+
+	if (req->newptr && securelevel >= 3)
+		return (EPERM);
+	return sysctl_handle_int(oidp, arg1, arg2, req);
+}
+
 SYSCTL_NODE(_net_inet_ip, OID_AUTO, fw, CTLFLAG_RW, 0, "Firewall");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, enable, CTLFLAG_RW,
-    &fw_enable, 0, "Enable ipfw");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO,one_pass,CTLFLAG_RW, 
-    &fw_one_pass, 0, 
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, enable, CTLTYPE_INT|CTLFLAG_RW,
+    &fw_enable, 0, sysctl_fw_securelevel_check, "I", "Enable ipfw");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, one_pass, CTLTYPE_INT|CTLFLAG_RW,
+    &fw_one_pass, 0, sysctl_fw_securelevel_check, "I",
     "Only do a single pass through ipfw when using dummynet(4)");
 SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, debug, CTLFLAG_RW, 
     &fw_debug, 0, "Enable printing of debug ip_fw statements");
@@ -173,30 +183,40 @@ static u_int32_t static_count = 0 ;	/* #
 static u_int32_t dyn_count = 0 ;	/* # of dynamic rules */
 static u_int32_t dyn_max = 1000 ;	/* max # of dynamic rules */
 
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLFLAG_RW,
-    &dyn_buckets, 0, "Number of dyn. buckets");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLFLAG_RD,
-    &curr_dyn_buckets, 0, "Current Number of dyn. buckets");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_count, CTLFLAG_RD,
-    &dyn_count, 0, "Number of dyn. rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_max, CTLFLAG_RW,
-    &dyn_max, 0, "Max number of dyn. rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, static_count, CTLFLAG_RD,
-    &static_count, 0, "Number of static rules");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLFLAG_RW,
-    &dyn_ack_lifetime, 0, "Lifetime of dyn. rules for acks");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLFLAG_RW,
-    &dyn_syn_lifetime, 0, "Lifetime of dyn. rules for syn");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime, CTLFLAG_RW,
-    &dyn_fin_lifetime, 0, "Lifetime of dyn. rules for fin");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLFLAG_RW,
-    &dyn_rst_lifetime, 0, "Lifetime of dyn. rules for rst");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime, CTLFLAG_RW,
-    &dyn_udp_lifetime, 0, "Lifetime of dyn. rules for UDP");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLFLAG_RW,
-    &dyn_short_lifetime, 0, "Lifetime of dyn. rules for other situations");
-SYSCTL_INT(_net_inet_ip_fw, OID_AUTO, dyn_grace_time, CTLFLAG_RD,
-    &dyn_grace_time, 0, "Grace time for dyn. rules");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_buckets, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_buckets, 0, sysctl_fw_securelevel_check, "IU",
+    "Number of dyn. buckets");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, curr_dyn_buckets, CTLTYPE_INT|CTLFLAG_RD,
+    &curr_dyn_buckets, 0, sysctl_fw_securelevel_check, "IU",
+    "Current Number of dyn. buckets");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_count, CTLTYPE_INT|CTLFLAG_RD,
+    &dyn_count, 0, sysctl_fw_securelevel_check, "IU", "Number of dyn. rules");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_max, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_max, 0, sysctl_fw_securelevel_check, "IU", "Max number of dyn. rules");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, static_count, CTLTYPE_INT|CTLFLAG_RD,
+    &static_count, 0, sysctl_fw_securelevel_check, "IU",
+    "Number of static rules");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_ack_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_ack_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for acks");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_syn_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_syn_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for syn");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_fin_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_fin_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for fin");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_rst_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_rst_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for rst");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_udp_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_udp_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for UDP");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_short_lifetime, CTLTYPE_INT|CTLFLAG_RW,
+    &dyn_short_lifetime, 0, sysctl_fw_securelevel_check, "IU",
+    "Lifetime of dyn. rules for other situations");
+SYSCTL_PROC(_net_inet_ip_fw, OID_AUTO, dyn_grace_time, CTLTYPE_INT|CTLFLAG_RD,
+    &dyn_grace_time, 0, sysctl_fw_securelevel_check, "IU",
+    "Grace time for dyn. rules");
 
 #endif /* SYSCTL_NODE */
 
%%%

-- 
Ruslan Ermilov		Sysadmin and DBA,
ru@sunbay.com		Sunbay Software Ltd,
ru@FreeBSD.org		FreeBSD committer
Comment 3 ru freebsd_committer freebsd_triage 2003-10-02 13:10:49 UTC
State Changed
From-To: closed->open

Closed by mistake.
Comment 4 Bruce M Simpson freebsd_committer freebsd_triage 2003-10-05 07:44:19 UTC
State Changed
From-To: open->feedback

This should have been fixed by rev 1.6.2.17 of ip_fw2.c 
Please let me know if you can still reproduce the issue. 


Comment 5 Bruce M Simpson freebsd_committer freebsd_triage 2003-10-05 07:44:19 UTC
Responsible Changed
From-To: freebsd-bugs->bms

I recently committed a fix for PR kern/39396 which looks to be a duplicate.
Comment 6 Bruce M Simpson freebsd_committer freebsd_triage 2003-11-15 08:34:51 UTC
State Changed
From-To: feedback->closed

Timeout on feedback from originator. Problem believed fixed in previous commit 
to RELENG_4.