aboutsummaryrefslogtreecommitdiffstats
path: root/net/socket.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2010-12-09 12:17:25 -0500
committerThomas Gleixner <tglx@linutronix.de>2010-12-09 12:17:25 -0500
commitd834a9dcecae834cd6b2bc5e50e1907738d9cf6a (patch)
tree0589d753465d3fe359ba451ba6cb7798df03aaa2 /net/socket.c
parenta38c5380ef9f088be9f49b6e4c5d80af8b1b5cd4 (diff)
parentf658bcfb2607bf0808966a69cf74135ce98e5c2d (diff)
Merge branch 'x86/amd-nb' into x86/apic-cleanups
Reason: apic cleanup series depends on x86/apic, x86/amd-nb x86/platform Conflicts: arch/x86/include/asm/io_apic.h Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'net/socket.c')
-rw-r--r--net/socket.c58
1 files changed, 36 insertions, 22 deletions
diff --git a/net/socket.c b/net/socket.c
index 2270b941bcc7..3ca2fd9e3720 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -209,8 +209,8 @@ int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr *kaddr)
209 * specified. Zero is returned for a success. 209 * specified. Zero is returned for a success.
210 */ 210 */
211 211
212int move_addr_to_user(struct sockaddr *kaddr, int klen, void __user *uaddr, 212static int move_addr_to_user(struct sockaddr *kaddr, int klen,
213 int __user *ulen) 213 void __user *uaddr, int __user *ulen)
214{ 214{
215 int err; 215 int err;
216 int len; 216 int len;
@@ -305,19 +305,17 @@ static const struct super_operations sockfs_ops = {
305 .statfs = simple_statfs, 305 .statfs = simple_statfs,
306}; 306};
307 307
308static int sockfs_get_sb(struct file_system_type *fs_type, 308static struct dentry *sockfs_mount(struct file_system_type *fs_type,
309 int flags, const char *dev_name, void *data, 309 int flags, const char *dev_name, void *data)
310 struct vfsmount *mnt)
311{ 310{
312 return get_sb_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC, 311 return mount_pseudo(fs_type, "socket:", &sockfs_ops, SOCKFS_MAGIC);
313 mnt);
314} 312}
315 313
316static struct vfsmount *sock_mnt __read_mostly; 314static struct vfsmount *sock_mnt __read_mostly;
317 315
318static struct file_system_type sock_fs_type = { 316static struct file_system_type sock_fs_type = {
319 .name = "sockfs", 317 .name = "sockfs",
320 .get_sb = sockfs_get_sb, 318 .mount = sockfs_mount,
321 .kill_sb = kill_anon_super, 319 .kill_sb = kill_anon_super,
322}; 320};
323 321
@@ -377,7 +375,7 @@ static int sock_alloc_file(struct socket *sock, struct file **f, int flags)
377 &socket_file_ops); 375 &socket_file_ops);
378 if (unlikely(!file)) { 376 if (unlikely(!file)) {
379 /* drop dentry, keep inode */ 377 /* drop dentry, keep inode */
380 atomic_inc(&path.dentry->d_inode->i_count); 378 ihold(path.dentry->d_inode);
381 path_put(&path); 379 path_put(&path);
382 put_unused_fd(fd); 380 put_unused_fd(fd);
383 return -ENFILE; 381 return -ENFILE;
@@ -480,6 +478,7 @@ static struct socket *sock_alloc(void)
480 sock = SOCKET_I(inode); 478 sock = SOCKET_I(inode);
481 479
482 kmemcheck_annotate_bitfield(sock, type); 480 kmemcheck_annotate_bitfield(sock, type);
481 inode->i_ino = get_next_ino();
483 inode->i_mode = S_IFSOCK | S_IRWXUGO; 482 inode->i_mode = S_IFSOCK | S_IRWXUGO;
484 inode->i_uid = current_fsuid(); 483 inode->i_uid = current_fsuid();
485 inode->i_gid = current_fsgid(); 484 inode->i_gid = current_fsgid();
@@ -502,6 +501,7 @@ static int sock_no_open(struct inode *irrelevant, struct file *dontcare)
502const struct file_operations bad_sock_fops = { 501const struct file_operations bad_sock_fops = {
503 .owner = THIS_MODULE, 502 .owner = THIS_MODULE,
504 .open = sock_no_open, 503 .open = sock_no_open,
504 .llseek = noop_llseek,
505}; 505};
506 506
507/** 507/**
@@ -535,14 +535,13 @@ void sock_release(struct socket *sock)
535} 535}
536EXPORT_SYMBOL(sock_release); 536EXPORT_SYMBOL(sock_release);
537 537
538int sock_tx_timestamp(struct msghdr *msg, struct sock *sk, 538int sock_tx_timestamp(struct sock *sk, __u8 *tx_flags)
539 union skb_shared_tx *shtx)
540{ 539{
541 shtx->flags = 0; 540 *tx_flags = 0;
542 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE)) 541 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_HARDWARE))
543 shtx->hardware = 1; 542 *tx_flags |= SKBTX_HW_TSTAMP;
544 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE)) 543 if (sock_flag(sk, SOCK_TIMESTAMPING_TX_SOFTWARE))
545 shtx->software = 1; 544 *tx_flags |= SKBTX_SW_TSTAMP;
546 return 0; 545 return 0;
547} 546}
548EXPORT_SYMBOL(sock_tx_timestamp); 547EXPORT_SYMBOL(sock_tx_timestamp);
@@ -662,7 +661,8 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk,
662} 661}
663EXPORT_SYMBOL_GPL(__sock_recv_timestamp); 662EXPORT_SYMBOL_GPL(__sock_recv_timestamp);
664 663
665inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) 664static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk,
665 struct sk_buff *skb)
666{ 666{
667 if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount) 667 if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && skb->dropcount)
668 put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, 668 put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL,
@@ -1144,7 +1144,7 @@ call_kill:
1144} 1144}
1145EXPORT_SYMBOL(sock_wake_async); 1145EXPORT_SYMBOL(sock_wake_async);
1146 1146
1147static int __sock_create(struct net *net, int family, int type, int protocol, 1147int __sock_create(struct net *net, int family, int type, int protocol,
1148 struct socket **res, int kern) 1148 struct socket **res, int kern)
1149{ 1149{
1150 int err; 1150 int err;
@@ -1256,6 +1256,7 @@ out_release:
1256 rcu_read_unlock(); 1256 rcu_read_unlock();
1257 goto out_sock_release; 1257 goto out_sock_release;
1258} 1258}
1259EXPORT_SYMBOL(__sock_create);
1259 1260
1260int sock_create(int family, int type, int protocol, struct socket **res) 1261int sock_create(int family, int type, int protocol, struct socket **res)
1261{ 1262{
@@ -1651,6 +1652,8 @@ SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len,
1651 struct iovec iov; 1652 struct iovec iov;
1652 int fput_needed; 1653 int fput_needed;
1653 1654
1655 if (len > INT_MAX)
1656 len = INT_MAX;
1654 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1657 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1655 if (!sock) 1658 if (!sock)
1656 goto out; 1659 goto out;
@@ -1708,6 +1711,8 @@ SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size,
1708 int err, err2; 1711 int err, err2;
1709 int fput_needed; 1712 int fput_needed;
1710 1713
1714 if (size > INT_MAX)
1715 size = INT_MAX;
1711 sock = sockfd_lookup_light(fd, &err, &fput_needed); 1716 sock = sockfd_lookup_light(fd, &err, &fput_needed);
1712 if (!sock) 1717 if (!sock)
1713 goto out; 1718 goto out;
@@ -1919,7 +1924,8 @@ SYSCALL_DEFINE3(sendmsg, int, fd, struct msghdr __user *, msg, unsigned, flags)
1919 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted 1924 * Afterwards, it will be a kernel pointer. Thus the compiler-assisted
1920 * checking falls down on this. 1925 * checking falls down on this.
1921 */ 1926 */
1922 if (copy_from_user(ctl_buf, (void __user *)msg_sys.msg_control, 1927 if (copy_from_user(ctl_buf,
1928 (void __user __force *)msg_sys.msg_control,
1923 ctl_len)) 1929 ctl_len))
1924 goto out_freectl; 1930 goto out_freectl;
1925 msg_sys.msg_control = ctl_buf; 1931 msg_sys.msg_control = ctl_buf;
@@ -3054,14 +3060,19 @@ int kernel_getsockopt(struct socket *sock, int level, int optname,
3054 char *optval, int *optlen) 3060 char *optval, int *optlen)
3055{ 3061{
3056 mm_segment_t oldfs = get_fs(); 3062 mm_segment_t oldfs = get_fs();
3063 char __user *uoptval;
3064 int __user *uoptlen;
3057 int err; 3065 int err;
3058 3066
3067 uoptval = (char __user __force *) optval;
3068 uoptlen = (int __user __force *) optlen;
3069
3059 set_fs(KERNEL_DS); 3070 set_fs(KERNEL_DS);
3060 if (level == SOL_SOCKET) 3071 if (level == SOL_SOCKET)
3061 err = sock_getsockopt(sock, level, optname, optval, optlen); 3072 err = sock_getsockopt(sock, level, optname, uoptval, uoptlen);
3062 else 3073 else
3063 err = sock->ops->getsockopt(sock, level, optname, optval, 3074 err = sock->ops->getsockopt(sock, level, optname, uoptval,
3064 optlen); 3075 uoptlen);
3065 set_fs(oldfs); 3076 set_fs(oldfs);
3066 return err; 3077 return err;
3067} 3078}
@@ -3071,13 +3082,16 @@ int kernel_setsockopt(struct socket *sock, int level, int optname,
3071 char *optval, unsigned int optlen) 3082 char *optval, unsigned int optlen)
3072{ 3083{
3073 mm_segment_t oldfs = get_fs(); 3084 mm_segment_t oldfs = get_fs();
3085 char __user *uoptval;
3074 int err; 3086 int err;
3075 3087
3088 uoptval = (char __user __force *) optval;
3089
3076 set_fs(KERNEL_DS); 3090 set_fs(KERNEL_DS);
3077 if (level == SOL_SOCKET) 3091 if (level == SOL_SOCKET)
3078 err = sock_setsockopt(sock, level, optname, optval, optlen); 3092 err = sock_setsockopt(sock, level, optname, uoptval, optlen);
3079 else 3093 else
3080 err = sock->ops->setsockopt(sock, level, optname, optval, 3094 err = sock->ops->setsockopt(sock, level, optname, uoptval,
3081 optlen); 3095 optlen);
3082 set_fs(oldfs); 3096 set_fs(oldfs);
3083 return err; 3097 return err;