--- zzzz-none-000/linux-2.6.19.2/net/socket.c 2007-01-10 19:10:37.000000000 +0000 +++ davinci-8020-5504/linux-2.6.19.2/net/socket.c 2007-07-03 11:34:51.000000000 +0000 @@ -85,6 +85,7 @@ #include #include #include +#include #include #include @@ -94,6 +95,21 @@ #include #include +extern void gr_attach_curr_ip(const struct sock *sk); +extern int gr_handle_sock_all(const int family, const int type, + const int protocol); +extern int gr_handle_sock_server(const struct sockaddr *sck); +extern int gr_handle_sock_server_other(const struct socket *sck); +extern int gr_handle_sock_client(const struct sockaddr *sck); +extern int gr_search_connect(const struct socket * sock, + const struct sockaddr_in * addr); +extern int gr_search_bind(const struct socket * sock, + const struct sockaddr_in * addr); +extern int gr_search_listen(const struct socket * sock); +extern int gr_search_accept(const struct socket * sock); +extern int gr_search_socket(const int domain, const int type, + const int protocol); + static int sock_no_open(struct inode *irrelevant, struct file *dontcare); static ssize_t sock_aio_read(struct kiocb *iocb, const struct iovec *iov, unsigned long nr_segs, loff_t pos); @@ -296,7 +312,7 @@ mnt); } -static struct vfsmount *sock_mnt __read_mostly; +struct vfsmount *sock_mnt __read_mostly; static struct file_system_type sock_fs_type = { .name = "sockfs", @@ -805,6 +821,7 @@ struct socket *sock; void __user *argp = (void __user *)arg; int pid, err; + unsigned long tc_index; sock = file->private_data; if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) { @@ -869,6 +886,19 @@ mutex_unlock(&dlci_ioctl_mutex); } break; + + case SIOCSET_TC_INDEX: + err = -EFAULT; + if (get_user(tc_index, (unsigned long __user *)argp)) + break; + sock->sk->sk_tc_index = tc_index; + err = 0; + break; + + case SIOCGET_TC_INDEX: + err = put_user(sock->sk->sk_tc_index, (unsigned long __user *)argp); + break; + default: err = sock->ops->ioctl(sock, cmd, arg); @@ -1174,6 +1204,16 @@ int retval; struct socket *sock; + if(!gr_search_socket(family, type, protocol)) { + retval = -EACCES; + goto out; + } + + if (gr_handle_sock_all(family, type, protocol)) { + retval = -EACCES; + goto out; + } + retval = sock_create(family, type, protocol, &sock); if (retval < 0) goto out; @@ -1269,12 +1309,20 @@ { struct socket *sock; char address[MAX_SOCK_ADDR]; + struct sockaddr *sck; int err, fput_needed; sock = sockfd_lookup_light(fd, &err, &fput_needed); if(sock) { err = move_addr_to_kernel(umyaddr, addrlen, address); if (err >= 0) { + sck = (struct sockaddr *)address; + if (!gr_search_bind(sock, (struct sockaddr_in *)sck) || + gr_handle_sock_server(sck)) { + err = -EACCES; + goto error; + } + err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); @@ -1283,6 +1331,7 @@ (struct sockaddr *) address, addrlen); } +error: fput_light(sock->file, fput_needed); } return err; @@ -1306,10 +1355,17 @@ if ((unsigned)backlog > sysctl_somaxconn) backlog = sysctl_somaxconn; + if (gr_handle_sock_server_other(sock) || + !gr_search_listen(sock)) { + err = -EPERM; + goto error; + } + err = security_socket_listen(sock, backlog); if (!err) err = sock->ops->listen(sock, backlog); +error: fput_light(sock->file, fput_needed); } return err; @@ -1346,6 +1402,13 @@ newsock->type = sock->type; newsock->ops = sock->ops; + if (gr_handle_sock_server_other(sock) || + !gr_search_accept(sock)) { + err = -EPERM; + sock_release(newsock); + goto out_put; + } + /* * We don't need try_module_get here, as the listening socket (sock) * has the protocol module (sock->ops->owner) held. @@ -1389,6 +1452,7 @@ err = newfd; security_socket_post_accept(sock, newsock); + gr_attach_curr_ip(newsock->sk); out_put: fput_light(sock->file, fput_needed); @@ -1417,6 +1481,7 @@ { struct socket *sock; char address[MAX_SOCK_ADDR]; + struct sockaddr *sck; int err, fput_needed; sock = sockfd_lookup_light(fd, &err, &fput_needed); @@ -1426,6 +1491,13 @@ if (err < 0) goto out_put; + sck = (struct sockaddr *)address; + if (!gr_search_connect(sock, (struct sockaddr_in *)sck) || + gr_handle_sock_client(sck)) { + err = -EACCES; + goto out_put; + } + err = security_socket_connect(sock, (struct sockaddr *)address, addrlen); if (err) @@ -1699,6 +1771,7 @@ err = sock->ops->shutdown(sock, how); fput_light(sock->file, fput_needed); } + return err; }