Messages in this thread Patch in this message |  | | Date | Sun, 10 Sep 2000 20:58:52 -0300 | From | Arnaldo Carvalho de Melo <> | Subject | [PATCH] af_ipv6.c: check proc_net_create and cleanups |
| |
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 majordomo@vger.kernel.org Please read the FAQ at http://www.tux.org/lkml/
|  |