Skip to content

Commit

Permalink
Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Browse files Browse the repository at this point in the history
* master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6:
  [PKT_SCHED] sch_htb: use rb_first() cleanup
  [RTNETLINK]: Fix use of wrong skb in do_getlink()
  [DECNET]: Fix sfuzz hanging on 2.6.18
  [NET]: Do not memcmp() over pad bytes of struct flowi.
  [NET]: Introduce protocol-specific destructor for time-wait sockets.
  [NET]: Use typesafe inet_twsk() inline function instead of cast.
  [NET]: Use hton{l,s}() for non-initializers.
  [TCP]: Use TCPOLEN_TSTAMP_ALIGNED macro instead of magic number.
  [IPV6]: Seperate sit driver to extra module (addrconf.c changes)
  [IPV6]: Seperate sit driver to extra module
  [NET]: File descriptor loss while receiving SCM_RIGHTS
  [SCTP]: Fix the RX queue size shown in /proc/net/sctp/assocs output.
  [SCTP]: Fix receive buffer accounting.
  SELinux: Bug fix in polidydb_destroy
  IPsec: fix handling of errors for socket policies
  IPsec: correct semantics for SELinux policy matching
  IPsec: propagate security module errors up from flow_cache_lookup
  NetLabel: use SECINITSID_UNLABELED for a base SID
  NetLabel: fix a cache race condition
  • Loading branch information
Linus Torvalds committed Oct 12, 2006
2 parents 83d3d3c + 30bdbe3 commit 9ff4680
Show file tree
Hide file tree
Showing 43 changed files with 411 additions and 219 deletions.
24 changes: 9 additions & 15 deletions include/linux/security.h
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,8 @@ struct request_sock;
* Check permission when a flow selects a xfrm_policy for processing
* XFRMs on a packet. The hook is called when selecting either a
* per-socket policy or a generic xfrm policy.
* Return 0 if permission is granted.
* Return 0 if permission is granted, -ESRCH otherwise, or -errno
* on other errors.
* @xfrm_state_pol_flow_match:
* @x contains the state to match.
* @xp contains the policy to check for a match.
Expand All @@ -891,6 +892,7 @@ struct request_sock;
* @xfrm_flow_state_match:
* @fl contains the flow key to match.
* @xfrm points to the xfrm_state to match.
* @xp points to the xfrm_policy to match.
* Return 1 if there is a match.
* @xfrm_decode_session:
* @skb points to skb to decode.
Expand Down Expand Up @@ -1388,7 +1390,8 @@ struct security_operations {
int (*xfrm_policy_lookup)(struct xfrm_policy *xp, u32 fl_secid, u8 dir);
int (*xfrm_state_pol_flow_match)(struct xfrm_state *x,
struct xfrm_policy *xp, struct flowi *fl);
int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm);
int (*xfrm_flow_state_match)(struct flowi *fl, struct xfrm_state *xfrm,
struct xfrm_policy *xp);
int (*xfrm_decode_session)(struct sk_buff *skb, u32 *secid, int ckall);
#endif /* CONFIG_SECURITY_NETWORK_XFRM */

Expand Down Expand Up @@ -3120,11 +3123,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
return security_ops->xfrm_policy_alloc_security(xp, sec_ctx, NULL);
}

static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
{
return security_ops->xfrm_policy_alloc_security(xp, NULL, sk);
}

static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
{
return security_ops->xfrm_policy_clone_security(old, new);
Expand Down Expand Up @@ -3175,9 +3173,10 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
return security_ops->xfrm_state_pol_flow_match(x, xp, fl);
}

static inline int security_xfrm_flow_state_match(struct flowi *fl, struct xfrm_state *xfrm)
static inline int security_xfrm_flow_state_match(struct flowi *fl,
struct xfrm_state *xfrm, struct xfrm_policy *xp)
{
return security_ops->xfrm_flow_state_match(fl, xfrm);
return security_ops->xfrm_flow_state_match(fl, xfrm, xp);
}

static inline int security_xfrm_decode_session(struct sk_buff *skb, u32 *secid)
Expand All @@ -3197,11 +3196,6 @@ static inline int security_xfrm_policy_alloc(struct xfrm_policy *xp, struct xfrm
return 0;
}

