patch-2.2.0-pre6 linux/net/ipv4/ip_fw.c

Next file: linux/net/ipv4/tcp.c
Previous file: linux/net/core/dev.c
Back to the patch index
Back to the overall index

diff -u --recursive --new-file v2.2.0-pre5/linux/net/ipv4/ip_fw.c linux/net/ipv4/ip_fw.c
@@ -29,6 +29,9 @@
  * 1-May-1998:  Remove caching of device pointer.
  * 12-May-1998: Allow tiny fragment case for TCP/UDP.
  * 15-May-1998: Treat short packets as fragments, don't just block.
+ * 3-Jan-1999:  Fixed serious procfs security hole -- users should never
+ *              be allowed to view the chains!
+ *              Marc Santoro <ultima@snicker.emoti.com>
  */
 
 /*
@@ -509,7 +512,7 @@
 		printk("%s\n",chain->label);
 }
 
-static inline void
+static inline int
 ip_fw_domatch(struct ip_fwkernel *f,
 	      struct iphdr *ip, 
 	      const char *rif,
@@ -550,9 +553,15 @@
 			       len-(sizeof(__u32)*2+IFNAMSIZ));
 			netlink_broadcast(ipfwsk, outskb, 0, ~0, GFP_KERNEL);
 		}
-		else duprintf("netlink post failed - alloc_skb failed!\n");
+		else {
+			if (net_ratelimit())
+				printk(KERN_WARNING "ip_fw: packet drop due to "
+				       "netlink failure\n");
+			return 0;
+		}
 	}
 #endif
+	return 1;
 }
 
 /*
@@ -695,9 +704,13 @@
 		for (; f; f = f->next) {
 			if (ip_rule_match(f,rif,ip,
 					  tcpsyn,src_port,dst_port,offset)) {
-				if (!testing)
-					ip_fw_domatch(f, ip, rif, chain->label, skb,
-						      slot, src_port,dst_port);
+				if (!testing
+				    && !ip_fw_domatch(f, ip, rif, chain->label,
+						      skb, slot, 
+						      src_port, dst_port)) {
+					ret = FW_BLOCK;
+					goto out;
+				}
 				break;
 			}
 		}
@@ -759,6 +772,7 @@
 		}
 	} while (ret == FW_SKIP+2);
 
+ out:
 	if (!testing) FWC_READ_UNLOCK(&ip_fw_lock);
 
 	/* Recalculate checksum if not going to reject, and TOS changed. */
@@ -1671,13 +1685,13 @@
 #ifdef CONFIG_PROC_FS		
 static struct proc_dir_entry proc_net_ipfwchains_chain = {
 	PROC_NET_IPFW_CHAINS, sizeof(IP_FW_PROC_CHAINS)-1, 
-	IP_FW_PROC_CHAINS, S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
+	IP_FW_PROC_CHAINS, S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
 	0, &proc_net_inode_operations, ip_chain_procinfo
 };
 
 static struct proc_dir_entry proc_net_ipfwchains_chainnames = {
 	PROC_NET_IPFW_CHAIN_NAMES, sizeof(IP_FW_PROC_CHAIN_NAMES)-1, 
-	IP_FW_PROC_CHAIN_NAMES, S_IFREG | S_IRUGO | S_IWUSR, 1, 0, 0,
+	IP_FW_PROC_CHAIN_NAMES, S_IFREG | S_IRUSR | S_IWUSR, 1, 0, 0,
 	0, &proc_net_inode_operations, ip_chain_name_procinfo
 };
 

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov