Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
ad370e28
Commit
ad370e28
authored
Feb 09, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://kernel.bkbits.net/davem/net-2.5
into home.transmeta.com:/home/torvalds/v2.5/linux
parents
d8a1413d
fd7c713f
Changes
23
Show whitespace changes
Inline
Side-by-side
Showing
23 changed files
with
800 additions
and
103 deletions
+800
-103
MAINTAINERS
MAINTAINERS
+1
-3
include/linux/security.h
include/linux/security.h
+423
-6
include/net/sock.h
include/net/sock.h
+64
-33
net/bridge/br.c
net/bridge/br.c
+2
-2
net/bridge/br_if.c
net/bridge/br_if.c
+2
-2
net/core/rtnetlink.c
net/core/rtnetlink.c
+2
-1
net/decnet/dn_nsp_in.c
net/decnet/dn_nsp_in.c
+11
-18
net/ipv4/netfilter/Kconfig
net/ipv4/netfilter/Kconfig
+8
-0
net/ipv4/netfilter/ip_nat_helper.c
net/ipv4/netfilter/ip_nat_helper.c
+0
-1
net/ipv4/netfilter/ip_queue.c
net/ipv4/netfilter/ip_queue.c
+2
-1
net/ipv4/route.c
net/ipv4/route.c
+9
-7
net/ipv4/tcp_ipv4.c
net/ipv4/tcp_ipv4.c
+3
-6
net/ipv4/xfrm_user.c
net/ipv4/xfrm_user.c
+2
-1
net/ipv6/netfilter/ip6_queue.c
net/ipv6/netfilter/ip6_queue.c
+3
-3
net/ipv6/route.c
net/ipv6/route.c
+17
-9
net/ipv6/tcp_ipv6.c
net/ipv6/tcp_ipv6.c
+8
-7
net/netlink/af_netlink.c
net/netlink/af_netlink.c
+7
-1
net/sctp/input.c
net/sctp/input.c
+4
-0
net/socket.c
net/socket.c
+71
-1
net/unix/af_unix.c
net/unix/af_unix.c
+16
-0
security/Kconfig
security/Kconfig
+9
-0
security/capability.c
security/capability.c
+2
-0
security/dummy.c
security/dummy.c
+134
-1
No files found.
MAINTAINERS
View file @
ad370e28
...
...
@@ -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:
M
aintained
S:
Unm
aintained
ETHERTEAM 16I DRIVER
P: Mika Kuoppala
...
...
include/linux/security.h
View file @
ad370e28
...
...
@@ -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 */
include/net/sock.h
View file @
ad370e28
...
...
@@ -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
)
static
inline
int
__sk_filter
(
struct
sock
*
sk
,
struct
sk_buff
*
skb
,
int
needlock
)
{
int
pkt_len
;
int
err
=
0
;
if
(
sk
->
filter
)
{
struct
sk_filter
*
filter
;
pkt_len
=
sk_run_filter
(
skb
,
filter
->
insns
,
filter
->
len
);
if
(
!
pkt_len
)
return
1
;
/* Toss Packet */
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
);
}
return
0
;
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
;
if
(
atomic_read
(
&
sk
->
rmem_alloc
)
+
skb
->
truesize
>=
(
unsigned
)
sk
->
rcvbuf
)
{
err
=
-
ENOMEM
;
goto
out
;
}
/* 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
);
err
=
sk_filter
(
sk
,
skb
,
1
);
if
(
err
)
return
err
;
/* Toss packet */
}
#endif
/* CONFIG_FILTER */
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
)
...
...
net/bridge/br.c
View file @
ad370e28
...
...
@@ -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
)
...
...
net/bridge/br_if.c
View file @
ad370e28
...
...
@@ -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
;
...
...
net/core/rtnetlink.c
View file @
ad370e28
...
...
@@ -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
;
}
...
...
net/decnet/dn_nsp_in.c
View file @
ad370e28
...
...
@@ -566,26 +566,19 @@ static void dn_nsp_linkservice(struct sock *sk, struct sk_buff *skb)
*/
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
;
if
(
atomic_read
(
&
sk
->
rmem_alloc
)
+
skb
->
truesize
>=
(
unsigned
)
sk
->
rcvbuf
)
{
err
=
-
ENOMEM
;
goto
out
;
}
#ifdef CONFIG_FILTER
if
(
sk
->
filter
)
{
int
err
=
0
;
if
((
filter
=
sk
->
filter
)
!=
NULL
&&
sk_filter
(
skb
,
sk
->
filter
))
err
=
-
EPERM
;
/* Toss packet */
err
=
sk_filter
(
sk
,
skb
,
0
);
if
(
err
)
return
err
;
}
#endif
/* CONFIG_FILTER */
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
)
...
...
net/ipv4/netfilter/Kconfig
View file @
ad370e28
...
...
@@ -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"
...
...
net/ipv4/netfilter/ip_nat_helper.c
View file @
ad370e28
...
...
@@ -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
);
...
...
net/ipv4/netfilter/ip_queue.c
View file @
ad370e28
...
...
@@ -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
);
...
...
net/ipv4/route.c
View file @
ad370e28
...
...
@@ -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
)
...
...
net/ipv4/tcp_ipv4.c
View file @
ad370e28
...
...
@@ -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 @@ int tcp_v4_rcv(struct sk_buff *skb)
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
);
...
...
net/ipv4/xfrm_user.c
View file @
ad370e28
...
...
@@ -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
;
}
...
...
net/ipv6/netfilter/ip6_queue.c
View file @
ad370e28
...
...
@@ -539,7 +539,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
);
...
...
net/ipv6/route.c
View file @
ad370e28
...
...
@@ -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
)
if
(
err
>
0
)
err
=
0
;
out:
return
err
;
return
0
;
out_free:
kfree_skb
(
skb
);
goto
out
;
}
void
inet6_rt_notify
(
int
event
,
struct
rt6_info
*
rt
)
...
...
net/ipv6/tcp_ipv6.c
View file @
ad370e28
...
...
@@ -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 @@ static int tcp_v6_rcv(struct sk_buff *skb)
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 @@ static int tcp_v6_rcv(struct sk_buff *skb)
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
);
...
...
net/netlink/af_netlink.c
View file @
ad370e28
...
...
@@ -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
))
{
...
...
net/sctp/input.c
View file @
ad370e28
...
...
@@ -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
)
{
...
...
net/socket.c
View file @
ad370e28
...
...
@@ -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
;
/*
...
...
@@ -987,6 +998,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
);
}
...
...
net/unix/af_unix.c
View file @
ad370e28
...
...
@@ -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 @@ static int unix_stream_connect(struct socket *sock, struct sockaddr *uaddr,
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 @@ static int unix_dgram_sendmsg(struct kiocb *iocb, struct socket *sock,
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
)
{
...
...
security/Kconfig
View file @
ad370e28
...
...
@@ -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
...
...
security/capability.c
View file @
ad370e28
...
...
@@ -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
,
...
...
security/dummy.c
View file @
ad370e28
...
...
@@ -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 */
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment