netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] multi-protocol MSF API sysctl limit support
@ 2004-03-06  9:37 David Stevens
  2004-03-08 20:17 ` David S. Miller
  0 siblings, 1 reply; 2+ messages in thread
From: David Stevens @ 2004-03-06  9:37 UTC (permalink / raw)
  To: netdev, davem


[-- Attachment #1.1: Type: text/plain, Size: 5521 bytes --]





This patch adds support for administrator-controlled multicast source
filter limits for the multiprotocol multicast source filter API. The v4
portion
uses the same sysctl variable as the previous v4-only API patch, and
the v6 portion uses a new v6 sysctl variable, "mld_max_msf".

In-line 2.4.x and attached 2.4.x and 2.6.x versions.

                        +-DLS

diff -ruN linux-2.4.25F4/include/linux/sysctl.h linux-2.4.25F5/include/linux/sysctl.h
--- linux-2.4.25F4/include/linux/sysctl.h 2004-03-04 17:02:54.000000000 -0800
+++ linux-2.4.25F5/include/linux/sysctl.h 2004-03-05 00:02:57.000000000 -0800
@@ -388,7 +388,8 @@
      NET_IPV6_NEIGH=17,
      NET_IPV6_ROUTE=18,
      NET_IPV6_ICMP=19,
-     NET_IPV6_BINDV6ONLY=20
+     NET_IPV6_BINDV6ONLY=20,
+     NET_IPV6_MLD_MAX_MSF=25,
 };

 enum {
diff -ruN linux-2.4.25F4/include/net/ipv6.h linux-2.4.25F5/include/net/ipv6.h
--- linux-2.4.25F4/include/net/ipv6.h     2004-03-04 17:15:19.000000000 -0800
+++ linux-2.4.25F5/include/net/ipv6.h     2004-03-05 00:19:31.000000000 -0800
@@ -104,6 +104,7 @@

 /* sysctls */
 extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;

 extern struct ipv6_mib       ipv6_statistics[NR_CPUS*2];
 #define IP6_INC_STATS(field)       SNMP_INC_STATS(ipv6_statistics, field)
diff -ruN linux-2.4.25F4/net/ipv4/ip_sockglue.c linux-2.4.25F5/net/ipv4/ip_sockglue.c
--- linux-2.4.25F4/net/ipv4/ip_sockglue.c 2004-03-04 19:29:33.000000000 -0800
+++ linux-2.4.25F5/net/ipv4/ip_sockglue.c 2004-03-05 16:21:06.000000000 -0800
@@ -762,6 +762,8 @@
            }
            case MCAST_MSFILTER:
            {
+                 extern int sysctl_optmem_max;
+                 extern int sysctl_igmp_max_msf;
                  struct sockaddr_in *psin;
                  struct ip_msfilter *msf = 0;
                  struct group_filter *gsf = 0;
@@ -769,6 +771,10 @@

                  if (optlen < GROUP_FILTER_SIZE(0))
                        goto e_inval;
+                 if (optlen > sysctl_optmem_max) {
+                       err = -ENOBUFS;
+                       break;
+                 }
                  gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
                  if (gsf == 0) {
                        err = -ENOBUFS;
@@ -778,7 +784,13 @@
                  if (copy_from_user(gsf, optval, optlen)) {
                        goto mc_msf_out;
                  }
-                 if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+                 /* numsrc >= (4G-140)/128 overflow in 32 bits */
+                 if (gsf->gf_numsrc >= 0x1ffffff ||
+                     gsf->gf_numsrc > sysctl_igmp_max_msf) {
+                       err = -ENOBUFS;
+                       goto mc_msf_out;
+                 }
+                 if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
                        err = EINVAL;
                        goto mc_msf_out;
                  }
diff -ruN linux-2.4.25F4/net/ipv6/ipv6_sockglue.c linux-2.4.25F5/net/ipv6/ipv6_sockglue.c
--- linux-2.4.25F4/net/ipv6/ipv6_sockglue.c     2004-02-23 16:35:09.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/ipv6_sockglue.c     2004-03-05 01:57:30.000000000 -0800
@@ -453,6 +453,7 @@
      case MCAST_MSFILTER:
      {
            extern int sysctl_optmem_max;
+           extern int sysctl_mld_max_msf;
            struct group_filter *gsf;

            if (optlen < GROUP_FILTER_SIZE(0))
@@ -471,8 +472,14 @@
                  kfree(gsf);
                  break;
            }
-           if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
-               GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+           /* numsrc >= (4G-140)/128 overflow in 32 bits */
+           if (gsf->gf_numsrc >= 0x1ffffffU ||
+               gsf->gf_numsrc > sysctl_mld_max_msf) {
+                 kfree(gsf);
+                 retv = -ENOBUFS;
+                 break;
+           }
+           if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
                  kfree(gsf);
                  retv = -EINVAL;
                  break;
diff -ruN linux-2.4.25F4/net/ipv6/mcast.c linux-2.4.25F5/net/ipv6/mcast.c
--- linux-2.4.25F4/net/ipv6/mcast.c 2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/mcast.c 2004-03-04 22:37:31.000000000 -0800
@@ -163,6 +163,10 @@
 #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
 #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)

+#define IPV6_MLD_MAX_MSF     10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
 /*
  *   socket join on multicast group
  */
@@ -401,6 +405,10 @@
      }
      /* else, add a new source to the filter */

+     if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+           err = -ENOBUFS;
+           goto done;
+     }
      if (!psl || psl->sl_count == psl->sl_max) {
            struct ip6_sf_socklist *newpsl;
            int count = IP6_SFBLOCK;
diff -ruN linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c
--- linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c   2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c   2004-03-05 00:01:05.000000000 -0800
@@ -24,6 +24,8 @@
      {NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
      {NET_IPV6_BINDV6ONLY, "bindv6only",
       &sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
+     {NET_IPV6_MLD_MAX_MSF, "mld_max_msf",
+      &sysctl_mld_max_msf, sizeof(int), 0644, NULL, &proc_dointvec},
      {0}
 };

(See attached file: 2.4.25mpmsflimit.patch)
(See attached file: 2.6.4rc2mpmsflimit.patch)

[-- Attachment #1.2: Type: text/html, Size: 5411 bytes --]

[-- Attachment #2: 2.4.25mpmsflimit.patch --]
[-- Type: application/octet-stream, Size: 4238 bytes --]

diff -ruN linux-2.4.25F4/include/linux/sysctl.h linux-2.4.25F5/include/linux/sysctl.h
--- linux-2.4.25F4/include/linux/sysctl.h	2004-03-04 17:02:54.000000000 -0800
+++ linux-2.4.25F5/include/linux/sysctl.h	2004-03-05 00:02:57.000000000 -0800
@@ -388,7 +388,8 @@
 	NET_IPV6_NEIGH=17,
 	NET_IPV6_ROUTE=18,
 	NET_IPV6_ICMP=19,
-	NET_IPV6_BINDV6ONLY=20
+	NET_IPV6_BINDV6ONLY=20,
+	NET_IPV6_MLD_MAX_MSF=25,
 };
 
 enum {
diff -ruN linux-2.4.25F4/include/net/ipv6.h linux-2.4.25F5/include/net/ipv6.h
--- linux-2.4.25F4/include/net/ipv6.h	2004-03-04 17:15:19.000000000 -0800
+++ linux-2.4.25F5/include/net/ipv6.h	2004-03-05 00:19:31.000000000 -0800
@@ -104,6 +104,7 @@
 
 /* sysctls */
 extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
 
 extern struct ipv6_mib		ipv6_statistics[NR_CPUS*2];
 #define IP6_INC_STATS(field)		SNMP_INC_STATS(ipv6_statistics, field)
diff -ruN linux-2.4.25F4/net/ipv4/ip_sockglue.c linux-2.4.25F5/net/ipv4/ip_sockglue.c
--- linux-2.4.25F4/net/ipv4/ip_sockglue.c	2004-03-04 19:29:33.000000000 -0800
+++ linux-2.4.25F5/net/ipv4/ip_sockglue.c	2004-03-05 16:21:06.000000000 -0800
@@ -762,6 +762,8 @@
 		}
 		case MCAST_MSFILTER:
 		{
+			extern int sysctl_optmem_max;
+			extern int sysctl_igmp_max_msf;
 			struct sockaddr_in *psin;
 			struct ip_msfilter *msf = 0;
 			struct group_filter *gsf = 0;
@@ -769,6 +771,10 @@
 
 			if (optlen < GROUP_FILTER_SIZE(0))
 				goto e_inval;
+			if (optlen > sysctl_optmem_max) {
+				err = -ENOBUFS;
+				break;
+			}
 			gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
 			if (gsf == 0) {
 				err = -ENOBUFS;
@@ -778,7 +784,13 @@
 			if (copy_from_user(gsf, optval, optlen)) {
 				goto mc_msf_out;
 			}
-			if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+			/* numsrc >= (4G-140)/128 overflow in 32 bits */
+			if (gsf->gf_numsrc >= 0x1ffffff ||
+			    gsf->gf_numsrc > sysctl_igmp_max_msf) {
+				err = -ENOBUFS;
+				goto mc_msf_out;
+			}
+			if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
 				err = EINVAL;
 				goto mc_msf_out;
 			}
diff -ruN linux-2.4.25F4/net/ipv6/ipv6_sockglue.c linux-2.4.25F5/net/ipv6/ipv6_sockglue.c
--- linux-2.4.25F4/net/ipv6/ipv6_sockglue.c	2004-02-23 16:35:09.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/ipv6_sockglue.c	2004-03-05 01:57:30.000000000 -0800
@@ -453,6 +453,7 @@
 	case MCAST_MSFILTER:
 	{
 		extern int sysctl_optmem_max;
+		extern int sysctl_mld_max_msf;
 		struct group_filter *gsf;
 
 		if (optlen < GROUP_FILTER_SIZE(0))
@@ -471,8 +472,14 @@
 			kfree(gsf);
 			break;
 		}
-		if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
-		    GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+		/* numsrc >= (4G-140)/128 overflow in 32 bits */
+		if (gsf->gf_numsrc >= 0x1ffffffU ||
+		    gsf->gf_numsrc > sysctl_mld_max_msf) {
+			kfree(gsf);
+			retv = -ENOBUFS;
+			break;
+		}
+		if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
 			kfree(gsf);
 			retv = -EINVAL;
 			break;
diff -ruN linux-2.4.25F4/net/ipv6/mcast.c linux-2.4.25F5/net/ipv6/mcast.c
--- linux-2.4.25F4/net/ipv6/mcast.c	2004-02-18 05:36:32.000000000 -0800
+++ linux-2.4.25F5/net/ipv6/mcast.c	2004-03-04 22:37:31.000000000 -0800
@@ -163,6 +163,10 @@
 #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
 #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
 
+#define IPV6_MLD_MAX_MSF	10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
 /*
  *	socket join on multicast group
  */
@@ -401,6 +405,10 @@
 	}
 	/* else, add a new source to the filter */
 
+	if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+		err = -ENOBUFS;
+		goto done;
+	}
 	if (!psl || psl->sl_count == psl->sl_max) {
 		struct ip6_sf_socklist *newpsl;
 		int count = IP6_SFBLOCK;
diff -ruN linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c
--- linux-2.4.25F4/net/ipv6/sysctl_net_ipv6.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.25F5/net/ipv6/sysctl_net_ipv6.c	2004-03-05 00:01:05.000000000 -0800
@@ -24,6 +24,8 @@
 	{NET_IPV6_ICMP, "icmp", NULL, 0, 0500, ipv6_icmp_table},
 	{NET_IPV6_BINDV6ONLY, "bindv6only",
 	 &sysctl_ipv6_bindv6only, sizeof(int), 0644, NULL, &proc_dointvec},
+	{NET_IPV6_MLD_MAX_MSF, "mld_max_msf",
+	 &sysctl_mld_max_msf, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 

[-- Attachment #3: 2.6.4rc2mpmsflimit.patch --]
[-- Type: application/octet-stream, Size: 4299 bytes --]

diff -ruN linux-2.6.4rc2F1/include/linux/sysctl.h linux-2.6.4rc2F2/include/linux/sysctl.h
--- linux-2.6.4rc2F1/include/linux/sysctl.h	2004-03-04 16:57:26.000000000 -0800
+++ linux-2.6.4rc2F2/include/linux/sysctl.h	2004-03-06 00:18:17.000000000 -0800
@@ -405,7 +405,8 @@
 	NET_IPV6_IP6FRAG_HIGH_THRESH=21,
 	NET_IPV6_IP6FRAG_LOW_THRESH=22,
 	NET_IPV6_IP6FRAG_TIME=23,
-	NET_IPV6_IP6FRAG_SECRET_INTERVAL=24
+	NET_IPV6_IP6FRAG_SECRET_INTERVAL=24,
+	NET_IPV6_MLD_MAX_MSF=25,
 };
 
 enum {
diff -ruN linux-2.6.4rc2F1/include/net/ipv6.h linux-2.6.4rc2F2/include/net/ipv6.h
--- linux-2.6.4rc2F1/include/net/ipv6.h	2004-03-04 16:18:23.000000000 -0800
+++ linux-2.6.4rc2F2/include/net/ipv6.h	2004-03-06 00:10:21.000000000 -0800
@@ -108,6 +108,7 @@
 
 /* sysctls */
 extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
 
 /* MIBs */
 DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
diff -ruN linux-2.6.4rc2F1/net/ipv4/ip_sockglue.c linux-2.6.4rc2F2/net/ipv4/ip_sockglue.c
--- linux-2.6.4rc2F1/net/ipv4/ip_sockglue.c	2004-03-04 19:30:26.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv4/ip_sockglue.c	2004-03-06 00:10:21.000000000 -0800
@@ -771,6 +771,8 @@
 		}
 		case MCAST_MSFILTER:
 		{
+			extern int sysctl_optmem_max;
+			extern int sysctl_igmp_max_msf;
 			struct sockaddr_in *psin;
 			struct ip_msfilter *msf = 0;
 			struct group_filter *gsf = 0;
@@ -778,6 +780,10 @@
 
 			if (optlen < GROUP_FILTER_SIZE(0))
 				goto e_inval;
+			if (optlen > sysctl_optmem_max) {
+				err = -ENOBUFS;
+				break;
+			}
 			gsf = (struct group_filter *)kmalloc(optlen,GFP_KERNEL);
 			if (gsf == 0) {
 				err = -ENOBUFS;
@@ -787,7 +793,13 @@
 			if (copy_from_user(gsf, optval, optlen)) {
 				goto mc_msf_out;
 			}
-			if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < optlen) {
+			/* numsrc >= (4G-140)/128 overflow in 32 bits */
+			if (gsf->gf_numsrc >= 0x1ffffff ||
+			    gsf->gf_numsrc > sysctl_igmp_max_msf) {
+				err = -ENOBUFS;
+				goto mc_msf_out;
+			}
+			if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
 				err = EINVAL;
 				goto mc_msf_out;
 			}
diff -ruN linux-2.6.4rc2F1/net/ipv6/ipv6_sockglue.c linux-2.6.4rc2F2/net/ipv6/ipv6_sockglue.c
--- linux-2.6.4rc2F1/net/ipv6/ipv6_sockglue.c	2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/ipv6_sockglue.c	2004-03-06 00:10:21.000000000 -0800
@@ -437,6 +437,7 @@
 	case MCAST_MSFILTER:
 	{
 		extern int sysctl_optmem_max;
+		extern int sysctl_mld_max_msf;
 		struct group_filter *gsf;
 
 		if (optlen < GROUP_FILTER_SIZE(0))
@@ -455,8 +456,14 @@
 			kfree(gsf);
 			break;
 		}
-		if (GROUP_FILTER_SIZE(gsf->gf_numsrc) < GROUP_FILTER_SIZE(0) ||
-		    GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
+		/* numsrc >= (4G-140)/128 overflow in 32 bits */
+		if (gsf->gf_numsrc >= 0x1ffffffU ||
+		    gsf->gf_numsrc > sysctl_mld_max_msf) {
+			kfree(gsf);
+			retv = -ENOBUFS;
+			break;
+		}
+		if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
 			kfree(gsf);
 			retv = -EINVAL;
 			break;
diff -ruN linux-2.6.4rc2F1/net/ipv6/mcast.c linux-2.6.4rc2F2/net/ipv6/mcast.c
--- linux-2.6.4rc2F1/net/ipv6/mcast.c	2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/mcast.c	2004-03-06 00:10:21.000000000 -0800
@@ -166,6 +166,10 @@
 #define MLDV2_QQIC(value) MLDV2_EXP(0x80, 4, 3, value)
 #define MLDV2_MRC(value) MLDV2_EXP(0x8000, 12, 3, value)
 
+#define IPV6_MLD_MAX_MSF	10
+
+int sysctl_mld_max_msf = IPV6_MLD_MAX_MSF;
+
 /*
  *	socket join on multicast group
  */
@@ -404,6 +408,10 @@
 	}
 	/* else, add a new source to the filter */
 
+	if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+		err = -ENOBUFS;
+		goto done;
+	}
 	if (!psl || psl->sl_count == psl->sl_max) {
 		struct ip6_sf_socklist *newpsl;
 		int count = IP6_SFBLOCK;
diff -ruN linux-2.6.4rc2F1/net/ipv6/sysctl_net_ipv6.c linux-2.6.4rc2F2/net/ipv6/sysctl_net_ipv6.c
--- linux-2.6.4rc2F1/net/ipv6/sysctl_net_ipv6.c	2004-03-04 16:18:24.000000000 -0800
+++ linux-2.6.4rc2F2/net/ipv6/sysctl_net_ipv6.c	2004-03-06 00:16:32.000000000 -0800
@@ -76,6 +76,14 @@
 		.proc_handler	= &proc_dointvec_jiffies,
 		.strategy	= &sysctl_jiffies
 	},
+	{
+		.ctl_name	= NET_IPV6_MLD_MAX_MSF,
+		.procname	= "mld_max_msf",
+		.data		= &sysctl_mld_max_msf,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec
+	},
 	{ .ctl_name = 0 }
 };
 

^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2004-03-08 20:17 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-03-06  9:37 [PATCH] multi-protocol MSF API sysctl limit support David Stevens
2004-03-08 20:17 ` David S. Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).