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 {
/* sysctls */
extern int sysctl_ipv6_bindv6only;
+extern int sysctl_mld_max_msf;
/* MIBs */
DECLARE_SNMP_STAT(struct ipv6_mib, ipv6_statistics);
}
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;
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;
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;
}
case MCAST_MSFILTER:
{
extern int sysctl_optmem_max;
+ extern int sysctl_mld_max_msf;
struct group_filter *gsf;
if (optlen < GROUP_FILTER_SIZE(0))
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;
#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
*/
}
/* 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;
.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 }
};