Hi,

        Please take a look and consider applying. One question: why
we need to set sk->dead to 1 before calling inet_sock_release in
inet6_create? sock_orphan does this for us and is called by
inet_sock_release.

                        - Arnaldo

--- linux-2.4.0-test8/net/ipv6/af_inet6.c       Wed Apr 26 16:13:17 2000
+++ linux-2.4.0-test8.acme/net/ipv6/af_inet6.c  Sun Sep 10 20:44:16 2000
@@ -11,6 +11,7 @@
  *
  *     Fixes:
  *     Hideaki YOSHIFUJI       :       sin6_scope_id support
+ *     Arnaldo Melo            :       check proc_net_create return, cleanups
  *
  *     This program is free software; you can redistribute it and/or
  *      modify it under the terms of the GNU General Public License
@@ -104,37 +105,45 @@
 
 static int inet6_create(struct socket *sock, int protocol)
 {
-       struct sock *sk;
+       int err = -EPROTONOSUPPORT;
        struct proto *prot;
+       struct sock *sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
 
-       sk = sk_alloc(PF_INET6, GFP_KERNEL, 1);
        if (sk == NULL) 
-               goto do_oom;
+               return -ENOBUFS;
 
-       if(sock->type == SOCK_STREAM || sock->type == SOCK_SEQPACKET) {
-               if (protocol && protocol != IPPROTO_TCP) 
-                       goto free_and_noproto;
-               protocol = IPPROTO_TCP;
-               prot = &tcpv6_prot;
-               sock->ops = &inet6_stream_ops;
-       } else if(sock->type == SOCK_DGRAM) {
-               if (protocol && protocol != IPPROTO_UDP) 
-                       goto free_and_noproto;
-               protocol = IPPROTO_UDP;
-               sk->no_check = UDP_CSUM_DEFAULT;
-               prot=&udpv6_prot;
-               sock->ops = &inet6_dgram_ops;
-       } else if(sock->type == SOCK_RAW) {
-               if (!capable(CAP_NET_RAW))
-                       goto free_and_badperm;
-               if (!protocol) 
-                       goto free_and_noproto;
-               prot = &rawv6_prot;
-               sock->ops = &inet6_dgram_ops;
-               sk->reuse = 1;
-               sk->num = protocol;
-       } else {
-               goto free_and_badtype;
+       switch(sock->type) {
+               case SOCK_STREAM:
+               case SOCK_SEQPACKET:
+                       if (protocol && protocol != IPPROTO_TCP)
+                               goto cleanup_sk;
+                       protocol = IPPROTO_TCP;
+                       prot = &tcpv6_prot;
+                       sock->ops = &inet6_stream_ops;
+                       break;
+               case SOCK_DGRAM:
+                       if (protocol && protocol != IPPROTO_UDP)
+                               goto cleanup_sk;
+                       protocol = IPPROTO_UDP;
+                       sk->no_check = UDP_CSUM_DEFAULT;
+                       prot = &udpv6_prot;
+                       sock->ops = &inet6_dgram_ops;
+                       break;
+               case SOCK_RAW:
+                       if (!capable(CAP_NET_RAW)) {
+                               err = -EPERM;
+                               goto cleanup_sk;
+                       }
+                       if (!protocol)
+                               goto cleanup_sk;
+                       prot = &rawv6_prot;
+                       sock->ops = &inet6_dgram_ops;
+                       sk->reuse = 1;
+                       sk->num = protocol;
+                       break;
+               default:
+                       err = -ESOCKTNOSUPPORT;
+                       goto cleanup_sk;
        }
        
        sock_init_data(sock, sk);
@@ -191,22 +200,14 @@
                if (err != 0) {
                        sk->dead = 1;
                        inet_sock_release(sk);
+                       MOD_DEC_USE_COUNT;
                        return(err);
                }
        }
        return(0);
-
-free_and_badtype:
-       sk_free(sk);
-       return -ESOCKTNOSUPPORT;
-free_and_badperm:
-       sk_free(sk);
-       return -EPERM;
-free_and_noproto:
+cleanup_sk:
        sk_free(sk);
-       return -EPROTONOSUPPORT;
-do_oom:
-       return -ENOBUFS;
+       return err;
 }
 
 
