#include <net/checksum.h>
#include <linux/security.h>
-int sysctl_unix_max_dgram_qlen = 10;
+int sysctl_unix_max_dgram_qlen __read_mostly = 10;
struct hlist_head unix_socket_table[UNIX_HASH_SIZE + 1];
DEFINE_SPINLOCK(unix_table_lock);
#define UNIX_ABSTRACT(sk) (unix_sk(sk)->addr->hash != UNIX_HASH_SIZE)
#ifdef CONFIG_SECURITY_NETWORK
-static void unix_get_peersec_dgram(struct sk_buff *skb)
+static void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- int err;
-
- err = security_socket_getpeersec_dgram(skb, UNIXSECDATA(skb),
- UNIXSECLEN(skb));
- if (err)
- *(UNIXSECDATA(skb)) = NULL;
+ memcpy(UNIXSID(skb), &scm->secid, sizeof(u32));
}
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{
- scm->secdata = *UNIXSECDATA(skb);
- scm->seclen = *UNIXSECLEN(skb);
+ scm->secid = *UNIXSID(skb);
}
#else
-static inline void unix_get_peersec_dgram(struct sk_buff *skb)
+static inline void unix_get_secdata(struct scm_cookie *scm, struct sk_buff *skb)
{ }
static inline void unix_set_secdata(struct scm_cookie *scm, struct sk_buff *skb)
* each socket state is protected by separate rwlock.
*/
-static inline unsigned unix_hash_fold(unsigned hash)
+static inline unsigned unix_hash_fold(__wsum n)
{
+ unsigned hash = (__force unsigned)n;
hash ^= hash>>16;
hash ^= hash>>8;
return hash&(UNIX_HASH_SIZE-1);
* - if started by not zero, should be NULL terminated (FS object)
* - if started by zero, it is abstract name.
*/
-
+
static int unix_mkname(struct sockaddr_un * sunaddr, int len, unsigned *hashp)
{
if (len <= sizeof(short) || len > sizeof(*sunaddr))
*/
if (atomic_read(&unix_tot_inflight))
- unix_gc(); /* Garbage collect fds */
+ unix_gc(); /* Garbage collect fds */
return 0;
}
goto out;
err = -ENOMEM;
- addr = kmalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
+ addr = kzalloc(sizeof(*addr) + sizeof(short) + 16, GFP_KERNEL);
if (!addr)
goto out;
- memset(addr, 0, sizeof(*addr) + sizeof(short) + 16);
addr->name->sun_family = AF_UNIX;
atomic_set(&addr->refcnt, 1);
struct sock *u;
struct nameidata nd;
int err = 0;
-
+
if (sunname->sun_path[0]) {
err = path_lookup(sunname->sun_path, LOOKUP_FOLLOW, &nd);
if (err)
unix_peer(sk)=other;
unix_state_wunlock(sk);
}
- return 0;
+ return 0;
out_unlock:
unix_state_wunlock(sk);
goto out;
sock_put(other);
goto restart;
- }
+ }
/* Latch our state.
memcpy(UNIXCREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
if (siocb->scm->fp)
unix_attach_fds(siocb->scm, skb);
-
- unix_get_peersec_dgram(skb);
+ unix_get_secdata(siocb->scm, skb);
skb->h.raw = skb->data;
err = memcpy_fromiovec(skb_put(skb,len), msg->msg_iov, len);
return err;
}
-
+
static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock,
struct msghdr *msg, size_t len)
{
if (size > SKB_MAX_ALLOC)
size = SKB_MAX_ALLOC;
-
+
/*
* Grab a buffer
*/
-
+
skb=sock_alloc_send_skb(sk,size,msg->msg_flags&MSG_DONTWAIT, &err);
if (skb==NULL)
{
int err;
struct sock *sk = sock->sk;
-
+
err = sock_error(sk);
if (err)
return err;
return unix_dgram_sendmsg(kiocb, sock, msg, len);
}
-
+
static void unix_copy_addr(struct msghdr *msg, struct sock *sk)
{
struct unix_sock *u = unix_sk(sk);
if (UNIXCB(skb).fp)
unix_detach_fds(siocb->scm, skb);
}
- else
+ else
{
/* It is questionable: on PEEK we could:
- do not return fds - good, but too simple 8)
apparently wrong)
- clone fds (I chose it for now, it is the most universal
solution)
-
- POSIX 1003.1g does not actually define this clearly
- at all. POSIX 1003.1g doesn't define a lot of things
- clearly however!
-
+
+ POSIX 1003.1g does not actually define this clearly
+ at all. POSIX 1003.1g doesn't define a lot of things
+ clearly however!
+
*/
if (UNIXCB(skb).fp)
siocb->scm->fp = scm_fp_dup(UNIXCB(skb).fp);
/*
* Sleep until data has arrive. But check for races..
*/
-
+
static long unix_stream_data_wait(struct sock * sk, long timeo)
{
DEFINE_WAIT(wait);
/*
* POSIX 1003.1g mandates this order.
*/
-
+
if ((err = sock_error(sk)) != 0)
break;
if (sk->sk_shutdown & RCV_SHUTDOWN)
struct sock *s;
for (s = first_unix_socket(iter); s; s = next_unix_socket(iter, s)) {
- if (off == pos)
+ if (off == pos)
return s;
++off;
}
{
++*pos;
- if (v == (void *)1)
+ if (v == (void *)1)
return first_unix_socket(seq->private);
return next_unix_socket(seq->private, v);
}
static int unix_seq_show(struct seq_file *seq, void *v)
{
-
+
if (v == (void *)1)
seq_puts(seq, "Num RefCount Protocol Flags Type St "
"Inode Path\n");
int rc = -1;
struct sk_buff *dummy_skb;
- if (sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb)) {
- printk(KERN_CRIT "%s: panic\n", __FUNCTION__);
- goto out;
- }
+ BUILD_BUG_ON(sizeof(struct unix_skb_parms) > sizeof(dummy_skb->cb));
rc = proto_register(&unix_proto, 1);
- if (rc != 0) {
- printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
+ if (rc != 0) {
+ printk(KERN_CRIT "%s: Cannot create unix_sock SLAB cache!\n",
__FUNCTION__);
goto out;
}