static inline int security_xfrm_sock_policy_alloc(struct xfrm_policy *xp, struct sock *sk)
{
return 0;
}

static inline int security_xfrm_policy_clone(struct xfrm_policy *old, struct xfrm_policy *new)
{
return 0;
Expand Down Expand Up @@ -3249,7 +3243,7 @@ static inline int security_xfrm_state_pol_flow_match(struct xfrm_state *x,
}

static inline int security_xfrm_flow_state_match(struct flowi *fl,
struct xfrm_state *xfrm)
struct xfrm_state *xfrm, struct xfrm_policy *xp)
{
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion include/net/flow.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ struct flowi {
#define FLOW_DIR_FWD 2

struct sock;
typedef void (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
typedef int (*flow_resolve_t)(struct flowi *key, u16 family, u8 dir,
void **objp, atomic_t **obj_refp);

extern void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,
Expand Down
1 change: 1 addition & 0 deletions include/net/inet_timewait_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ static inline void inet_twsk_put(struct inet_timewait_sock *tw)
{
if (atomic_dec_and_test(&tw->tw_refcnt)) {
struct module *owner = tw->tw_prot->owner;
twsk_destructor((struct sock *)tw);
#ifdef SOCK_REFCNT_DEBUG
printk(KERN_DEBUG "%s timewait_sock %p released\n",
tw->tw_prot->name, tw);
Expand Down
62 changes: 47 additions & 15 deletions include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include <linux/net.h>
#include <linux/skbuff.h>
#include <net/netlink.h>
#include <asm/atomic.h>

/*
* NetLabel - A management interface for maintaining network packet label
Expand Down Expand Up @@ -106,6 +107,7 @@ int netlbl_domhsh_remove(const char *domain, struct netlbl_audit *audit_info);

/* LSM security attributes */
struct netlbl_lsm_cache {
atomic_t refcount;
void (*free) (const void *data);
void *data;
};
Expand All @@ -117,14 +119,51 @@ struct netlbl_lsm_secattr {
unsigned char *mls_cat;
size_t mls_cat_len;

struct netlbl_lsm_cache cache;
struct netlbl_lsm_cache *cache;
};

/*
* LSM security attribute operations
*/


/**
* netlbl_secattr_cache_alloc - Allocate and initialize a secattr cache
* @flags: the memory allocation flags
*
* Description:
* Allocate and initialize a netlbl_lsm_cache structure. Returns a pointer
* on success, NULL on failure.
*
*/
static inline struct netlbl_lsm_cache *netlbl_secattr_cache_alloc(int flags)
{
struct netlbl_lsm_cache *cache;

cache = kzalloc(sizeof(*cache), flags);
if (cache)
atomic_set(&cache->refcount, 1);
return cache;
}

/**
* netlbl_secattr_cache_free - Frees a netlbl_lsm_cache struct
* @cache: the struct to free
*
* Description:
* Frees @secattr including all of the internal buffers.
*
*/
static inline void netlbl_secattr_cache_free(struct netlbl_lsm_cache *cache)
{
if (!atomic_dec_and_test(&cache->refcount))
return;

if (cache->free)
cache->free(cache->data);
kfree(cache);
}

/**
* netlbl_secattr_init - Initialize a netlbl_lsm_secattr struct
* @secattr: the struct to initialize
Expand All @@ -143,20 +182,16 @@ static inline int netlbl_secattr_init(struct netlbl_lsm_secattr *secattr)
/**
* netlbl_secattr_destroy - Clears a netlbl_lsm_secattr struct
* @secattr: the struct to clear
* @clear_cache: cache clear flag
*
* Description:
* Destroys the @secattr struct, including freeing all of the internal buffers.
* If @clear_cache is true then free the cache fields, otherwise leave them
* intact. The struct must be reset with a call to netlbl_secattr_init()
* before reuse.
* The struct must be reset with a call to netlbl_secattr_init() before reuse.
*
*/
static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr,
u32 clear_cache)
static inline void netlbl_secattr_destroy(struct netlbl_lsm_secattr *secattr)
{
if (clear_cache && secattr->cache.data != NULL && secattr->cache.free)
secattr->cache.free(secattr->cache.data);
if (secattr->cache)
netlbl_secattr_cache_free(secattr->cache);
kfree(secattr->domain);
kfree(secattr->mls_cat);
}
Expand All @@ -178,17 +213,14 @@ static inline struct netlbl_lsm_secattr *netlbl_secattr_alloc(int flags)
/**
* netlbl_secattr_free - Frees a netlbl_lsm_secattr struct
* @secattr: the struct to free
* @clear_cache: cache clear flag
*
* Description:
* Frees @secattr including all of the internal buffers. If @clear_cache is
* true then free the cache fields, otherwise leave them intact.
* Frees @secattr including all of the internal buffers.
*
*/
static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr,
u32 clear_cache)
static inline void netlbl_secattr_free(struct netlbl_lsm_secattr *secattr)
{
netlbl_secattr_destroy(secattr, clear_cache);
netlbl_secattr_destroy(secattr);
kfree(secattr);
}

Expand Down
14 changes: 14 additions & 0 deletions include/net/sctp/sctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ int sctp_inet_listen(struct socket *sock, int backlog);
void sctp_write_space(struct sock *sk);
unsigned int sctp_poll(struct file *file, struct socket *sock,
poll_table *wait);
void sctp_sock_rfree(struct sk_buff *skb);

/*
* sctp/primitive.c
Expand Down Expand Up @@ -444,6 +445,19 @@ static inline struct list_head *sctp_list_dequeue(struct list_head *list)
return result;
}

/* SCTP version of skb_set_owner_r. We need this one because
* of the way we have to do receive buffer accounting on bundled
* chunks.
*/
static inline void sctp_skb_set_owner_r(struct sk_buff *skb, struct sock *sk)
{
struct sctp_ulpevent *event = sctp_skb2event(skb);

skb->sk = sk;
skb->destructor = sctp_sock_rfree;
atomic_add(event->rmem_len, &sk->sk_rmem_alloc);
}

/* Tests if the list has one and only one entry. */
static inline int sctp_list_single_entry(struct list_head *head)
{
Expand Down
1 change: 1 addition & 0 deletions include/net/sctp/ulpevent.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ struct sctp_ulpevent {
__u32 cumtsn;
int msg_flags;
int iif;
unsigned int rmem_len;
};

/* Retrieve the skb this event sits inside of. */
Expand Down
7 changes: 7 additions & 0 deletions include/net/timewait_sock.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct timewait_sock_ops {
unsigned int twsk_obj_size;
int (*twsk_unique)(struct sock *sk,
struct sock *sktw, void *twp);
void (*twsk_destructor)(struct sock *sk);
};

static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
Expand All @@ -28,4 +29,10 @@ static inline int twsk_unique(struct sock *sk, struct sock *sktw, void *twp)
return 0;
}

static inline void twsk_destructor(struct sock *sk)
{
if (sk->sk_prot->twsk_prot->twsk_destructor != NULL)
sk->sk_prot->twsk_prot->twsk_destructor(sk);
}

#endif /* _TIMEWAIT_SOCK_H */
3 changes: 2 additions & 1 deletion include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -995,7 +995,8 @@ struct xfrm_state * xfrm_find_acq(u8 mode, u32 reqid, u8 proto,
int create, unsigned short family);
extern void xfrm_policy_flush(u8 type);
extern int xfrm_sk_policy_insert(struct sock *sk, int dir, struct xfrm_policy *pol);
extern int xfrm_bundle_ok(struct xfrm_dst *xdst, struct flowi *fl, int family, int strict);
extern int xfrm_bundle_ok(struct xfrm_policy *pol, struct xfrm_dst *xdst,
struct flowi *fl, int family, int strict);
extern void xfrm_init_pmtu(struct dst_entry *dst);

extern wait_queue_head_t km_waitq;
Expand Down
3 changes: 1 addition & 2 deletions net/compat.c
Original file line number Diff line number Diff line change
Expand Up @@ -285,8 +285,7 @@ void scm_detach_fds_compat(struct msghdr *kmsg, struct scm_cookie *scm)

if (i > 0) {
int cmlen = CMSG_COMPAT_LEN(i * sizeof(int));
if (!err)
err = put_user(SOL_SOCKET, &cm->cmsg_level);
err = put_user(SOL_SOCKET, &cm->cmsg_level);
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
if (!err)
Expand Down
42 changes: 28 additions & 14 deletions net/core/flow.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,14 @@ static void flow_cache_new_hashrnd(unsigned long arg)
add_timer(&flow_hash_rnd_timer);
}

static void flow_entry_kill(int cpu, struct flow_cache_entry *fle)
{
if (fle->object)
atomic_dec(fle->object_ref);
kmem_cache_free(flow_cachep, fle);
flow_count(cpu)--;
}

static void __flow_cache_shrink(int cpu, int shrink_to)
{
struct flow_cache_entry *fle, **flp;
Expand All @@ -100,10 +108,7 @@ static void __flow_cache_shrink(int cpu, int shrink_to)
}
while ((fle = *flp) != NULL) {
*flp = fle->next;
if (fle->object)
atomic_dec(fle->object_ref);
kmem_cache_free(flow_cachep, fle);
flow_count(cpu)--;
flow_entry_kill(cpu, fle);
}
}
}
Expand Down Expand Up @@ -220,24 +225,33 @@ void *flow_cache_lookup(struct flowi *key, u16 family, u8 dir,

nocache:
{
int err;
void *obj;
atomic_t *obj_ref;

resolver(key, family, dir, &obj, &obj_ref);
err = resolver(key, family, dir, &obj, &obj_ref);

if (fle) {
fle->genid = atomic_read(&flow_cache_genid);

if (fle->object)
atomic_dec(fle->object_ref);

fle->object = obj;
fle->object_ref = obj_ref;
if (obj)
atomic_inc(fle->object_ref);
if (err) {
/* Force security policy check on next lookup */
*head = fle->next;
flow_entry_kill(cpu, fle);
} else {
fle->genid = atomic_read(&flow_cache_genid);

if (fle->object)
atomic_dec(fle->object_ref);

fle->object = obj;
fle->object_ref = obj_ref;
if (obj)
atomic_inc(fle->object_ref);
}
}
local_bh_enable();

if (err)
obj = ERR_PTR(err);
return obj;
}
}
Expand Down
2 changes: 1 addition & 1 deletion net/core/rtnetlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,7 @@ static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
goto errout;
}