@@ -395,10 +396,8 @@
        {
        case FIOSETOWN:
        case SIOCSPGRP:
-               err = get_user(pid, (int *) arg);
-               if(err)
-                       return err;
-
+               if (get_user(pid, (int *) arg))
+                       return -EFAULT;
                /* see sock_no_fcntl */
                if (current->pid != pid && current->pgrp != -pid && 
                    !capable(CAP_NET_ADMIN))
@@ -407,24 +406,14 @@
                return(0);
        case FIOGETOWN:
        case SIOCGPGRP:
-               err = put_user(sk->proc,(int *)arg);
-               if(err)
-                       return err;
-               return(0);
+               return put_user(sk->proc,(int *)arg);
        case SIOCGSTAMP:
                if(sk->stamp.tv_sec==0)
                        return -ENOENT;
-               err = copy_to_user((void *)arg, &sk->stamp,
-                                  sizeof(struct timeval));
-               if (err)
-                       return -EFAULT;
-               return 0;
-
+               return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? 
+-EFAULT : 0;
        case SIOCADDRT:
        case SIOCDELRT:
-         
                return(ipv6_route_ioctl(cmd,(void *)arg));
-
        case SIOCSIFADDR:
                return addrconf_add_ifaddr((void *) arg);
        case SIOCDIFADDR:
@@ -550,6 +539,20 @@
        err = igmp6_init(&inet6_family_ops);
        if (err)
                goto igmp_fail;
+       /* Create /proc/foo6 entries. */
+#ifdef CONFIG_PROC_FS
+       err = -ENOMEM;
+       if (!proc_net_create("raw6", 0, raw6_get_info))
+               goto proc_raw6_fail;
+       if (!proc_net_create("tcp6", 0, tcp6_get_info))
+               goto proc_tcp6_fail;
+       if (!proc_net_create("udp6", 0, udp6_get_info))
+               goto proc_udp6_fail;
+       if (!proc_net_create("sockstat6", 0, afinet6_get_info))
+               goto proc_sockstat6_fail;
+       if (!proc_net_create("snmp6", 0, afinet6_get_snmp))
+               goto proc_snmp6_fail;
+#endif
        ipv6_netdev_notif_init();
        ipv6_packet_init();
        ip6_route_init();
@@ -561,15 +564,6 @@
        udpv6_init();
        tcpv6_init();
 
-       /* Create /proc/foo6 entries. */
-#ifdef CONFIG_PROC_FS
-       proc_net_create("raw6", 0, raw6_get_info);
-       proc_net_create("tcp6", 0, tcp6_get_info);
-       proc_net_create("udp6", 0, udp6_get_info);
-       proc_net_create("sockstat6", 0, afinet6_get_info);
-       proc_net_create("snmp6", 0, afinet6_get_snmp);
-#endif
-
        /* Now the userspace is allowed to create INET6 sockets. */
        (void) sock_register(&inet6_family_ops);
        
@@ -579,6 +573,18 @@
        return;
 #endif
 
+#ifdef CONFIG_PROC_FS
+proc_snmp6_fail:
+       proc_net_remove("sockstat6");
+proc_sockstat6_fail:
+       proc_net_remove("udp6");
+proc_udp6_fail:
+       proc_net_remove("tcp6");
+proc_tcp6_fail:
+        proc_net_remove("raw6");
+proc_raw6_fail:
+       igmp6_cleanup();
+#endif
 igmp_fail:
        ndisc_cleanup();
 ndisc_fail:
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [EMAIL PROTECTED]
Please read the FAQ at http://www.tux.org/lkml/

Reply via email to