Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 137588
b: refs/heads/master
c: 389fb80
h: refs/heads/master
v: v3
  • Loading branch information
Paul Moore authored and James Morris committed Mar 28, 2009
1 parent 5e80e1a commit d3b0e90
Show file tree
Hide file tree
Showing 9 changed files with 361 additions and 221 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: 284904aa79466a4736f4c775fdbe5c7407fa136c
refs/heads/master: 389fb800ac8be2832efedd19978a2b8ced37eb61
17 changes: 17 additions & 0 deletions trunk/include/net/cipso_ipv4.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/netlabel.h>
#include <net/request_sock.h>
#include <asm/atomic.h>

/* known doi values */
Expand Down Expand Up @@ -215,6 +216,10 @@ int cipso_v4_sock_setattr(struct sock *sk,
const struct netlbl_lsm_secattr *secattr);
void cipso_v4_sock_delattr(struct sock *sk);
int cipso_v4_sock_getattr(struct sock *sk, struct netlbl_lsm_secattr *secattr);
int cipso_v4_req_setattr(struct request_sock *req,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr);
void cipso_v4_req_delattr(struct request_sock *req);
int cipso_v4_skbuff_setattr(struct sk_buff *skb,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr);
Expand Down Expand Up @@ -247,6 +252,18 @@ static inline int cipso_v4_sock_getattr(struct sock *sk,
return -ENOSYS;
}

static inline int cipso_v4_req_setattr(struct request_sock *req,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}

static inline void cipso_v4_req_delattr(struct request_sock *req)
{
return;
}

static inline int cipso_v4_skbuff_setattr(struct sk_buff *skb,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr)
Expand Down
12 changes: 11 additions & 1 deletion trunk/include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include <linux/in.h>
#include <linux/in6.h>
#include <net/netlink.h>
#include <net/request_sock.h>
#include <asm/atomic.h>

