Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 157336
b: refs/heads/master
c: 2b980db
h: refs/heads/master
v: v3
  • Loading branch information
Paul Moore authored and James Morris committed Aug 31, 2009
1 parent b69b382 commit 0c9b22f
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d8e180dcd5bbbab9cd3ff2e779efcf70692ef541
refs/heads/master: 2b980dbd77d229eb60588802162c9659726b11f4
22 changes: 15 additions & 7 deletions trunk/drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,17 +130,10 @@ static inline struct tun_sock *tun_sk(struct sock *sk)
static int tun_attach(struct tun_struct *tun, struct file *file)
{
struct tun_file *tfile = file->private_data;
const struct cred *cred = current_cred();
int err;

ASSERT_RTNL();

/* Check permissions */
if (((tun->owner != -1 && cred->euid != tun->owner) ||
(tun->group != -1 && !in_egroup_p(tun->group))) &&
!capable(CAP_NET_ADMIN))
return -EPERM;

netif_tx_lock_bh(tun->dev);

err = -EINVAL;
Expand Down Expand Up @@ -926,6 +919,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)

dev = __dev_get_by_name(net, ifr->ifr_name);
if (dev) {
const struct cred *cred = current_cred();

if (ifr->ifr_flags & IFF_TUN_EXCL)
return -EBUSY;
if ((ifr->ifr_flags & IFF_TUN) && dev->netdev_ops == &tun_netdev_ops)
Expand All @@ -935,6 +930,14 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
else
return -EINVAL;

if (((tun->owner != -1 && cred->euid != tun->owner) ||
(tun->group != -1 && !in_egroup_p(tun->group))) &&
!capable(CAP_NET_ADMIN))
return -EPERM;
err = security_tun_dev_attach(tun->sk);
if (err < 0)
return err;

err = tun_attach(tun, file);
if (err < 0)
return err;
Expand All @@ -947,6 +950,9 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)

if (!capable(CAP_NET_ADMIN))
return -EPERM;
err = security_tun_dev_create();
if (err < 0)
return err;

/* Set dev type */
if (ifr->ifr_flags & IFF_TUN) {
Expand Down Expand Up @@ -989,6 +995,8 @@ static int tun_set_iff(struct net *net, struct file *file, struct ifreq *ifr)
tun->sk = sk;
container_of(sk, struct tun_sock, sk)->tun = tun;

security_tun_dev_post_create(sk);

tun_net_init(dev);

if (strchr(dev->name, '%')) {
Expand Down
31 changes: 31 additions & 0 deletions trunk/include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -998,6 +998,17 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
* Sets the connection's peersid to the secmark on skb.
* @req_classify_flow:
* Sets the flow's sid to the openreq sid.
* @tun_dev_create:
* Check permissions prior to creating a new TUN device.
* @tun_dev_post_create:
* This hook allows a module to update or allocate a per-socket security
* structure.
* @sk contains the newly created sock structure.
* @tun_dev_attach:
* Check permissions prior to attaching to a persistent TUN device. This
* hook can also be used by the module to update any security state
* associated with the TUN device's sock structure.
* @sk contains the existing sock structure.
*
* Security hooks for XFRM operations.
*
Expand Down Expand Up @@ -1597,6 +1608,9 @@ struct security_operations {
void (*inet_csk_clone) (struct sock *newsk, const struct request_sock *req);
void (*inet_conn_established) (struct sock *sk, struct sk_buff *skb);
void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
int (*tun_dev_create)(void);
void (*tun_dev_post_create)(struct sock *sk);
int (*tun_dev_attach)(struct sock *sk);
#endif /* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_NETWORK_XFRM
Expand Down Expand Up @@ -2586,6 +2600,9 @@ void security_inet_csk_clone(struct sock *newsk,
const struct request_sock *req);
void security_inet_conn_established(struct sock *sk,
struct sk_buff *skb);
int security_tun_dev_create(void);
void security_tun_dev_post_create(struct sock *sk);
int security_tun_dev_attach(struct sock *sk);

#else /* CONFIG_SECURITY_NETWORK */
static inline int security_unix_stream_connect(struct socket *sock,
Expand Down Expand Up @@ -2736,6 +2753,20 @@ static inline void security_inet_conn_established(struct sock *sk,
struct sk_buff *skb)
{
}

static inline int security_tun_dev_create(void)
{
return 0;
}

static inline void security_tun_dev_post_create(struct sock *sk)
{
}

static inline int security_tun_dev_attach(struct sock *sk)
{
return 0;
}
#endif /* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_NETWORK_XFRM
Expand Down
19 changes: 19 additions & 0 deletions trunk/security/capability.c
Original file line number Diff line number Diff line change
Expand Up @@ -706,10 +706,26 @@ static void cap_inet_conn_established(struct sock *sk, struct sk_buff *skb)
{
}



static void cap_req_classify_flow(const struct request_sock *req,
struct flowi *fl)
{
}

static int cap_tun_dev_create(void)
{
return 0;
}

static void cap_tun_dev_post_create(struct sock *sk)
{
}

static int cap_tun_dev_attach(struct sock *sk)
{
return 0;
}
#endif /* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_NETWORK_XFRM
Expand Down Expand Up @@ -1026,6 +1042,9 @@ void security_fixup_ops(struct security_operations *ops)
set_to_cap_if_null(ops, inet_csk_clone);
set_to_cap_if_null(ops, inet_conn_established);
set_to_cap_if_null(ops, req_classify_flow);
set_to_cap_if_null(ops, tun_dev_create);
set_to_cap_if_null(ops, tun_dev_post_create);
set_to_cap_if_null(ops, tun_dev_attach);
#endif /* CONFIG_SECURITY_NETWORK */
#ifdef CONFIG_SECURITY_NETWORK_XFRM
set_to_cap_if_null(ops, xfrm_policy_alloc_security);
Expand Down
18 changes: 18 additions & 0 deletions trunk/security/security.c
Original file line number Diff line number Diff line change
Expand Up @@ -1117,6 +1117,24 @@ void security_inet_conn_established(struct sock *sk,
security_ops->inet_conn_established(sk, skb);
}

int security_tun_dev_create(void)
{
return security_ops->tun_dev_create();
}
EXPORT_SYMBOL(security_tun_dev_create);

void security_tun_dev_post_create(struct sock *sk)
{
return security_ops->tun_dev_post_create(sk);
}
EXPORT_SYMBOL(security_tun_dev_post_create);

int security_tun_dev_attach(struct sock *sk)
{
return security_ops->tun_dev_attach(sk);
}
EXPORT_SYMBOL(security_tun_dev_attach);

#endif /* CONFIG_SECURITY_NETWORK */

#ifdef CONFIG_SECURITY_NETWORK_XFRM
Expand Down

0 comments on commit 0c9b22f

Please sign in to comment.