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
Expand all
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
This diff is collapsed.
Click to expand it.
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