diff options
| author | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-09 01:01:59 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@home.transmeta.com> | 2003-02-09 01:01:59 -0800 |
| commit | ad370e28deac7065c3fb511ffc7de8043f2be5f7 (patch) | |
| tree | fa2b80a89c18777ac52f427f50116ea840bdc6d8 | |
| parent | d8a1413de9480f8cdc856daa05abe5c15482c24b (diff) | |
| parent | fd7c713fd43e878d85a431bdf25ac573efc17b6d (diff) | |
Merge bk://kernel.bkbits.net/davem/net-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
| -rw-r--r-- | MAINTAINERS | 4 | ||||
| -rw-r--r-- | include/linux/security.h | 429 | ||||
| -rw-r--r-- | include/net/sock.h | 97 | ||||
| -rw-r--r-- | net/bridge/br.c | 4 | ||||
| -rw-r--r-- | net/bridge/br_if.c | 4 | ||||
| -rw-r--r-- | net/core/rtnetlink.c | 3 | ||||
| -rw-r--r-- | net/decnet/dn_nsp_in.c | 29 | ||||
| -rw-r--r-- | net/ipv4/netfilter/Kconfig | 8 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_nat_helper.c | 1 | ||||
| -rw-r--r-- | net/ipv4/netfilter/ip_queue.c | 3 | ||||
| -rw-r--r-- | net/ipv4/route.c | 16 | ||||
| -rw-r--r-- | net/ipv4/tcp_ipv4.c | 9 | ||||
| -rw-r--r-- | net/ipv4/xfrm_user.c | 3 | ||||
| -rw-r--r-- | net/ipv6/netfilter/ip6_queue.c | 6 | ||||
| -rw-r--r-- | net/ipv6/route.c | 26 | ||||
| -rw-r--r-- | net/ipv6/tcp_ipv6.c | 15 | ||||
| -rw-r--r-- | net/netlink/af_netlink.c | 8 | ||||
| -rw-r--r-- | net/sctp/input.c | 4 | ||||
| -rw-r--r-- | net/socket.c | 72 | ||||
| -rw-r--r-- | net/unix/af_unix.c | 16 | ||||
| -rw-r--r-- | security/Kconfig | 9 | ||||
| -rw-r--r-- | security/capability.c | 2 | ||||
| -rw-r--r-- | security/dummy.c | 135 |
23 files changed, 800 insertions, 103 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index 672ddfd9bd42..a3f537d9fb93 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -614,11 +614,9 @@ L: linux-net@vger.kernel.org S: Maintained ETHERNET BRIDGE -P: Lennert Buytenhek -M: buytenh@gnu.org L: bridge@math.leidenuniv.nl W: http://bridge.sourceforge.net/ -S: Maintained +S: Unmaintained ETHERTEAM 16I DRIVER P: Mika Kuoppala diff --git a/include/linux/security.h b/include/linux/security.h index a7d728493d2c..d2873ec35117 100644 --- a/include/linux/security.h +++ b/include/linux/security.h @@ -31,7 +31,8 @@ #include <linux/shm.h> #include <linux/msg.h> #include <linux/sched.h> - +#include <linux/skbuff.h> +#include <linux/netlink.h> /* * These functions are in security/capability.c and are used @@ -48,6 +49,20 @@ extern int cap_task_post_setuid (uid_t old_ruid, uid_t old_euid, uid_t old_suid, extern void cap_task_kmod_set_label (void); extern void cap_task_reparent_to_init (struct task_struct *p); +static inline int cap_netlink_send (struct sk_buff *skb) +{ + NETLINK_CB (skb).eff_cap = current->cap_effective; + return 0; +} + +static inline int cap_netlink_recv (struct sk_buff *skb) +{ + if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + return 0; +} + + /* * Values used in the task_security_ops calls */ @@ -63,16 +78,13 @@ extern void cap_task_reparent_to_init (struct task_struct *p); /* setfsuid or setfsgid, id0 == fsuid or fsgid */ #define LSM_SETID_FS 8 - -#ifdef CONFIG_SECURITY - /* forward declares to avoid warnings */ -struct sk_buff; -struct net_device; struct nfsctl_arg; struct sched_param; struct swap_info_struct; +#ifdef CONFIG_SECURITY + /** * struct security_operations - main security structure * @@ -586,6 +598,149 @@ struct swap_info_struct; * is being reparented to the init task. * @p contains the task_struct for the kernel thread. * + * Security hooks for Netlink messaging. + * + * @netlink_send: + * Save security information for a netlink message so that permission + * checking can be performed when the message is processed. The security + * information can be saved using the eff_cap field of the + * netlink_skb_parms structure. + * @skb contains the sk_buff structure for the netlink message. + * Return 0 if the information was successfully saved. + * @netlink_recv: + * Check permission before processing the received netlink message in + * @skb. + * @skb contains the sk_buff structure for the netlink message. + * Return 0 if permission is granted. + * + * Security hooks for Unix domain networking. + * + * @unix_stream_connect: + * Check permissions before establishing a Unix domain stream connection + * between @sock and @other. + * @sock contains the socket structure. + * @other contains the peer socket structure. + * Return 0 if permission is granted. + * @unix_may_send: + * Check permissions before connecting or sending datagrams from @sock to + * @other. + * @sock contains the socket structure. + * @sock contains the peer socket structure. + * Return 0 if permission is granted. + * + * The @unix_stream_connect and @unix_may_send hooks were necessary because + * Linux provides an alternative to the conventional file name space for Unix + * domain sockets. Whereas binding and connecting to sockets in the file name + * space is mediated by the typical file permissions (and caught by the mknod + * and permission hooks in inode_security_ops), binding and connecting to + * sockets in the abstract name space is completely unmediated. Sufficient + * control of Unix domain sockets in the abstract name space isn't possible + * using only the socket layer hooks, since we need to know the actual target + * socket, which is not looked up until we are inside the af_unix code. + * + * Security hooks for socket operations. + * + * @socket_create: + * Check permissions prior to creating a new socket. + * @family contains the requested protocol family. + * @type contains the requested communications type. + * @protocol contains the requested protocol. + * Return 0 if permission is granted. + * @socket_post_create: + * This hook allows a module to update or allocate a per-socket security + * structure. Note that the security field was not added directly to the + * socket structure, but rather, the socket security information is stored + * in the associated inode. Typically, the inode alloc_security hook will + * allocate and and attach security information to + * sock->inode->i_security. This hook may be used to update the + * sock->inode->i_security field with additional information that wasn't + * available when the inode was allocated. + * @sock contains the newly created socket structure. + * @family contains the requested protocol family. + * @type contains the requested communications type. + * @protocol contains the requested protocol. + * @socket_bind: + * Check permission before socket protocol layer bind operation is + * performed and the socket @sock is bound to the address specified in the + * @address parameter. + * @sock contains the socket structure. + * @address contains the address to bind to. + * @addrlen contains the length of address. + * Return 0 if permission is granted. + * @socket_connect: + * Check permission before socket protocol layer connect operation + * attempts to connect socket @sock to a remote address, @address. + * @sock contains the socket structure. + * @address contains the address of remote endpoint. + * @addrlen contains the length of address. + * Return 0 if permission is granted. + * @socket_listen: + * Check permission before socket protocol layer listen operation. + * @sock contains the socket structure. + * @backlog contains the maximum length for the pending connection queue. + * Return 0 if permission is granted. + * @socket_accept: + * Check permission before accepting a new connection. Note that the new + * socket, @newsock, has been created and some information copied to it, + * but the accept operation has not actually been performed. + * @sock contains the listening socket structure. + * @newsock contains the newly created server socket for connection. + * Return 0 if permission is granted. + * @socket_post_accept: + * This hook allows a security module to copy security + * information into the newly created socket's inode. + * @sock contains the listening socket structure. + * @newsock contains the newly created server socket for connection. + * @socket_sendmsg: + * Check permission before transmitting a message to another socket. + * @sock contains the socket structure. + * @msg contains the message to be transmitted. + * @size contains the size of message. + * Return 0 if permission is granted. + * @socket_recvmsg: + * Check permission before receiving a message from a socket. + * @sock contains the socket structure. + * @msg contains the message structure. + * @size contains the size of message structure. + * @flags contains the operational flags. + * Return 0 if permission is granted. + * @socket_getsockname: + * Check permission before the local address (name) of the socket object + * @sock is retrieved. + * @sock contains the socket structure. + * Return 0 if permission is granted. + * @socket_getpeername: + * Check permission before the remote address (name) of a socket object + * @sock is retrieved. + * @sock contains the socket structure. + * Return 0 if permission is granted. + * @socket_getsockopt: + * Check permissions before retrieving the options associated with socket + * @sock. + * @sock contains the socket structure. + * @level contains the protocol level to retrieve option from. + * @optname contains the name of option to retrieve. + * Return 0 if permission is granted. + * @socket_setsockopt: + * Check permissions before setting the options associated with socket + * @sock. + * @sock contains the socket structure. + * @level contains the protocol level to set options for. + * @optname contains the name of the option to set. + * Return 0 if permission is granted. + * @socket_shutdown: + * Checks permission before all or part of a connection on the socket + * @sock is shut down. + * @sock contains the socket structure. + * @how contains the flag indicating how future sends and receives are handled. + * Return 0 if permission is granted. + * @socket_sock_rcv_skb: + * Check permissions on incoming network packets. This hook is distinct + * from Netfilter's IP input hooks since it is the first time that the + * incoming sk_buff @skb has been associated with a particular socket, @sk. + * @sk contains the sock (not socket) associated with the incoming sk_buff. + * @skb contains the incoming network data. + * * Security hooks affecting all System V IPC operations. * * @ipc_permission: @@ -947,11 +1102,42 @@ struct security_operations { int (*sem_semop) (struct sem_array * sma, struct sembuf * sops, unsigned nsops, int alter); + int (*netlink_send) (struct sk_buff * skb); + int (*netlink_recv) (struct sk_buff * skb); + /* allow module stacking */ int (*register_security) (const char *name, struct security_operations *ops); int (*unregister_security) (const char *name, struct security_operations *ops); + +#ifdef CONFIG_SECURITY_NETWORK + int (*unix_stream_connect) (struct socket * sock, + struct socket * other, struct sock * newsk); + int (*unix_may_send) (struct socket * sock, struct socket * other); + + int (*socket_create) (int family, int type, int protocol); + void (*socket_post_create) (struct socket * sock, int family, + int type, int protocol); + int (*socket_bind) (struct socket * sock, + struct sockaddr * address, int addrlen); + int (*socket_connect) (struct socket * sock, + struct sockaddr * address, int addrlen); + int (*socket_listen) (struct socket * sock, int backlog); + int (*socket_accept) (struct socket * sock, struct socket * newsock); + void (*socket_post_accept) (struct socket * sock, + struct socket * newsock); + int (*socket_sendmsg) (struct socket * sock, + struct msghdr * msg, int size); + int (*socket_recvmsg) (struct socket * sock, + struct msghdr * msg, int size, int flags); + int (*socket_getsockname) (struct socket * sock); + int (*socket_getpeername) (struct socket * sock); + int (*socket_getsockopt) (struct socket * sock, int level, int optname); + int (*socket_setsockopt) (struct socket * sock, int level, int optname); + int (*socket_shutdown) (struct socket * sock, int how); + int (*socket_sock_rcv_skb) (struct sock * sk, struct sk_buff * skb); +#endif /* CONFIG_SECURITY_NETWORK */ }; /* global variables */ @@ -1543,6 +1729,16 @@ static inline int security_sem_semop (struct sem_array * sma, return security_ops->sem_semop(sma, sops, nsops, alter); } +static inline int security_netlink_send(struct sk_buff * skb) +{ + return security_ops->netlink_send(skb); +} + +static inline int security_netlink_recv(struct sk_buff * skb) +{ + return security_ops->netlink_recv(skb); +} + /* prototypes */ extern int security_scaffolding_startup (void); extern int register_security (struct security_operations *ops); @@ -2104,7 +2300,228 @@ static inline int security_sem_semop (struct sem_array * sma, return 0; } +/* + * The netlink capability defaults need to be used inline by default + * (rather than hooking into the capability module) to reduce overhead + * in the networking code. + */ +static inline int security_netlink_send (struct sk_buff *skb) +{ + return cap_netlink_send (skb); +} + +static inline int security_netlink_recv (struct sk_buff *skb) +{ + return cap_netlink_recv (skb); +} + #endif /* CONFIG_SECURITY */ +#ifdef CONFIG_SECURITY_NETWORK +static inline int security_unix_stream_connect(struct socket * sock, + struct socket * other, + struct sock * newsk) +{ + return security_ops->unix_stream_connect(sock, other, newsk); +} + + +static inline int security_unix_may_send(struct socket * sock, + struct socket * other) +{ + return security_ops->unix_may_send(sock, other); +} + +static inline int security_socket_create (int family, int type, int protocol) +{ + return security_ops->socket_create(family, type, protocol); +} + +static inline void security_socket_post_create(struct socket * sock, + int family, + int type, + int protocol) +{ + security_ops->socket_post_create(sock, family, type, protocol); +} + +static inline int security_socket_bind(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return security_ops->socket_bind(sock, address, addrlen); +} + +static inline int security_socket_connect(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return security_ops->socket_connect(sock, address, addrlen); +} + +static inline int security_socket_listen(struct socket * sock, int backlog) +{ + return security_ops->socket_listen(sock, backlog); +} + +static inline int security_socket_accept(struct socket * sock, + struct socket * newsock) +{ + return security_ops->socket_accept(sock, newsock); +} + +static inline void security_socket_post_accept(struct socket * sock, + struct socket * newsock) +{ + security_ops->socket_post_accept(sock, newsock); +} + +static inline int security_socket_sendmsg(struct socket * sock, + struct msghdr * msg, int size) +{ + return security_ops->socket_sendmsg(sock, msg, size); +} + +static inline int security_socket_recvmsg(struct socket * sock, + struct msghdr * msg, int size, + int flags) +{ + return security_ops->socket_recvmsg(sock, msg, size, flags); +} + +static inline int security_socket_getsockname(struct socket * sock) +{ + return security_ops->socket_getsockname(sock); +} + +static inline int security_socket_getpeername(struct socket * sock) +{ + return security_ops->socket_getpeername(sock); +} + +static inline int security_socket_getsockopt(struct socket * sock, + int level, int optname) +{ + return security_ops->socket_getsockopt(sock, level, optname); +} + +static inline int security_socket_setsockopt(struct socket * sock, + int level, int optname) +{ + return security_ops->socket_setsockopt(sock, level, optname); +} + +static inline int security_socket_shutdown(struct socket * sock, int how) +{ + return security_ops->socket_shutdown(sock, how); +} + +static inline int security_sock_rcv_skb (struct sock * sk, + struct sk_buff * skb) +{ + return security_ops->socket_sock_rcv_skb (sk, skb); +} +#else /* CONFIG_SECURITY_NETWORK */ +static inline int security_unix_stream_connect(struct socket * sock, + struct socket * other, + struct sock * newsk) +{ + return 0; +} + +static inline int security_unix_may_send(struct socket * sock, + struct socket * other) +{ + return 0; +} + +static inline int security_socket_create (int family, int type, int protocol) +{ + return 0; +} + +static inline void security_socket_post_create(struct socket * sock, + int family, + int type, + int protocol) +{ +} + +static inline int security_socket_bind(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return 0; +} + +static inline int security_socket_connect(struct socket * sock, + struct sockaddr * address, + int addrlen) +{ + return 0; +} + +static inline int security_socket_listen(struct socket * sock, int backlog) +{ + return 0; +} + +static inline int security_socket_accept(struct socket * sock, + struct socket * newsock) +{ + return 0; +} + +static inline void security_socket_post_accept(struct socket * sock, + struct socket * newsock) +{ +} + +static inline int security_socket_sendmsg(struct socket * sock, + struct msghdr * msg, int size) +{ + return 0; +} + +static inline int security_socket_recvmsg(struct socket * sock, + struct msghdr * msg, int size, + int flags) +{ + return 0; +} + +static inline int security_socket_getsockname(struct socket * sock) +{ + return 0; +} + +static inline int security_socket_getpeername(struct socket * sock) +{ + return 0; +} + +static inline int security_socket_getsockopt(struct socket * sock, + int level, int optname) +{ + return 0; +} + +static inline int security_socket_setsockopt(struct socket * sock, + int level, int optname) +{ + return 0; +} + +static inline int security_socket_shutdown(struct socket * sock, int how) +{ + return 0; +} +static inline int security_sock_rcv_skb (struct sock * sk, + struct sk_buff * skb) +{ + return 0; +} +#endif /* CONFIG_SECURITY_NETWORK */ + #endif /* ! __LINUX_SECURITY_H */ diff --git a/include/net/sock.h b/include/net/sock.h index 46bf5cae69f2..9d15fc3c3ec2 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -44,6 +44,7 @@ #include <linux/netdevice.h> #include <linux/skbuff.h> /* struct sk_buff */ +#include <linux/security.h> #ifdef CONFIG_FILTER #include <linux/filter.h> @@ -458,28 +459,45 @@ extern void sock_init_data(struct socket *sock, struct sock *sk); #ifdef CONFIG_FILTER /** - * sk_filter - run a packet through a socket filter + * __sk_filter - run a packet through a socket filter + * @sk: sock associated with &sk_buff * @skb: buffer to filter - * @filter: filter to apply + * @needlock: set to 1 if the sock is not locked by caller. * * Run the filter code and then cut skb->data to correct size returned by * sk_run_filter. If pkt_len is 0 we toss packet. If skb->len is smaller * than pkt_len we keep whole skb->data. This is the socket level * wrapper to sk_run_filter. It returns 0 if the packet should - * be accepted or 1 if the packet should be tossed. + * be accepted or -EPERM if the packet should be tossed. + * + * This function should not be called directly, use sk_filter instead + * to ensure that the LSM security check is also performed. */ - -static inline int sk_filter(struct sk_buff *skb, struct sk_filter *filter) -{ - int pkt_len; - pkt_len = sk_run_filter(skb, filter->insns, filter->len); - if(!pkt_len) - return 1; /* Toss Packet */ - else - skb_trim(skb, pkt_len); +static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) +{ + int err = 0; - return 0; + if (sk->filter) { + struct sk_filter *filter; + + if (needlock) + bh_lock_sock(sk); + + filter = sk->filter; + if (filter) { + int pkt_len = sk_run_filter(skb, filter->insns, + filter->len); + if (!pkt_len) + err = -EPERM; + else + skb_trim(skb, pkt_len); + } + + if (needlock) + bh_unlock_sock(sk); + } + return err; } /** @@ -506,8 +524,26 @@ static inline void sk_filter_charge(struct sock *sk, struct sk_filter *fp) atomic_add(sk_filter_len(fp), &sk->omem_alloc); } +#else + +static inline int __sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) +{ + return 0; +} + #endif /* CONFIG_FILTER */ +static inline int sk_filter(struct sock *sk, struct sk_buff *skb, int needlock) +{ + int err; + + err = security_sock_rcv_skb(sk, skb); + if (err) + return err; + + return __sk_filter(sk, skb, needlock); +} + /* * Socket reference counting postulates. * @@ -712,36 +748,31 @@ static inline void skb_set_owner_r(struct sk_buff *skb, struct sock *sk) static inline int sock_queue_rcv_skb(struct sock *sk, struct sk_buff *skb) { + int err = 0; + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ - if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) - return -ENOMEM; - -#ifdef CONFIG_FILTER - if (sk->filter) { - int err = 0; - struct sk_filter *filter; - - /* It would be deadlock, if sock_queue_rcv_skb is used - with socket lock! We assume that users of this - function are lock free. - */ - bh_lock_sock(sk); - if ((filter = sk->filter) != NULL && sk_filter(skb, filter)) - err = -EPERM; - bh_unlock_sock(sk); - if (err) - return err; /* Toss packet */ + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) { + err = -ENOMEM; + goto out; } -#endif /* CONFIG_FILTER */ + + /* It would be deadlock, if sock_queue_rcv_skb is used + with socket lock! We assume that users of this + function are lock free. + */ + err = sk_filter(sk, skb, 1); + if (err) + goto out; skb->dev = NULL; skb_set_owner_r(skb, sk); skb_queue_tail(&sk->receive_queue, skb); if (!sk->dead) sk->data_ready(sk,skb->len); - return 0; +out: + return err; } static inline int sock_queue_err_skb(struct sock *sk, struct sk_buff *skb) diff --git a/net/bridge/br.c b/net/bridge/br.c index fe7f2325331a..23b44c9c9b82 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -33,12 +33,12 @@ int (*br_should_route_hook) (struct sk_buff **pskb) = NULL; void br_dec_use_count() { - MOD_DEC_USE_COUNT; + module_put(THIS_MODULE); } void br_inc_use_count() { - MOD_INC_USE_COUNT; + try_module_get(THIS_MODULE); } static int __init br_init(void) diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index d3b0f4a01924..39427429bf56 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c @@ -155,8 +155,6 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, struct net_device p->path_cost = br_initial_port_cost(dev); p->priority = 0x80; - dev->br_port = p; - for (i=1;i<255;i++) if (br_get_port(br, i) == NULL) break; @@ -166,6 +164,8 @@ static struct net_bridge_port *new_nbp(struct net_bridge *br, struct net_device return NULL; } + dev->br_port = p; + p->port_no = i; br_init_port(p); p->state = BR_STATE_DISABLED; diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index eac888a5e82e..2e2f9c1e9aee 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c @@ -34,6 +34,7 @@ #include <linux/capability.h> #include <linux/skbuff.h> #include <linux/init.h> +#include <linux/security.h> #include <asm/uaccess.h> #include <asm/system.h> @@ -363,7 +364,7 @@ rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *errp) sz_idx = type>>2; kind = type&3; - if (kind != 2 && !cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { + if (kind != 2 && security_netlink_recv(skb)) { *errp = -EPERM; return -1; } diff --git a/net/decnet/dn_nsp_in.c b/net/decnet/dn_nsp_in.c index 611f3952689d..5a5e3795d00d 100644 --- a/net/decnet/dn_nsp_in.c +++ b/net/decnet/dn_nsp_in.c @@ -566,26 +566,19 @@ out: */ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig, struct sk_buff_head *queue) { -#ifdef CONFIG_FILTER - struct sk_filter *filter; -#endif - + int err; + /* Cast skb->rcvbuf to unsigned... It's pointless, but reduces number of warnings when compiling with -W --ANK */ - if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf -) - return -ENOMEM; - -#ifdef CONFIG_FILTER - if (sk->filter) { - int err = 0; - if ((filter = sk->filter) != NULL && sk_filter(skb, sk->filter)) - err = -EPERM; /* Toss packet */ - if (err) - return err; + if (atomic_read(&sk->rmem_alloc) + skb->truesize >= (unsigned)sk->rcvbuf) { + err = -ENOMEM; + goto out; } -#endif /* CONFIG_FILTER */ + + err = sk_filter(sk, skb, 0); + if (err) + goto out; skb_set_owner_r(skb, sk); skb_queue_tail(queue, skb); @@ -603,8 +596,8 @@ static __inline__ int dn_queue_skb(struct sock *sk, struct sk_buff *skb, int sig (sig == SIGURG) ? POLL_PRI : POLL_IN); } read_unlock(&sk->callback_lock); - - return 0; +out: + return err; } static void dn_nsp_otherdata(struct sock *sk, struct sk_buff *skb) diff --git a/net/ipv4/netfilter/Kconfig b/net/ipv4/netfilter/Kconfig index 1cf6b26a3562..ff7687cc6f94 100644 --- a/net/ipv4/netfilter/Kconfig +++ b/net/ipv4/netfilter/Kconfig @@ -148,6 +148,14 @@ config IP_NF_MATCH_ECN config IP_NF_MATCH_DSCP tristate "DSCP match support" depends on IP_NF_IPTABLES + help + This option adds a `DSCP' match, which allows you to match against + the IPv4 header DSCP field (DSCP codepoint). + + The DSCP codepoint can have any value between 0x0 and 0x4f. + + If you want to compile it as a module, say M here and read + Documentation/modules.txt. If unsure, say `N'. config IP_NF_MATCH_AH_ESP tristate "AH/ESP match support" diff --git a/net/ipv4/netfilter/ip_nat_helper.c b/net/ipv4/netfilter/ip_nat_helper.c index 6f53c4430469..2a41d7d7d1f4 100644 --- a/net/ipv4/netfilter/ip_nat_helper.c +++ b/net/ipv4/netfilter/ip_nat_helper.c @@ -84,7 +84,6 @@ ip_nat_resize_packet(struct sk_buff **skb, iph = (*skb)->nh.iph; if (iph->protocol == IPPROTO_TCP) { struct tcphdr *tcph = (void *)iph + iph->ihl*4; - void *data = (void *)tcph + tcph->doff*4; DEBUGP("ip_nat_resize_packet: Seq_offset before: "); DUMP_OFFSET(this_way); diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 080c3d1efdd4..d832d2d98d3b 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -26,6 +26,7 @@ #include <linux/brlock.h> #include <linux/sysctl.h> #include <linux/proc_fs.h> +#include <linux/security.h> #include <net/sock.h> #include <net/route.h> @@ -496,7 +497,7 @@ ipq_rcv_skb(struct sk_buff *skb) if (type <= IPQM_BASE) return; - if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) + if (security_netlink_recv(skb)) RCV_SKB_FAIL(-EPERM); write_lock_bh(&queue_lock); diff --git a/net/ipv4/route.c b/net/ipv4/route.c index e5b18b00dd20..74422ccb7bf9 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c @@ -2288,7 +2288,7 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) struct net_device *dev = __dev_get_by_index(iif); err = -ENODEV; if (!dev) - goto out; + goto out_free; skb->protocol = htons(ETH_P_IP); skb->dev = dev; local_bh_disable(); @@ -2307,10 +2307,8 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) fl.oif = oif; err = ip_route_output_key(&rt, &fl); } - if (err) { - kfree_skb(skb); - goto out; - } + if (err) + goto out_free; skb->dst = &rt->u.dst; if (rtm->rtm_flags & RTM_F_NOTIFY) @@ -2321,16 +2319,20 @@ int inet_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) err = rt_fill_info(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq, RTM_NEWROUTE, 0); if (!err) - goto out; + goto out_free; if (err < 0) { err = -EMSGSIZE; - goto out; + goto out_free; } err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); if (err > 0) err = 0; out: return err; + +out_free: + kfree_skb(skb); + goto out; } int ip_rt_dump(struct sk_buff *skb, struct netlink_callback *cb) diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index 116a748cd875..74df93910166 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c @@ -1697,12 +1697,6 @@ static int tcp_v4_checksum_init(struct sk_buff *skb) */ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) { -#ifdef CONFIG_FILTER - struct sk_filter *filter = sk->filter; - if (filter && sk_filter(skb, filter)) - goto discard; -#endif /* CONFIG_FILTER */ - if (sk->state == TCP_ESTABLISHED) { /* Fast path */ TCP_CHECK_TIMER(sk); if (tcp_rcv_established(sk, skb, skb->h.th, skb->len)) @@ -1805,6 +1799,9 @@ process: if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_and_relse; + if (sk_filter(sk, skb, 0)) + goto discard_and_relse; + skb->dev = NULL; bh_lock_sock(sk); diff --git a/net/ipv4/xfrm_user.c b/net/ipv4/xfrm_user.c index 72a667a2f1be..05738783a11d 100644 --- a/net/ipv4/xfrm_user.c +++ b/net/ipv4/xfrm_user.c @@ -16,6 +16,7 @@ #include <linux/pfkeyv2.h> #include <linux/ipsec.h> #include <linux/init.h> +#include <linux/security.h> #include <net/sock.h> #include <net/xfrm.h> @@ -774,7 +775,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, int *err link = &xfrm_dispatch[type]; /* All operations require privileges, even GET */ - if (!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) { + if (security_netlink_recv(skb)) { *errp = -EPERM; return -1; } diff --git a/net/ipv6/netfilter/ip6_queue.c b/net/ipv6/netfilter/ip6_queue.c index 5e02b47050e9..aa87c34de72a 100644 --- a/net/ipv6/netfilter/ip6_queue.c +++ b/net/ipv6/netfilter/ip6_queue.c @@ -538,10 +538,10 @@ ipq_rcv_skb(struct sk_buff *skb) if (type <= IPQM_BASE) return; - - if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) - RCV_SKB_FAIL(-EPERM); + if (security_netlink_recv(skb)) + RCV_SKB_FAIL(-EPERM); + write_lock_bh(&queue_lock); if (peer_pid) { diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 1ff9ddc6ccdd..2fee2a47d689 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c @@ -1548,14 +1548,14 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) { struct rtattr **rta = arg; int iif = 0; - int err; + int err = -ENOBUFS; struct sk_buff *skb; struct flowi fl; struct rt6_info *rt; skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL); if (skb == NULL) - return -ENOBUFS; + goto out; /* Reserve room for dummy headers, this skb can pass through good chunk of routing engine. @@ -1579,8 +1579,10 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) if (iif) { struct net_device *dev; dev = __dev_get_by_index(iif); - if (!dev) - return -ENODEV; + if (!dev) { + err = -ENODEV; + goto out_free; + } } fl.oif = 0; @@ -1597,13 +1599,19 @@ int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr* nlh, void *arg) fl.nl_u.ip6_u.saddr, iif, RTM_NEWROUTE, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq); - if (err < 0) - return -EMSGSIZE; + if (err < 0) { + err = -EMSGSIZE; + goto out_free; + } err = netlink_unicast(rtnl, skb, NETLINK_CB(in_skb).pid, MSG_DONTWAIT); - if (err < 0) - return err; - return 0; + if (err > 0) + err = 0; +out: + return err; +out_free: + kfree_skb(skb); + goto out; } void inet6_rt_notify(int event, struct rt6_info *rt) diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 18424ac3fe07..437e81cebb7f 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c @@ -1470,9 +1470,6 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) { struct ipv6_pinfo *np = inet6_sk(sk); struct tcp_opt *tp; -#ifdef CONFIG_FILTER - struct sk_filter *filter; -#endif struct sk_buff *opt_skb = NULL; /* Imagine: socket is IPv6. IPv4 packet arrives, @@ -1486,11 +1483,8 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) if (skb->protocol == htons(ETH_P_IP)) return tcp_v4_do_rcv(sk, skb); -#ifdef CONFIG_FILTER - filter = sk->filter; - if (filter && sk_filter(skb, filter)) + if (sk_filter(sk, skb, 0)) goto discard; -#endif /* CONFIG_FILTER */ /* * socket locking is here for SMP purposes as backlog rcv @@ -1641,6 +1635,9 @@ process: if(sk->state == TCP_TIME_WAIT) goto do_time_wait; + if (sk_filter(sk, skb, 0)) + goto discard_and_relse; + skb->dev = NULL; bh_lock_sock(sk); @@ -1672,6 +1669,10 @@ discard_it: kfree_skb(skb); return 0; +discard_and_relse: + sock_put(sk); + goto discard_it; + do_time_wait: if (skb->len < (th->doff<<2) || tcp_checksum_complete(skb)) { TCP_INC_STATS_BH(TcpInErrs); diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 499a8c9a9c99..9249dddc9001 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c @@ -42,6 +42,7 @@ #include <linux/proc_fs.h> #include <linux/smp_lock.h> #include <linux/notifier.h> +#include <linux/security.h> #include <net/sock.h> #include <net/scm.h> @@ -636,7 +637,12 @@ static int netlink_sendmsg(struct kiocb *iocb, struct socket *sock, check them, when this message will be delivered to corresponding kernel module. --ANK (980802) */ - NETLINK_CB(skb).eff_cap = current->cap_effective; + + err = security_netlink_send(skb); + if (err) { + kfree_skb(skb); + goto out; + } err = -EFAULT; if (memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len)) { diff --git a/net/sctp/input.c b/net/sctp/input.c index d6e64da75733..83e2b5da8f70 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -159,6 +159,10 @@ int sctp_rcv(struct sk_buff *skb) if (!xfrm_policy_check(sk, XFRM_POLICY_IN, skb)) goto discard_release; + ret = sk_filter(sk, skb, 1); + if (ret) + goto discard_release; + /* Create an SCTP packet structure. */ chunk = sctp_chunkify(skb, asoc, sk); if (!chunk) { diff --git a/net/socket.c b/net/socket.c index b17a1944444a..5e7636d1408a 100644 --- a/net/socket.c +++ b/net/socket.c @@ -77,6 +77,7 @@ #include <linux/highmem.h> #include <linux/divert.h> #include <linux/mount.h> +#include <linux/security.h> #if defined(CONFIG_KMOD) && defined(CONFIG_NET) #include <linux/kmod.h> @@ -527,6 +528,10 @@ static int __sock_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr si->msg = msg; si->size = size; + err = security_socket_sendmsg(sock, msg, size); + if (err) + return err; + err = scm_send(sock, msg, si->scm); if (err >= 0) { err = sock->ops->sendmsg(iocb, sock, msg, size, si->scm); @@ -551,6 +556,7 @@ int sock_sendmsg(struct socket *sock, struct msghdr *msg, int size) int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, int size, int flags) { + int err; struct sock_iocb *si = kiocb_to_siocb(iocb); si->sock = sock; @@ -560,6 +566,10 @@ int __sock_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, si->size = size; si->flags = flags; + err = security_socket_recvmsg(sock, msg, size, flags); + if (err) + return err; + memset(si->scm, 0, sizeof(*si->scm)); size = sock->ops->recvmsg(iocb, sock, msg, size, flags, si->scm); @@ -963,6 +973,7 @@ int sock_wake_async(struct socket *sock, int how, int band) int sock_create(int family, int type, int protocol, struct socket **res) { int i; + int err; struct socket *sock; /* @@ -986,6 +997,10 @@ int sock_create(int family, int type, int protocol, struct socket **res) } family = PF_PACKET; } + + err = security_socket_create(family, type, protocol); + if (err) + return err; #if defined(CONFIG_KMOD) && defined(CONFIG_NET) /* Attempt to load a protocol module if the find failed. @@ -1031,6 +1046,7 @@ int sock_create(int family, int type, int protocol, struct socket **res) } *res = sock; + security_socket_post_create(sock, family, type, protocol); out: net_family_read_unlock(); @@ -1141,8 +1157,14 @@ asmlinkage long sys_bind(int fd, struct sockaddr *umyaddr, int addrlen) if((sock = sockfd_lookup(fd,&err))!=NULL) { - if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) + if((err=move_addr_to_kernel(umyaddr,addrlen,address))>=0) { + err = security_socket_bind(sock, (struct sockaddr *)address, addrlen); + if (err) { + sockfd_put(sock); + return err; + } err = sock->ops->bind(sock, (struct sockaddr *)address, addrlen); + } sockfd_put(sock); } return err; @@ -1163,6 +1185,13 @@ asmlinkage long sys_listen(int fd, int backlog) if ((sock = sockfd_lookup(fd, &err)) != NULL) { if ((unsigned) backlog > SOMAXCONN) backlog = SOMAXCONN; + + err = security_socket_listen(sock, backlog); + if (err) { + sockfd_put(sock); + return err; + } + err=sock->ops->listen(sock, backlog); sockfd_put(sock); } @@ -1199,6 +1228,10 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a newsock->type = sock->type; newsock->ops = sock->ops; + err = security_socket_accept(sock, newsock); + if (err) + goto out_release; + err = sock->ops->accept(sock, newsock, sock->file->f_flags); if (err < 0) goto out_release; @@ -1218,6 +1251,8 @@ asmlinkage long sys_accept(int fd, struct sockaddr *upeer_sockaddr, int *upeer_a if ((err = sock_map_fd(newsock)) < 0) goto out_release; + security_socket_post_accept(sock, newsock); + out_put: sockfd_put(sock); out: @@ -1253,6 +1288,11 @@ asmlinkage long sys_connect(int fd, struct sockaddr *uservaddr, int addrlen) err = move_addr_to_kernel(uservaddr, addrlen, address); if (err < 0) goto out_put; + + err = security_socket_connect(sock, (struct sockaddr *)address, addrlen); + if (err) + goto out_put; + err = sock->ops->connect(sock, (struct sockaddr *) address, addrlen, sock->file->f_flags); out_put: @@ -1275,6 +1315,11 @@ asmlinkage long sys_getsockname(int fd, struct sockaddr *usockaddr, int *usockad sock = sockfd_lookup(fd, &err); if (!sock) goto out; + + err = security_socket_getsockname(sock); + if (err) + goto out_put; + err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 0); if (err) goto out_put; @@ -1299,6 +1344,12 @@ asmlinkage long sys_getpeername(int fd, struct sockaddr *usockaddr, int *usockad if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_getpeername(sock); + if (err) { + sockfd_put(sock); + return err; + } + err = sock->ops->getname(sock, (struct sockaddr *)address, &len, 1); if (!err) err=move_addr_to_user(address,len, usockaddr, usockaddr_len); @@ -1427,6 +1478,12 @@ asmlinkage long sys_setsockopt(int fd, int level, int optname, char *optval, int if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_setsockopt(sock,level,optname); + if (err) { + sockfd_put(sock); + return err; + } + if (level == SOL_SOCKET) err=sock_setsockopt(sock,level,optname,optval,optlen); else @@ -1448,6 +1505,13 @@ asmlinkage long sys_getsockopt(int fd, int level, int optname, char *optval, int if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_getsockopt(sock, level, + optname); + if (err) { + sockfd_put(sock); + return err; + } + if (level == SOL_SOCKET) err=sock_getsockopt(sock,level,optname,optval,optlen); else @@ -1469,6 +1533,12 @@ asmlinkage long sys_shutdown(int fd, int how) if ((sock = sockfd_lookup(fd, &err))!=NULL) { + err = security_socket_shutdown(sock, how); + if (err) { + sockfd_put(sock); + return err; + } + err=sock->ops->shutdown(sock, how); sockfd_put(sock); } diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 42e341e9bb2d..c84795fd80a2 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -115,6 +115,7 @@ #include <linux/rtnetlink.h> #include <linux/mount.h> #include <net/checksum.h> +#include <linux/security.h> int sysctl_unix_max_dgram_qlen = 10; @@ -816,6 +817,11 @@ static int unix_dgram_connect(struct socket *sock, struct sockaddr *addr, err = -EPERM; if (!unix_may_send(sk, other)) goto out_unlock; + + err = security_unix_may_send(sk->socket, other->socket); + if (err) + goto out_unlock; + } else { /* * 1003.1g breaking connected state with AF_UNSPEC @@ -981,6 +987,12 @@ restart: goto restart; } + err = security_unix_stream_connect(sock, other->socket, newsk); + if (err) { + unix_state_wunlock(sk); + goto out_unlock; + } + /* The way is open! Fastly set all the necessary fields... */ sock_hold(sk); @@ -1280,6 +1292,10 @@ restart: if (other->shutdown&RCV_SHUTDOWN) goto out_unlock; + err = security_unix_may_send(sk->socket, other->socket); + if (err) + goto out_unlock; + if (unix_peer(other) != sk && skb_queue_len(&other->receive_queue) > other->max_ack_backlog) { if (!timeo) { diff --git a/security/Kconfig b/security/Kconfig index 76d62c92176f..e529321997bd 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -15,6 +15,15 @@ config SECURITY If you are unsure how to answer this question, answer N. +config SECURITY_NETWORK + bool "Socket and Networking Security Hooks" + depends on SECURITY + help + This enables the socket and networking security hooks. + If enabled, a security module can use these hooks to + implement socket and networking access controls. + If you are unsure how to answer this question, answer N. + config SECURITY_CAPABILITIES tristate "Default Linux Capabilities" depends on SECURITY!=n diff --git a/security/capability.c b/security/capability.c index d9b00d69fe41..5909732acdfc 100644 --- a/security/capability.c +++ b/security/capability.c @@ -282,6 +282,8 @@ static struct security_operations capability_ops = { .capset_check = cap_capset_check, .capset_set = cap_capset_set, .capable = cap_capable, + .netlink_send = cap_netlink_send, + .netlink_recv = cap_netlink_recv, .bprm_compute_creds = cap_bprm_compute_creds, .bprm_set_security = cap_bprm_set_security, diff --git a/security/dummy.c b/security/dummy.c index 7f2ad59f9d48..9b450c740bfa 100644 --- a/security/dummy.c +++ b/security/dummy.c @@ -20,7 +20,7 @@ #include <linux/security.h> #include <linux/skbuff.h> #include <linux/netlink.h> - +#include <net/sock.h> static int dummy_ptrace (struct task_struct *parent, struct task_struct *child) { @@ -597,6 +597,118 @@ static int dummy_sem_semop (struct sem_array *sma, return 0; } +static int dummy_netlink_send (struct sk_buff *skb) +{ + if (current->euid == 0) + cap_raise (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN); + else + NETLINK_CB (skb).eff_cap = 0; + return 0; +} + +static int dummy_netlink_recv (struct sk_buff *skb) +{ + if (!cap_raised (NETLINK_CB (skb).eff_cap, CAP_NET_ADMIN)) + return -EPERM; + return 0; +} + +#ifdef CONFIG_SECURITY_NETWORK +static int dummy_unix_stream_connect (struct socket *sock, + struct socket *other, + struct sock *newsk) +{ + return 0; +} + +static int dummy_unix_may_send (struct socket *sock, + struct socket *other) +{ + return 0; +} + +static int dummy_socket_create (int family, int type, int protocol) +{ + return 0; +} + +static void dummy_socket_post_create (struct socket *sock, int family, int type, + int protocol) +{ + return; +} + +static int dummy_socket_bind (struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int dummy_socket_connect (struct socket *sock, struct sockaddr *address, + int addrlen) +{ + return 0; +} + +static int dummy_socket_listen (struct socket *sock, int backlog) +{ + return 0; +} + +static int dummy_socket_accept (struct socket *sock, struct socket *newsock) +{ + return 0; +} + +static void dummy_socket_post_accept (struct socket *sock, + struct socket *newsock) +{ + return; +} + +static int dummy_socket_sendmsg (struct socket *sock, struct msghdr *msg, + int size) +{ + return 0; +} + +static int dummy_socket_recvmsg (struct socket *sock, struct msghdr *msg, + int size, int flags) +{ + return 0; +} + +static int dummy_socket_getsockname (struct socket *sock) +{ + return 0; +} + +static int dummy_socket_getpeername (struct socket *sock) +{ + return 0; +} + +static int dummy_socket_setsockopt (struct socket *sock, int level, int optname) +{ + return 0; +} + +static int dummy_socket_getsockopt (struct socket *sock, int level, int optname) +{ + return 0; +} + +static int dummy_socket_shutdown (struct socket *sock, int how) +{ + return 0; +} + +static int dummy_socket_sock_rcv_skb (struct sock *sk, struct sk_buff *skb) +{ + return 0; +} +#endif /* CONFIG_SECURITY_NETWORK */ + static int dummy_register_security (const char *name, struct security_operations *ops) { return -EINVAL; @@ -723,7 +835,28 @@ void security_fixup_ops (struct security_operations *ops) set_to_dummy_if_null(ops, sem_associate); set_to_dummy_if_null(ops, sem_semctl); set_to_dummy_if_null(ops, sem_semop); + set_to_dummy_if_null(ops, netlink_send); + set_to_dummy_if_null(ops, netlink_recv); set_to_dummy_if_null(ops, register_security); set_to_dummy_if_null(ops, unregister_security); +#ifdef CONFIG_SECURITY_NETWORK + set_to_dummy_if_null(ops, unix_stream_connect); + set_to_dummy_if_null(ops, unix_may_send); + set_to_dummy_if_null(ops, socket_create); + set_to_dummy_if_null(ops, socket_post_create); + set_to_dummy_if_null(ops, socket_bind); + set_to_dummy_if_null(ops, socket_connect); + set_to_dummy_if_null(ops, socket_listen); + set_to_dummy_if_null(ops, socket_accept); + set_to_dummy_if_null(ops, socket_post_accept); + set_to_dummy_if_null(ops, socket_sendmsg); + set_to_dummy_if_null(ops, socket_recvmsg); + set_to_dummy_if_null(ops, socket_getsockname); + set_to_dummy_if_null(ops, socket_getpeername); + set_to_dummy_if_null(ops, socket_setsockopt); + set_to_dummy_if_null(ops, socket_getsockopt); + set_to_dummy_if_null(ops, socket_shutdown); + set_to_dummy_if_null(ops, socket_sock_rcv_skb); +#endif /* CONFIG_SECURITY_NETWORK */ } |