err = rtnl_unicast(skb, NETLINK_CB(skb).pid);
err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
errout:
kfree(iw_buf);
dev_put(dev);
Expand Down
3 changes: 1 addition & 2 deletions net/core/scm.c
Original file line number Diff line number Diff line change
Expand Up @@ -245,8 +245,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm)
if (i > 0)
{
int cmlen = CMSG_LEN(i*sizeof(int));
if (!err)
err = put_user(SOL_SOCKET, &cm->cmsg_level);
err = put_user(SOL_SOCKET, &cm->cmsg_level);
if (!err)
err = put_user(SCM_RIGHTS, &cm->cmsg_type);
if (!err)
Expand Down
6 changes: 3 additions & 3 deletions net/dccp/ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -311,7 +311,7 @@ static void dccp_v4_err(struct sk_buff *skb, u32 info)
}

if (sk->sk_state == DCCP_TIME_WAIT) {
inet_twsk_put((struct inet_timewait_sock *)sk);
inet_twsk_put(inet_twsk(sk));
return;
}

Expand Down Expand Up @@ -614,7 +614,7 @@ static struct sock *dccp_v4_hnd_req(struct sock *sk, struct sk_buff *skb)
bh_lock_sock(nsk);
return nsk;
}
inet_twsk_put((struct inet_timewait_sock *)nsk);
inet_twsk_put(inet_twsk(nsk));
return NULL;
}

Expand Down Expand Up @@ -980,7 +980,7 @@ static int dccp_v4_rcv(struct sk_buff *skb)
goto discard_it;

do_time_wait:
inet_twsk_put((struct inet_timewait_sock *)sk);
inet_twsk_put(inet_twsk(sk));
goto no_dccp_socket;
}

Expand Down
Loading

0 comments on commit 9ff4680

Please sign in to comment.