struct cipso_v4_doi;
Expand Down Expand Up @@ -406,13 +407,16 @@ int netlbl_secattr_catmap_setrng(struct netlbl_lsm_secattr_catmap *catmap,
*/
int netlbl_enabled(void);
int netlbl_sock_setattr(struct sock *sk,
u16 family,
const struct netlbl_lsm_secattr *secattr);
void netlbl_sock_delattr(struct sock *sk);
int netlbl_sock_getattr(struct sock *sk,
struct netlbl_lsm_secattr *secattr);
int netlbl_conn_setattr(struct sock *sk,
struct sockaddr *addr,
const struct netlbl_lsm_secattr *secattr);
int netlbl_req_setattr(struct request_sock *req,
const struct netlbl_lsm_secattr *secattr);
int netlbl_skbuff_setattr(struct sk_buff *skb,
u16 family,
const struct netlbl_lsm_secattr *secattr);
Expand Down Expand Up @@ -519,7 +523,8 @@ static inline int netlbl_enabled(void)
return 0;
}
static inline int netlbl_sock_setattr(struct sock *sk,
const struct netlbl_lsm_secattr *secattr)
u16 family,
const struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
Expand All @@ -537,6 +542,11 @@ static inline int netlbl_conn_setattr(struct sock *sk,
{
return -ENOSYS;
}
static inline int netlbl_req_setattr(struct request_sock *req,
const struct netlbl_lsm_secattr *secattr)
{
return -ENOSYS;
}
static inline int netlbl_skbuff_setattr(struct sk_buff *skb,
u16 family,
const struct netlbl_lsm_secattr *secattr)
Expand Down
130 changes: 118 additions & 12 deletions trunk/net/ipv4/cipso_ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -1942,23 +1942,85 @@ int cipso_v4_sock_setattr(struct sock *sk,
}

/**
* cipso_v4_sock_delattr - Delete the CIPSO option from a socket
* @sk: the socket
* cipso_v4_req_setattr - Add a CIPSO option to a connection request socket
* @req: the connection request socket
* @doi_def: the CIPSO DOI to use
* @secattr: the specific security attributes of the socket
*
* Description:
* Removes the CIPSO option from a socket, if present.
* Set the CIPSO option on the given socket using the DOI definition and
* security attributes passed to the function. Returns zero on success and
* negative values on failure.
*
*/
void cipso_v4_sock_delattr(struct sock *sk)
int cipso_v4_req_setattr(struct request_sock *req,
const struct cipso_v4_doi *doi_def,
const struct netlbl_lsm_secattr *secattr)
{
u8 hdr_delta;
struct ip_options *opt;
struct inet_sock *sk_inet;
int ret_val = -EPERM;
unsigned char *buf = NULL;
u32 buf_len;
u32 opt_len;
struct ip_options *opt = NULL;
struct inet_request_sock *req_inet;

sk_inet = inet_sk(sk);
opt = sk_inet->opt;
if (opt == NULL || opt->cipso == 0)
return;
/* We allocate the maximum CIPSO option size here so we are probably
* being a little wasteful, but it makes our life _much_ easier later
* on and after all we are only talking about 40 bytes. */
buf_len = CIPSO_V4_OPT_LEN_MAX;
buf = kmalloc(buf_len, GFP_ATOMIC);
if (buf == NULL) {
ret_val = -ENOMEM;
goto req_setattr_failure;
}

ret_val = cipso_v4_genopt(buf, buf_len, doi_def, secattr);
if (ret_val < 0)
goto req_setattr_failure;
buf_len = ret_val;

/* We can't use ip_options_get() directly because it makes a call to
* ip_options_get_alloc() which allocates memory with GFP_KERNEL and
* we won't always have CAP_NET_RAW even though we _always_ want to
* set the IPOPT_CIPSO option. */
opt_len = (buf_len + 3) & ~3;
opt = kzalloc(sizeof(*opt) + opt_len, GFP_ATOMIC);
if (opt == NULL) {
ret_val = -ENOMEM;
goto req_setattr_failure;
}
memcpy(opt->__data, buf, buf_len);
opt->optlen = opt_len;
opt->cipso = sizeof(struct iphdr);
kfree(buf);
buf = NULL;

req_inet = inet_rsk(req);
opt = xchg(&req_inet->opt, opt);
kfree(opt);

return 0;

req_setattr_failure:
kfree(buf);
kfree(opt);
return ret_val;
}

/**
* cipso_v4_delopt - Delete the CIPSO option from a set of IP options
* @opt_ptr: IP option pointer
*
* Description:
* Deletes the CIPSO IP option from a set of IP options and makes the necessary
* adjustments to the IP option structure. Returns zero on success, negative
* values on failure.
*
*/
int cipso_v4_delopt(struct ip_options **opt_ptr)
{
int hdr_delta = 0;
struct ip_options *opt = *opt_ptr;

if (opt->srr || opt->rr || opt->ts || opt->router_alert) {
u8 cipso_len;
Expand Down Expand Up @@ -2003,18 +2065,62 @@ void cipso_v4_sock_delattr(struct sock *sk)
} else {
/* only the cipso option was present on the socket so we can
* remove the entire option struct */
sk_inet->opt = NULL;
*opt_ptr = NULL;
hdr_delta = opt->optlen;
kfree(opt);
}

return hdr_delta;
}

/**
* cipso_v4_sock_delattr - Delete the CIPSO option from a socket
* @sk: the socket
*
* Description:
* Removes the CIPSO option from a socket, if present.
*
*/
void cipso_v4_sock_delattr(struct sock *sk)
{
int hdr_delta;
struct ip_options *opt;
struct inet_sock *sk_inet;

sk_inet = inet_sk(sk);
opt = sk_inet->opt;
if (opt == NULL || opt->cipso == 0)
return;

hdr_delta = cipso_v4_delopt(&sk_inet->opt);
if (sk_inet->is_icsk && hdr_delta > 0) {
struct inet_connection_sock *sk_conn = inet_csk(sk);
sk_conn->icsk_ext_hdr_len -= hdr_delta;
sk_conn->icsk_sync_mss(sk, sk_conn->icsk_pmtu_cookie);
}
}

/**
* cipso_v4_req_delattr - Delete the CIPSO option from a request socket
* @reg: the request socket
*
* Description:
* Removes the CIPSO option from a request socket, if present.
*
*/
void cipso_v4_req_delattr(struct request_sock *req)
{
struct ip_options *opt;
struct inet_request_sock *req_inet;

req_inet = inet_rsk(req);
opt = req_inet->opt;
if (opt == NULL || opt->cipso == 0)
return;

cipso_v4_delopt(&req_inet->opt);
}

/**
* cipso_v4_getattr - Helper function for the cipso_v4_*_getattr functions
* @cipso: the CIPSO v4 option
Expand Down
Loading

0 comments on commit d3b0e90

Please sign in to comment.