Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 327807
b: refs/heads/master
c: 600e177
h: refs/heads/master
i:
  327805: bb7b56f
  327803: 28a07e7
  327799: a1f0c8a
  327791: c52d34b
  327775: d0f1f8b
  327743: 7a10dde
  327679: 9dd685f
v: v3
  • Loading branch information
Masatake YAMATO authored and David S. Miller committed Sep 4, 2012
1 parent 24b83e0 commit 47d27a5
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 6 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: cefd81cfeca14ec4c63cc748441634f1d4c0eb3f
refs/heads/master: 600e177920df936d03b807780ca92c662af98990
83 changes: 78 additions & 5 deletions trunk/net/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@
#include <linux/nsproxy.h>
#include <linux/magic.h>
#include <linux/slab.h>
#include <linux/xattr.h>

#include <asm/uaccess.h>
#include <asm/unistd.h>
Expand Down Expand Up @@ -346,7 +347,8 @@ static struct file_system_type sock_fs_type = {
* but we take care of internal coherence yet.
*/

static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
static int sock_alloc_file(struct socket *sock, struct file **f, int flags,
const char *dname)
{
struct qstr name = { .name = "" };
struct path path;
Expand All @@ -357,6 +359,13 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
if (unlikely(fd < 0))
return fd;

if (dname) {
name.name = dname;
name.len = strlen(name.name);
} else if (sock->sk) {
name.name = sock->sk->sk_prot_creator->name;
name.len = strlen(name.name);
}
path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name);
if (unlikely(!path.dentry)) {
put_unused_fd(fd);
Expand Down Expand Up @@ -389,7 +398,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
int sock_map_fd(struct socket *sock, int flags)
{
struct file *newfile;
int fd = sock_alloc_file(sock, &newfile, flags);
int fd = sock_alloc_file(sock, &newfile, flags, NULL);

if (likely(fd >= 0))
fd_install(fd, newfile);
Expand Down Expand Up @@ -455,6 +464,68 @@ static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed)
return NULL;
}

#define XATTR_SOCKPROTONAME_SUFFIX "sockprotoname"
#define XATTR_NAME_SOCKPROTONAME (XATTR_SYSTEM_PREFIX XATTR_SOCKPROTONAME_SUFFIX)
#define XATTR_NAME_SOCKPROTONAME_LEN (sizeof(XATTR_NAME_SOCKPROTONAME)-1)
static ssize_t sockfs_getxattr(struct dentry *dentry,
const char *name, void *value, size_t size)
{
const char *proto_name;
size_t proto_size;
int error;

error = -ENODATA;
if (!strncmp(name, XATTR_NAME_SOCKPROTONAME, XATTR_NAME_SOCKPROTONAME_LEN)) {
proto_name = dentry->d_name.name;
proto_size = strlen(proto_name);

if (value) {
error = -ERANGE;
if (proto_size + 1 > size)
goto out;

strncpy(value, proto_name, proto_size + 1);
}
error = proto_size + 1;
}

out:
return error;
}

static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer,
size_t size)
{
ssize_t len;
ssize_t used = 0;

len = security_inode_listsecurity(dentry->d_inode, buffer, size);
if (len < 0)
return len;
used += len;
if (buffer) {
if (size < used)
return -ERANGE;
buffer += len;
}

len = (XATTR_NAME_SOCKPROTONAME_LEN + 1);
used += len;
if (buffer) {
if (size < used)
return -ERANGE;
memcpy(buffer, XATTR_NAME_SOCKPROTONAME, len);
buffer += len;
}

return used;
}

static const struct inode_operations sockfs_inode_ops = {
.getxattr = sockfs_getxattr,
.listxattr = sockfs_listxattr,
};

/**
* sock_alloc - allocate a socket
*
Expand All @@ -479,6 +550,7 @@ static struct socket *sock_alloc(void)
inode->i_mode = S_IFSOCK | S_IRWXUGO;
inode->i_uid = current_fsuid();
inode->i_gid = current_fsgid();
inode->i_op = &sockfs_inode_ops;

this_cpu_add(sockets_in_use, 1);
return sock;
Expand Down Expand Up @@ -1394,13 +1466,13 @@ SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol,
if (err < 0)
goto out_release_both;

fd1 = sock_alloc_file(sock1, &newfile1, flags);
fd1 = sock_alloc_file(sock1, &newfile1, flags, NULL);
if (unlikely(fd1 < 0)) {
err = fd1;
goto out_release_both;
}

fd2 = sock_alloc_file(sock2, &newfile2, flags);
fd2 = sock_alloc_file(sock2, &newfile2, flags, NULL);
if (unlikely(fd2 < 0)) {
err = fd2;
fput(newfile1);
Expand Down Expand Up @@ -1536,7 +1608,8 @@ SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr,
*/
__module_get(newsock->ops->owner);

newfd = sock_alloc_file(newsock, &newfile, flags);
newfd = sock_alloc_file(newsock, &newfile, flags,
sock->sk->sk_prot_creator->name);
if (unlikely(newfd < 0)) {
err = newfd;
sock_release(newsock);
Expand Down

0 comments on commit 47d27a5

Please sign in to comment.