X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=net%2Fipv4%2Fdevinet.c;h=a85a45964d4230a21498a7672bde2186d8abc368;hb=9bf4aaab3e101692164d49b7ca357651eb691cb6;hp=b97526d8c9627b26f7d5a3b017dbe9b72f10ddc9;hpb=a8e794ca871505c8ea96cc102f4ad555c5231d7f;p=linux-2.6.git diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index b97526d8c..a85a45964 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -516,7 +516,7 @@ static inline int devinet_notiproot (struct in_ifaddr *ifa) } -int devinet_ioctl(unsigned int cmd, void *arg) +int devinet_ioctl(unsigned int cmd, void __user *arg) { struct ifreq ifr; struct sockaddr_in sin_orig; @@ -728,6 +728,20 @@ int devinet_ioctl(unsigned int cmd, void *arg) inet_del_ifa(in_dev, ifap, 0); ifa->ifa_mask = sin->sin_addr.s_addr; ifa->ifa_prefixlen = inet_mask_len(ifa->ifa_mask); + + /* See if current broadcast address matches + * with current netmask, then recalculate + * the broadcast address. Otherwise it's a + * funny address, so don't touch it since + * the user seems to know what (s)he's doing... + */ + if ((dev->flags & IFF_BROADCAST) && + (ifa->ifa_prefixlen < 31) && + (ifa->ifa_broadcast == + (ifa->ifa_local|~ifa->ifa_mask))) { + ifa->ifa_broadcast = (ifa->ifa_local | + ~sin->sin_addr.s_addr); + } inet_insert_ifa(ifa); } break; @@ -742,7 +756,7 @@ rarok: goto out; } -static int inet_gifconf(struct net_device *dev, char *buf, int len) +static int inet_gifconf(struct net_device *dev, char __user *buf, int len) { struct in_device *in_dev = __in_dev_get(dev); struct in_ifaddr *ifa; @@ -1169,12 +1183,12 @@ void inet_forward_change(void) } static int devinet_sysctl_forward(ctl_table *ctl, int write, - struct file* filp, void *buffer, - size_t *lenp) + struct file* filp, void __user *buffer, + size_t *lenp, loff_t *ppos) { int *valp = ctl->data; int val = *valp; - int ret = proc_dointvec(ctl, write, filp, buffer, lenp); + int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); if (write && *valp != val) { if (valp == &ipv4_devconf.forwarding) @@ -1187,12 +1201,12 @@ static int devinet_sysctl_forward(ctl_table *ctl, int write, } int ipv4_doint_and_flush(ctl_table *ctl, int write, - struct file* filp, void *buffer, - size_t *lenp) + struct file* filp, void __user *buffer, + size_t *lenp, loff_t *ppos) { int *valp = ctl->data; int val = *valp; - int ret = proc_dointvec(ctl, write, filp, buffer, lenp); + int ret = proc_dointvec(ctl, write, filp, buffer, lenp, ppos); if (write && *valp != val) rt_cache_flush(0); @@ -1200,9 +1214,9 @@ int ipv4_doint_and_flush(ctl_table *ctl, int write, return ret; } -int ipv4_doint_and_flush_strategy(ctl_table *table, int *name, int nlen, - void *oldval, size_t *oldlenp, - void *newval, size_t newlen, +int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen, + void __user *oldval, size_t __user *oldlenp, + void __user *newval, size_t newlen, void **context) { int *valp = table->data; @@ -1214,7 +1228,7 @@ int ipv4_doint_and_flush_strategy(ctl_table *table, int *name, int nlen, if (newlen != sizeof(int)) return -EINVAL; - if (get_user(new, (int *)newval)) + if (get_user(new, (int __user *)newval)) return -EFAULT; if (new == *valp)