Blame view
net/socket.c
84.4 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 3 4 5 6 |
/* * NET An implementation of the SOCKET network access protocol. * * Version: @(#)socket.c 1.1.93 18/02/95 * * Authors: Orest Zborowski, <obz@Kodak.COM> |
02c30a84e [PATCH] update Ro... |
7 |
* Ross Biro |
1da177e4c Linux-2.6.12-rc2 |
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
* Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG> * * Fixes: * Anonymous : NOTSOCK/BADF cleanup. Error fix in * shutdown() * Alan Cox : verify_area() fixes * Alan Cox : Removed DDI * Jonathan Kamens : SOCK_DGRAM reconnect bug * Alan Cox : Moved a load of checks to the very * top level. * Alan Cox : Move address structures to/from user * mode above the protocol layers. * Rob Janssen : Allow 0 length sends. * Alan Cox : Asynchronous I/O support (cribbed from the * tty drivers). * Niibe Yutaka : Asynchronous I/O for writes (4.4BSD style) * Jeff Uphoff : Made max number of sockets command-line * configurable. * Matti Aarnio : Made the number of sockets dynamic, * to be allocated when needed, and mr. * Uphoff's max is used as max to be * allowed to allocate. * Linus : Argh. removed all the socket allocation * altogether: it's in the inode now. * Alan Cox : Made sock_alloc()/sock_release() public * for NetROM and future kernel nfsd type * stuff. * Alan Cox : sendmsg/recvmsg basics. * Tom Dyas : Export net symbols. * Marcin Dalecki : Fixed problems with CONFIG_NET="n". * Alan Cox : Added thread locking to sys_* calls * for sockets. May have errors at the * moment. * Kevin Buhr : Fixed the dumb errors in the above. * Andi Kleen : Some small cleanups, optimizations, * and fixed a copy_from_user() bug. * Tigran Aivazian : sys_send(args) calls sys_sendto(args, NULL, 0) |
89bddce58 [NET] socket: cod... |
45 |
* Tigran Aivazian : Made listen(2) backlog sanity checks |
1da177e4c Linux-2.6.12-rc2 |
46 47 48 49 50 51 52 53 54 55 |
* protocol-independent * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * * * This module is effectively the top level interface to the BSD socket |
89bddce58 [NET] socket: cod... |
56 |
* paradigm. |
1da177e4c Linux-2.6.12-rc2 |
57 58 59 |
* * Based upon Swansea University Computer Society NET3.039 */ |
1da177e4c Linux-2.6.12-rc2 |
60 |
#include <linux/mm.h> |
1da177e4c Linux-2.6.12-rc2 |
61 62 63 64 |
#include <linux/socket.h> #include <linux/file.h> #include <linux/net.h> #include <linux/interrupt.h> |
aaca0bdca flag parameters: ... |
65 |
#include <linux/thread_info.h> |
55737fda0 [NET]: socket fam... |
66 |
#include <linux/rcupdate.h> |
1da177e4c Linux-2.6.12-rc2 |
67 68 69 |
#include <linux/netdevice.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> |
4a3e2f711 [NET] sem2mutex: ... |
70 |
#include <linux/mutex.h> |
1da177e4c Linux-2.6.12-rc2 |
71 |
#include <linux/if_bridge.h> |
20380731b [NET]: Fix sparse... |
72 73 |
#include <linux/if_frad.h> #include <linux/if_vlan.h> |
408eccce3 net: ptp: move PT... |
74 |
#include <linux/ptp_classify.h> |
1da177e4c Linux-2.6.12-rc2 |
75 76 77 78 79 |
#include <linux/init.h> #include <linux/poll.h> #include <linux/cache.h> #include <linux/module.h> #include <linux/highmem.h> |
1da177e4c Linux-2.6.12-rc2 |
80 81 82 83 84 |
#include <linux/mount.h> #include <linux/security.h> #include <linux/syscalls.h> #include <linux/compat.h> #include <linux/kmod.h> |
3ec3b2fba AUDIT: Capture sy... |
85 |
#include <linux/audit.h> |
d86b5e0e6 [PATCH] net/: fix... |
86 |
#include <linux/wireless.h> |
1b8d7ae42 [NET]: Make socke... |
87 |
#include <linux/nsproxy.h> |
1fd7317d0 Move magic number... |
88 |
#include <linux/magic.h> |
5a0e3ad6a include cleanup: ... |
89 |
#include <linux/slab.h> |
600e17792 net: Providing pr... |
90 |
#include <linux/xattr.h> |
1da177e4c Linux-2.6.12-rc2 |
91 |
|
7c0f6ba68 Replace <asm/uacc... |
92 |
#include <linux/uaccess.h> |
1da177e4c Linux-2.6.12-rc2 |
93 94 95 |
#include <asm/unistd.h> #include <net/compat.h> |
87de87d5e wext: Dispatch an... |
96 |
#include <net/wext.h> |
f84517253 cls_cgroup: Store... |
97 |
#include <net/cls_cgroup.h> |
1da177e4c Linux-2.6.12-rc2 |
98 99 100 |
#include <net/sock.h> #include <linux/netfilter.h> |
6b96018b2 compat: move sock... |
101 102 103 |
#include <linux/if_tun.h> #include <linux/ipv6_route.h> #include <linux/route.h> |
6b96018b2 compat: move sock... |
104 |
#include <linux/sockios.h> |
076bb0c82 net: rename inclu... |
105 |
#include <net/busy_poll.h> |
f24b9be59 net-timestamp: ex... |
106 |
#include <linux/errqueue.h> |
060212928 net: add low late... |
107 |
|
e0d1095ae net: rename CONFI... |
108 |
#ifdef CONFIG_NET_RX_BUSY_POLL |
64b0dc517 net: rename busy ... |
109 110 |
unsigned int sysctl_net_busy_read __read_mostly; unsigned int sysctl_net_busy_poll __read_mostly; |
060212928 net: add low late... |
111 |
#endif |
6b96018b2 compat: move sock... |
112 |
|
8ae5e030f net: switch socke... |
113 114 |
static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to); static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from); |
89bddce58 [NET] socket: cod... |
115 |
static int sock_mmap(struct file *file, struct vm_area_struct *vma); |
1da177e4c Linux-2.6.12-rc2 |
116 117 |
static int sock_close(struct inode *inode, struct file *file); |
152524231 net: add support ... |
118 119 120 121 |
static struct wait_queue_head *sock_get_poll_head(struct file *file, __poll_t events); static __poll_t sock_poll_mask(struct file *file, __poll_t); static __poll_t sock_poll(struct file *file, struct poll_table_struct *wait); |
89bddce58 [NET] socket: cod... |
122 |
static long sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg); |
89bbfc95d [NET]: allow 32 b... |
123 124 |
#ifdef CONFIG_COMPAT static long compat_sock_ioctl(struct file *file, |
89bddce58 [NET] socket: cod... |
125 |
unsigned int cmd, unsigned long arg); |
89bbfc95d [NET]: allow 32 b... |
126 |
#endif |
1da177e4c Linux-2.6.12-rc2 |
127 |
static int sock_fasync(int fd, struct file *filp, int on); |
1da177e4c Linux-2.6.12-rc2 |
128 129 |
static ssize_t sock_sendpage(struct file *file, struct page *page, int offset, size_t size, loff_t *ppos, int more); |
9c55e01c0 [TCP]: Splice rec... |
130 |
static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |
c6d409cfd From abbffa2aa9bd... |
131 |
struct pipe_inode_info *pipe, size_t len, |
9c55e01c0 [TCP]: Splice rec... |
132 |
unsigned int flags); |
1da177e4c Linux-2.6.12-rc2 |
133 |
|
1da177e4c Linux-2.6.12-rc2 |
134 135 136 137 |
/* * Socket files have a set of 'special' operations as well as the generic file ones. These don't appear * in the operation structures but are done directly via the socketcall() multiplexor. */ |
da7071d7e [PATCH] mark stru... |
138 |
static const struct file_operations socket_file_ops = { |
1da177e4c Linux-2.6.12-rc2 |
139 140 |
.owner = THIS_MODULE, .llseek = no_llseek, |
8ae5e030f net: switch socke... |
141 142 |
.read_iter = sock_read_iter, .write_iter = sock_write_iter, |
152524231 net: add support ... |
143 144 |
.get_poll_head = sock_get_poll_head, .poll_mask = sock_poll_mask, |
1da177e4c Linux-2.6.12-rc2 |
145 146 |
.poll = sock_poll, .unlocked_ioctl = sock_ioctl, |
89bbfc95d [NET]: allow 32 b... |
147 148 149 |
#ifdef CONFIG_COMPAT .compat_ioctl = compat_sock_ioctl, #endif |
1da177e4c Linux-2.6.12-rc2 |
150 |
.mmap = sock_mmap, |
1da177e4c Linux-2.6.12-rc2 |
151 152 |
.release = sock_close, .fasync = sock_fasync, |
5274f052e [PATCH] Introduce... |
153 154 |
.sendpage = sock_sendpage, .splice_write = generic_splice_sendpage, |
9c55e01c0 [TCP]: Splice rec... |
155 |
.splice_read = sock_splice_read, |
1da177e4c Linux-2.6.12-rc2 |
156 157 158 159 160 |
}; /* * The protocol list. Each protocol is registered in here. */ |
1da177e4c Linux-2.6.12-rc2 |
161 |
static DEFINE_SPINLOCK(net_family_lock); |
190683a9d net: net_families... |
162 |
static const struct net_proto_family __rcu *net_families[NPROTO] __read_mostly; |
1da177e4c Linux-2.6.12-rc2 |
163 |
|
1da177e4c Linux-2.6.12-rc2 |
164 |
/* |
89bddce58 [NET] socket: cod... |
165 166 167 |
* Support routines. * Move socket addresses back and forth across the kernel/user * divide and look after the messy bits. |
1da177e4c Linux-2.6.12-rc2 |
168 |
*/ |
1da177e4c Linux-2.6.12-rc2 |
169 170 171 172 173 174 175 176 177 178 |
/** * move_addr_to_kernel - copy a socket address into kernel space * @uaddr: Address in user space * @kaddr: Address in kernel space * @ulen: Length in user space * * The address is copied into kernel space. If the provided address is * too long an error code of -EINVAL is returned. If the copy gives * invalid addresses -EFAULT is returned. On a success 0 is returned. */ |
43db362d3 net: get rid of s... |
179 |
int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr) |
1da177e4c Linux-2.6.12-rc2 |
180 |
{ |
230b18392 net: Use standard... |
181 |
if (ulen < 0 || ulen > sizeof(struct sockaddr_storage)) |
1da177e4c Linux-2.6.12-rc2 |
182 |
return -EINVAL; |
89bddce58 [NET] socket: cod... |
183 |
if (ulen == 0) |
1da177e4c Linux-2.6.12-rc2 |
184 |
return 0; |
89bddce58 [NET] socket: cod... |
185 |
if (copy_from_user(kaddr, uaddr, ulen)) |
1da177e4c Linux-2.6.12-rc2 |
186 |
return -EFAULT; |
3ec3b2fba AUDIT: Capture sy... |
187 |
return audit_sockaddr(ulen, kaddr); |
1da177e4c Linux-2.6.12-rc2 |
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
} /** * move_addr_to_user - copy an address to user space * @kaddr: kernel space address * @klen: length of address in kernel * @uaddr: user space address * @ulen: pointer to user length field * * The value pointed to by ulen on entry is the buffer length available. * This is overwritten with the buffer space used. -EINVAL is returned * if an overlong buffer is specified or a negative buffer size. -EFAULT * is returned if either the buffer or the length field are not * accessible. * After copying the data up to the limit the user specifies, the true * length of the data is written over the length limit the user * specified. Zero is returned for a success. */ |
89bddce58 [NET] socket: cod... |
206 |
|
43db362d3 net: get rid of s... |
207 |
static int move_addr_to_user(struct sockaddr_storage *kaddr, int klen, |
11165f145 socket: localize ... |
208 |
void __user *uaddr, int __user *ulen) |
1da177e4c Linux-2.6.12-rc2 |
209 210 211 |
{ int err; int len; |
68c6beb37 net: add BUG_ON i... |
212 |
BUG_ON(klen > sizeof(struct sockaddr_storage)); |
89bddce58 [NET] socket: cod... |
213 214 |
err = get_user(len, ulen); if (err) |
1da177e4c Linux-2.6.12-rc2 |
215 |
return err; |
89bddce58 [NET] socket: cod... |
216 217 |
if (len > klen) len = klen; |
68c6beb37 net: add BUG_ON i... |
218 |
if (len < 0) |
1da177e4c Linux-2.6.12-rc2 |
219 |
return -EINVAL; |
89bddce58 [NET] socket: cod... |
220 |
if (len) { |
d6fe3945b [PATCH] sockaddr ... |
221 222 |
if (audit_sockaddr(klen, kaddr)) return -ENOMEM; |
89bddce58 [NET] socket: cod... |
223 |
if (copy_to_user(uaddr, kaddr, len)) |
1da177e4c Linux-2.6.12-rc2 |
224 225 226 |
return -EFAULT; } /* |
89bddce58 [NET] socket: cod... |
227 228 |
* "fromlen shall refer to the value before truncation.." * 1003.1g |
1da177e4c Linux-2.6.12-rc2 |
229 230 231 |
*/ return __put_user(klen, ulen); } |
08009a760 net: make kmem ca... |
232 |
static struct kmem_cache *sock_inode_cachep __ro_after_init; |
1da177e4c Linux-2.6.12-rc2 |
233 234 235 236 |
static struct inode *sock_alloc_inode(struct super_block *sb) { struct socket_alloc *ei; |
eaefd1105 net: add __rcu an... |
237 |
struct socket_wq *wq; |
89bddce58 [NET] socket: cod... |
238 |
|
e94b17660 [PATCH] slab: rem... |
239 |
ei = kmem_cache_alloc(sock_inode_cachep, GFP_KERNEL); |
1da177e4c Linux-2.6.12-rc2 |
240 241 |
if (!ei) return NULL; |
eaefd1105 net: add __rcu an... |
242 243 |
wq = kmalloc(sizeof(*wq), GFP_KERNEL); if (!wq) { |
438154823 net: sock_def_rea... |
244 245 246 |
kmem_cache_free(sock_inode_cachep, ei); return NULL; } |
eaefd1105 net: add __rcu an... |
247 248 |
init_waitqueue_head(&wq->wait); wq->fasync_list = NULL; |
574aab1e0 net, socket, sock... |
249 |
wq->flags = 0; |
eaefd1105 net: add __rcu an... |
250 |
RCU_INIT_POINTER(ei->socket.wq, wq); |
89bddce58 [NET] socket: cod... |
251 |
|
1da177e4c Linux-2.6.12-rc2 |
252 253 254 255 256 |
ei->socket.state = SS_UNCONNECTED; ei->socket.flags = 0; ei->socket.ops = NULL; ei->socket.sk = NULL; ei->socket.file = NULL; |
1da177e4c Linux-2.6.12-rc2 |
257 258 259 260 261 262 |
return &ei->vfs_inode; } static void sock_destroy_inode(struct inode *inode) { |
438154823 net: sock_def_rea... |
263 |
struct socket_alloc *ei; |
eaefd1105 net: add __rcu an... |
264 |
struct socket_wq *wq; |
438154823 net: sock_def_rea... |
265 266 |
ei = container_of(inode, struct socket_alloc, vfs_inode); |
eaefd1105 net: add __rcu an... |
267 |
wq = rcu_dereference_protected(ei->socket.wq, 1); |
618452202 net,rcu: convert ... |
268 |
kfree_rcu(wq, rcu); |
438154823 net: sock_def_rea... |
269 |
kmem_cache_free(sock_inode_cachep, ei); |
1da177e4c Linux-2.6.12-rc2 |
270 |
} |
51cc50685 SL*B: drop kmem c... |
271 |
static void init_once(void *foo) |
1da177e4c Linux-2.6.12-rc2 |
272 |
{ |
89bddce58 [NET] socket: cod... |
273 |
struct socket_alloc *ei = (struct socket_alloc *)foo; |
1da177e4c Linux-2.6.12-rc2 |
274 |
|
a35afb830 Remove SLAB_CTOR_... |
275 |
inode_init_once(&ei->vfs_inode); |
1da177e4c Linux-2.6.12-rc2 |
276 |
} |
89bddce58 [NET] socket: cod... |
277 |
|
1e9116327 net: change init_... |
278 |
static void init_inodecache(void) |
1da177e4c Linux-2.6.12-rc2 |
279 280 |
{ sock_inode_cachep = kmem_cache_create("sock_inode_cache", |
89bddce58 [NET] socket: cod... |
281 282 283 284 |
sizeof(struct socket_alloc), 0, (SLAB_HWCACHE_ALIGN | SLAB_RECLAIM_ACCOUNT | |
5d097056c kmemcg: account c... |
285 |
SLAB_MEM_SPREAD | SLAB_ACCOUNT), |
20c2df83d mm: Remove slab d... |
286 |
init_once); |
1e9116327 net: change init_... |
287 |
BUG_ON(sock_inode_cachep == NULL); |
1da177e4c Linux-2.6.12-rc2 |
288 |
} |
b87221de6 const: mark remai... |
289 |
static const struct super_operations sockfs_ops = { |
c6d409cfd From abbffa2aa9bd... |
290 291 292 |
.alloc_inode = sock_alloc_inode, .destroy_inode = sock_destroy_inode, .statfs = simple_statfs, |
1da177e4c Linux-2.6.12-rc2 |
293 |
}; |
c23fbb6bc VFS: delay the de... |
294 295 296 297 298 299 |
/* * sockfs_dname() is called from d_path(). */ static char *sockfs_dname(struct dentry *dentry, char *buffer, int buflen) { return dynamic_dname(dentry, buffer, buflen, "socket:[%lu]", |
c5ef60352 VFS: net/: d_inod... |
300 |
d_inode(dentry)->i_ino); |
c23fbb6bc VFS: delay the de... |
301 |
} |
3ba13d179 constify dentry_o... |
302 |
static const struct dentry_operations sockfs_dentry_operations = { |
c23fbb6bc VFS: delay the de... |
303 |
.d_dname = sockfs_dname, |
1da177e4c Linux-2.6.12-rc2 |
304 |
}; |
bba0bd31b sockfs: Get rid o... |
305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 |
static int sockfs_xattr_get(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *suffix, void *value, size_t size) { if (value) { if (dentry->d_name.len + 1 > size) return -ERANGE; memcpy(value, dentry->d_name.name, dentry->d_name.len + 1); } return dentry->d_name.len + 1; } #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 const struct xattr_handler sockfs_xattr_handler = { .name = XATTR_NAME_SOCKPROTONAME, .get = sockfs_xattr_get, }; |
4a5901537 xattr: Fix settin... |
325 326 327 328 329 330 331 332 333 334 335 336 337 |
static int sockfs_security_xattr_set(const struct xattr_handler *handler, struct dentry *dentry, struct inode *inode, const char *suffix, const void *value, size_t size, int flags) { /* Handled by LSM. */ return -EAGAIN; } static const struct xattr_handler sockfs_security_xattr_handler = { .prefix = XATTR_SECURITY_PREFIX, .set = sockfs_security_xattr_set, }; |
bba0bd31b sockfs: Get rid o... |
338 339 |
static const struct xattr_handler *sockfs_xattr_handlers[] = { &sockfs_xattr_handler, |
4a5901537 xattr: Fix settin... |
340 |
&sockfs_security_xattr_handler, |
bba0bd31b sockfs: Get rid o... |
341 342 |
NULL }; |
c74a1cbb3 pass default dent... |
343 344 345 |
static struct dentry *sockfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { |
bba0bd31b sockfs: Get rid o... |
346 347 348 |
return mount_pseudo_xattr(fs_type, "socket:", &sockfs_ops, sockfs_xattr_handlers, &sockfs_dentry_operations, SOCKFS_MAGIC); |
c74a1cbb3 pass default dent... |
349 350 351 352 353 354 355 356 357 |
} static struct vfsmount *sock_mnt __read_mostly; static struct file_system_type sock_fs_type = { .name = "sockfs", .mount = sockfs_mount, .kill_sb = kill_anon_super, }; |
1da177e4c Linux-2.6.12-rc2 |
358 359 360 |
/* * Obtains the first available file descriptor and sets it up for use. * |
39d8c1b6f [NET]: Do not los... |
361 362 |
* These functions create file structures and maps them to fd space * of the current process. On success it returns file descriptor |
1da177e4c Linux-2.6.12-rc2 |
363 364 365 366 367 368 369 370 371 372 373 |
* and file struct implicitly stored in sock->file. * Note that another thread may close file descriptor before we return * from this function. We use the fact that now we do not refer * to socket after mapping. If one day we will need it, this * function will increment ref. count on file by 1. * * In any case returned fd MAY BE not valid! * This race condition is unavoidable * with shared fd spaces, we cannot solve it inside kernel, * but we take care of internal coherence yet. */ |
aab174f0d Merge branch 'for... |
374 |
struct file *sock_alloc_file(struct socket *sock, int flags, const char *dname) |
1da177e4c Linux-2.6.12-rc2 |
375 |
{ |
7cbe66b6b merge sock_alloc_... |
376 |
struct qstr name = { .name = "" }; |
2c48b9c45 switch alloc_file... |
377 |
struct path path; |
7cbe66b6b merge sock_alloc_... |
378 |
struct file *file; |
1da177e4c Linux-2.6.12-rc2 |
379 |
|
600e17792 net: Providing pr... |
380 381 382 383 384 385 386 |
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); } |
4b936885a fs: improve scala... |
387 |
path.dentry = d_alloc_pseudo(sock_mnt->mnt_sb, &name); |
8e1611e23 make sock_alloc_f... |
388 389 |
if (unlikely(!path.dentry)) { sock_release(sock); |
284076305 take descriptor h... |
390 |
return ERR_PTR(-ENOMEM); |
8e1611e23 make sock_alloc_f... |
391 |
} |
2c48b9c45 switch alloc_file... |
392 |
path.mnt = mntget(sock_mnt); |
39d8c1b6f [NET]: Do not los... |
393 |
|
2c48b9c45 switch alloc_file... |
394 |
d_instantiate(path.dentry, SOCK_INODE(sock)); |
39d8c1b6f [NET]: Do not los... |
395 |
|
c9c554f21 alloc_file(): swi... |
396 |
file = alloc_file(&path, O_RDWR | (flags & O_NONBLOCK), |
ce8d2cdf3 r/o bind mounts: ... |
397 |
&socket_file_ops); |
b5ffe6344 net: Drop unlikel... |
398 |
if (IS_ERR(file)) { |
8e1611e23 make sock_alloc_f... |
399 |
/* drop dentry, keep inode for a bit */ |
c5ef60352 VFS: net/: d_inod... |
400 |
ihold(d_inode(path.dentry)); |
2c48b9c45 switch alloc_file... |
401 |
path_put(&path); |
8e1611e23 make sock_alloc_f... |
402 403 |
/* ... and now kill it properly */ sock_release(sock); |
39b652527 fs: Preserve erro... |
404 |
return file; |
cc3808f8c switch sock_alloc... |
405 406 407 |
} sock->file = file; |
39d8c1b6f [NET]: Do not los... |
408 |
file->private_data = sock; |
284076305 take descriptor h... |
409 |
return file; |
39d8c1b6f [NET]: Do not los... |
410 |
} |
56b31d1c9 unexport sock_map... |
411 |
EXPORT_SYMBOL(sock_alloc_file); |
39d8c1b6f [NET]: Do not los... |
412 |
|
56b31d1c9 unexport sock_map... |
413 |
static int sock_map_fd(struct socket *sock, int flags) |
39d8c1b6f [NET]: Do not los... |
414 415 |
{ struct file *newfile; |
284076305 take descriptor h... |
416 |
int fd = get_unused_fd_flags(flags); |
ce4bb04ca Fix a leak in soc... |
417 418 |
if (unlikely(fd < 0)) { sock_release(sock); |
284076305 take descriptor h... |
419 |
return fd; |
ce4bb04ca Fix a leak in soc... |
420 |
} |
39d8c1b6f [NET]: Do not los... |
421 |
|
aab174f0d Merge branch 'for... |
422 |
newfile = sock_alloc_file(sock, flags, NULL); |
284076305 take descriptor h... |
423 |
if (likely(!IS_ERR(newfile))) { |
39d8c1b6f [NET]: Do not los... |
424 |
fd_install(fd, newfile); |
284076305 take descriptor h... |
425 426 |
return fd; } |
7cbe66b6b merge sock_alloc_... |
427 |
|
284076305 take descriptor h... |
428 429 |
put_unused_fd(fd); return PTR_ERR(newfile); |
1da177e4c Linux-2.6.12-rc2 |
430 |
} |
406a3c638 net: netprio_cgro... |
431 |
struct socket *sock_from_file(struct file *file, int *err) |
6cb153cab [NET]: use fget_l... |
432 |
{ |
6cb153cab [NET]: use fget_l... |
433 434 |
if (file->f_op == &socket_file_ops) return file->private_data; /* set in sock_map_fd */ |
23bb80d21 [NET]: cleanup so... |
435 436 |
*err = -ENOTSOCK; return NULL; |
6cb153cab [NET]: use fget_l... |
437 |
} |
406a3c638 net: netprio_cgro... |
438 |
EXPORT_SYMBOL(sock_from_file); |
6cb153cab [NET]: use fget_l... |
439 |
|
1da177e4c Linux-2.6.12-rc2 |
440 |
/** |
c6d409cfd From abbffa2aa9bd... |
441 |
* sockfd_lookup - Go from a file number to its socket slot |
1da177e4c Linux-2.6.12-rc2 |
442 443 444 445 |
* @fd: file handle * @err: pointer to an error code return * * The file handle passed in is locked and the socket it is bound |
241c4667f net: socket: fix ... |
446 |
* to is returned. If an error occurs the err pointer is overwritten |
1da177e4c Linux-2.6.12-rc2 |
447 448 449 450 451 452 453 454 455 |
* with a negative errno code and NULL is returned. The function checks * for both invalid handles and passing a handle which is not a socket. * * On a success the socket object pointer is returned. */ struct socket *sockfd_lookup(int fd, int *err) { struct file *file; |
1da177e4c Linux-2.6.12-rc2 |
456 |
struct socket *sock; |
89bddce58 [NET] socket: cod... |
457 458 |
file = fget(fd); if (!file) { |
1da177e4c Linux-2.6.12-rc2 |
459 460 461 |
*err = -EBADF; return NULL; } |
89bddce58 [NET] socket: cod... |
462 |
|
6cb153cab [NET]: use fget_l... |
463 464 |
sock = sock_from_file(file, err); if (!sock) |
1da177e4c Linux-2.6.12-rc2 |
465 |
fput(file); |
6cb153cab [NET]: use fget_l... |
466 467 |
return sock; } |
c6d409cfd From abbffa2aa9bd... |
468 |
EXPORT_SYMBOL(sockfd_lookup); |
1da177e4c Linux-2.6.12-rc2 |
469 |
|
6cb153cab [NET]: use fget_l... |
470 471 |
static struct socket *sockfd_lookup_light(int fd, int *err, int *fput_needed) { |
00e188ef6 sockfd_lookup_lig... |
472 |
struct fd f = fdget(fd); |
6cb153cab [NET]: use fget_l... |
473 |
struct socket *sock; |
3672558c6 [NET]: sockfd_loo... |
474 |
*err = -EBADF; |
00e188ef6 sockfd_lookup_lig... |
475 476 477 478 |
if (f.file) { sock = sock_from_file(f.file, err); if (likely(sock)) { *fput_needed = f.flags; |
6cb153cab [NET]: use fget_l... |
479 |
return sock; |
00e188ef6 sockfd_lookup_lig... |
480 481 |
} fdput(f); |
1da177e4c Linux-2.6.12-rc2 |
482 |
} |
6cb153cab [NET]: use fget_l... |
483 |
return NULL; |
1da177e4c Linux-2.6.12-rc2 |
484 |
} |
600e17792 net: Providing pr... |
485 486 487 488 489 |
static ssize_t sockfs_listxattr(struct dentry *dentry, char *buffer, size_t size) { ssize_t len; ssize_t used = 0; |
c5ef60352 VFS: net/: d_inod... |
490 |
len = security_inode_listsecurity(d_inode(dentry), buffer, size); |
600e17792 net: Providing pr... |
491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
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; } |
dc647ec88 net: socket: Make... |
511 |
static int sockfs_setattr(struct dentry *dentry, struct iattr *iattr) |
86741ec25 net: core: Add a ... |
512 513 |
{ int err = simple_setattr(dentry, iattr); |
e1a3a60a2 net: socket: don'... |
514 |
if (!err && (iattr->ia_valid & ATTR_UID)) { |
86741ec25 net: core: Add a ... |
515 |
struct socket *sock = SOCKET_I(d_inode(dentry)); |
6d8c50dcb socket: close rac... |
516 517 518 519 |
if (sock->sk) sock->sk->sk_uid = iattr->ia_uid; else err = -ENOENT; |
86741ec25 net: core: Add a ... |
520 521 522 523 |
} return err; } |
600e17792 net: Providing pr... |
524 |
static const struct inode_operations sockfs_inode_ops = { |
600e17792 net: Providing pr... |
525 |
.listxattr = sockfs_listxattr, |
86741ec25 net: core: Add a ... |
526 |
.setattr = sockfs_setattr, |
600e17792 net: Providing pr... |
527 |
}; |
1da177e4c Linux-2.6.12-rc2 |
528 529 |
/** * sock_alloc - allocate a socket |
89bddce58 [NET] socket: cod... |
530 |
* |
1da177e4c Linux-2.6.12-rc2 |
531 532 533 534 |
* Allocate a new inode and socket object. The two are bound together * and initialised. The socket is then returned. If we are out of inodes * NULL is returned. */ |
f4a00aacd net: Make sock_al... |
535 |
struct socket *sock_alloc(void) |
1da177e4c Linux-2.6.12-rc2 |
536 |
{ |
89bddce58 [NET] socket: cod... |
537 538 |
struct inode *inode; struct socket *sock; |
1da177e4c Linux-2.6.12-rc2 |
539 |
|
a209dfc7b vfs: dont chain p... |
540 |
inode = new_inode_pseudo(sock_mnt->mnt_sb); |
1da177e4c Linux-2.6.12-rc2 |
541 542 543 544 |
if (!inode) return NULL; sock = SOCKET_I(inode); |
85fe4025c fs: do not assign... |
545 |
inode->i_ino = get_next_ino(); |
89bddce58 [NET] socket: cod... |
546 |
inode->i_mode = S_IFSOCK | S_IRWXUGO; |
8192b0c48 CRED: Wrap task c... |
547 548 |
inode->i_uid = current_fsuid(); inode->i_gid = current_fsgid(); |
600e17792 net: Providing pr... |
549 |
inode->i_op = &sockfs_inode_ops; |
1da177e4c Linux-2.6.12-rc2 |
550 |
|
1da177e4c Linux-2.6.12-rc2 |
551 552 |
return sock; } |
f4a00aacd net: Make sock_al... |
553 |
EXPORT_SYMBOL(sock_alloc); |
1da177e4c Linux-2.6.12-rc2 |
554 |
|
1da177e4c Linux-2.6.12-rc2 |
555 556 557 558 559 560 |
/** * sock_release - close a socket * @sock: socket to close * * The socket is released from the protocol stack if it has a release * callback, and the inode is then released if the socket is bound to |
89bddce58 [NET] socket: cod... |
561 |
* an inode not a file. |
1da177e4c Linux-2.6.12-rc2 |
562 |
*/ |
89bddce58 [NET] socket: cod... |
563 |
|
6d8c50dcb socket: close rac... |
564 |
static void __sock_release(struct socket *sock, struct inode *inode) |
1da177e4c Linux-2.6.12-rc2 |
565 566 567 |
{ if (sock->ops) { struct module *owner = sock->ops->owner; |
6d8c50dcb socket: close rac... |
568 569 |
if (inode) inode_lock(inode); |
1da177e4c Linux-2.6.12-rc2 |
570 |
sock->ops->release(sock); |
6d8c50dcb socket: close rac... |
571 572 |
if (inode) inode_unlock(inode); |
1da177e4c Linux-2.6.12-rc2 |
573 574 575 |
sock->ops = NULL; module_put(owner); } |
eaefd1105 net: add __rcu an... |
576 |
if (rcu_dereference_protected(sock->wq, 1)->fasync_list) |
3410f22ea socket: replace s... |
577 578 |
pr_err("%s: fasync list not empty! ", __func__); |
1da177e4c Linux-2.6.12-rc2 |
579 |
|
1da177e4c Linux-2.6.12-rc2 |
580 581 582 583 |
if (!sock->file) { iput(SOCK_INODE(sock)); return; } |
89bddce58 [NET] socket: cod... |
584 |
sock->file = NULL; |
1da177e4c Linux-2.6.12-rc2 |
585 |
} |
6d8c50dcb socket: close rac... |
586 587 588 589 590 |
void sock_release(struct socket *sock) { __sock_release(sock, NULL); } |
c6d409cfd From abbffa2aa9bd... |
591 |
EXPORT_SYMBOL(sock_release); |
1da177e4c Linux-2.6.12-rc2 |
592 |
|
c14ac9451 sock: enable time... |
593 |
void __sock_tx_timestamp(__u16 tsflags, __u8 *tx_flags) |
20d494735 net: socket infra... |
594 |
{ |
140c55d4b net-timestamp: so... |
595 |
u8 flags = *tx_flags; |
c14ac9451 sock: enable time... |
596 |
if (tsflags & SOF_TIMESTAMPING_TX_HARDWARE) |
140c55d4b net-timestamp: so... |
597 |
flags |= SKBTX_HW_TSTAMP; |
c14ac9451 sock: enable time... |
598 |
if (tsflags & SOF_TIMESTAMPING_TX_SOFTWARE) |
140c55d4b net-timestamp: so... |
599 |
flags |= SKBTX_SW_TSTAMP; |
c14ac9451 sock: enable time... |
600 |
if (tsflags & SOF_TIMESTAMPING_TX_SCHED) |
140c55d4b net-timestamp: so... |
601 |
flags |= SKBTX_SCHED_TSTAMP; |
140c55d4b net-timestamp: so... |
602 |
*tx_flags = flags; |
20d494735 net: socket infra... |
603 |
} |
67cc0d407 net-timestamp: op... |
604 |
EXPORT_SYMBOL(__sock_tx_timestamp); |
20d494735 net: socket infra... |
605 |
|
d8725c86a get rid of the si... |
606 |
static inline int sock_sendmsg_nosec(struct socket *sock, struct msghdr *msg) |
1da177e4c Linux-2.6.12-rc2 |
607 |
{ |
01e97e651 new helper: msg_d... |
608 |
int ret = sock->ops->sendmsg(sock, msg, msg_data_left(msg)); |
d8725c86a get rid of the si... |
609 610 |
BUG_ON(ret == -EIOCBQUEUED); return ret; |
1da177e4c Linux-2.6.12-rc2 |
611 |
} |
d8725c86a get rid of the si... |
612 |
int sock_sendmsg(struct socket *sock, struct msghdr *msg) |
228e548e6 net: Add sendmmsg... |
613 |
{ |
d8725c86a get rid of the si... |
614 |
int err = security_socket_sendmsg(sock, msg, |
01e97e651 new helper: msg_d... |
615 |
msg_data_left(msg)); |
228e548e6 net: Add sendmmsg... |
616 |
|
d8725c86a get rid of the si... |
617 |
return err ?: sock_sendmsg_nosec(sock, msg); |
0cf00c6f3 net/socket.c : in... |
618 |
} |
c6d409cfd From abbffa2aa9bd... |
619 |
EXPORT_SYMBOL(sock_sendmsg); |
1da177e4c Linux-2.6.12-rc2 |
620 621 622 623 |
int kernel_sendmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size) { |
6aa248145 switch kernel_sen... |
624 |
iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size); |
d8725c86a get rid of the si... |
625 |
return sock_sendmsg(sock, msg); |
1da177e4c Linux-2.6.12-rc2 |
626 |
} |
c6d409cfd From abbffa2aa9bd... |
627 |
EXPORT_SYMBOL(kernel_sendmsg); |
1da177e4c Linux-2.6.12-rc2 |
628 |
|
306b13eb3 proto_ops: Add lo... |
629 630 631 632 633 634 |
int kernel_sendmsg_locked(struct sock *sk, struct msghdr *msg, struct kvec *vec, size_t num, size_t size) { struct socket *sock = sk->sk_socket; if (!sock->ops->sendmsg_locked) |
db5980d80 net: fixes for sk... |
635 |
return sock_no_sendmsg_locked(sk, msg, size); |
306b13eb3 proto_ops: Add lo... |
636 637 638 639 640 641 |
iov_iter_kvec(&msg->msg_iter, WRITE | ITER_KVEC, vec, num, size); return sock->ops->sendmsg_locked(sk, msg, msg_data_left(msg)); } EXPORT_SYMBOL(kernel_sendmsg_locked); |
8605330aa tcp: fix SCM_TIME... |
642 643 644 645 646 647 648 649 650 |
static bool skb_is_err_queue(const struct sk_buff *skb) { /* pkt_type of skbs enqueued on the error queue are set to * PACKET_OUTGOING in skb_set_err_queue(). This is only safe to do * in recvmsg, since skbs received on a local socket will never * have a pkt_type of PACKET_OUTGOING. */ return skb->pkt_type == PACKET_OUTGOING; } |
b50a5c70f net: allow simult... |
651 652 653 654 655 656 657 658 659 660 661 662 |
/* On transmit, software and hardware timestamps are returned independently. * As the two skb clones share the hardware timestamp, which may be updated * before the software timestamp is received, a hardware TX timestamp may be * returned only if there is no software TX timestamp. Ignore false software * timestamps, which may be made in the __sock_recv_timestamp() call when the * option SO_TIMESTAMP(NS) is enabled on the socket, even when the skb has a * hardware timestamp. */ static bool skb_is_swtx_tstamp(const struct sk_buff *skb, int false_tstamp) { return skb->tstamp && !false_tstamp && skb_is_err_queue(skb); } |
aad9c8c47 net: add new cont... |
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 |
static void put_ts_pktinfo(struct msghdr *msg, struct sk_buff *skb) { struct scm_ts_pktinfo ts_pktinfo; struct net_device *orig_dev; if (!skb_mac_header_was_set(skb)) return; memset(&ts_pktinfo, 0, sizeof(ts_pktinfo)); rcu_read_lock(); orig_dev = dev_get_by_napi_id(skb_napi_id(skb)); if (orig_dev) ts_pktinfo.if_index = orig_dev->ifindex; rcu_read_unlock(); ts_pktinfo.pkt_length = skb->len - skb_mac_offset(skb); put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_PKTINFO, sizeof(ts_pktinfo), &ts_pktinfo); } |
92f37fd2e [NET]: Adding SO_... |
683 684 685 686 687 688 |
/* * called from sock_recv_timestamp() if sock_flag(sk, SOCK_RCVTSTAMP) */ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { |
20d494735 net: socket infra... |
689 |
int need_software_tstamp = sock_flag(sk, SOCK_RCVTSTAMP); |
f24b9be59 net-timestamp: ex... |
690 |
struct scm_timestamping tss; |
b50a5c70f net: allow simult... |
691 |
int empty = 1, false_tstamp = 0; |
20d494735 net: socket infra... |
692 693 694 695 696 |
struct skb_shared_hwtstamps *shhwtstamps = skb_hwtstamps(skb); /* Race occurred between timestamp enabling and packet receiving. Fill in the current time for now. */ |
b50a5c70f net: allow simult... |
697 |
if (need_software_tstamp && skb->tstamp == 0) { |
20d494735 net: socket infra... |
698 |
__net_timestamp(skb); |
b50a5c70f net: allow simult... |
699 700 |
false_tstamp = 1; } |
20d494735 net: socket infra... |
701 702 703 704 705 706 707 708 |
if (need_software_tstamp) { if (!sock_flag(sk, SOCK_RCVTSTAMPNS)) { struct timeval tv; skb_get_timestamp(skb, &tv); put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMP, sizeof(tv), &tv); } else { |
f24b9be59 net-timestamp: ex... |
709 710 |
struct timespec ts; skb_get_timestampns(skb, &ts); |
20d494735 net: socket infra... |
711 |
put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPNS, |
f24b9be59 net-timestamp: ex... |
712 |
sizeof(ts), &ts); |
20d494735 net: socket infra... |
713 714 |
} } |
f24b9be59 net-timestamp: ex... |
715 |
memset(&tss, 0, sizeof(tss)); |
c199105d1 net-timestamp: on... |
716 |
if ((sk->sk_tsflags & SOF_TIMESTAMPING_SOFTWARE) && |
f24b9be59 net-timestamp: ex... |
717 |
ktime_to_timespec_cond(skb->tstamp, tss.ts + 0)) |
20d494735 net: socket infra... |
718 |
empty = 0; |
4d276eb6a net: remove depre... |
719 |
if (shhwtstamps && |
b9f40e21e net-timestamp: mo... |
720 |
(sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && |
b50a5c70f net: allow simult... |
721 |
!skb_is_swtx_tstamp(skb, false_tstamp) && |
aad9c8c47 net: add new cont... |
722 |
ktime_to_timespec_cond(shhwtstamps->hwtstamp, tss.ts + 2)) { |
4d276eb6a net: remove depre... |
723 |
empty = 0; |
aad9c8c47 net: add new cont... |
724 725 726 727 |
if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && !skb_is_err_queue(skb)) put_ts_pktinfo(msg, skb); } |
1c885808e tcp: SOF_TIMESTAM... |
728 |
if (!empty) { |
20d494735 net: socket infra... |
729 |
put_cmsg(msg, SOL_SOCKET, |
f24b9be59 net-timestamp: ex... |
730 |
SCM_TIMESTAMPING, sizeof(tss), &tss); |
1c885808e tcp: SOF_TIMESTAM... |
731 |
|
8605330aa tcp: fix SCM_TIME... |
732 |
if (skb_is_err_queue(skb) && skb->len && |
4ef1b2869 tcp: mark skbs wi... |
733 |
SKB_EXT_ERR(skb)->opt_stats) |
1c885808e tcp: SOF_TIMESTAM... |
734 735 736 |
put_cmsg(msg, SOL_SOCKET, SCM_TIMESTAMPING_OPT_STATS, skb->len, skb->data); } |
92f37fd2e [NET]: Adding SO_... |
737 |
} |
7c81fd8bf [SOCKET]: Export ... |
738 |
EXPORT_SYMBOL_GPL(__sock_recv_timestamp); |
6e3e939f3 net: add wireless... |
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 |
void __sock_recv_wifi_status(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) { int ack; if (!sock_flag(sk, SOCK_WIFI_STATUS)) return; if (!skb->wifi_acked_valid) return; ack = skb->wifi_acked; put_cmsg(msg, SOL_SOCKET, SCM_WIFI_STATUS, sizeof(ack), &ack); } EXPORT_SYMBOL_GPL(__sock_recv_wifi_status); |
11165f145 socket: localize ... |
754 755 |
static inline void sock_recv_drops(struct msghdr *msg, struct sock *sk, struct sk_buff *skb) |
3b885787e net: Generalize s... |
756 |
{ |
744d5a3e9 net: move skb->dr... |
757 |
if (sock_flag(sk, SOCK_RXQ_OVFL) && skb && SOCK_SKB_CB(skb)->dropcount) |
3b885787e net: Generalize s... |
758 |
put_cmsg(msg, SOL_SOCKET, SO_RXQ_OVFL, |
744d5a3e9 net: move skb->dr... |
759 |
sizeof(__u32), &SOCK_SKB_CB(skb)->dropcount); |
3b885787e net: Generalize s... |
760 |
} |
767dd0336 net: speedup sock... |
761 |
void __sock_recv_ts_and_drops(struct msghdr *msg, struct sock *sk, |
3b885787e net: Generalize s... |
762 763 764 765 766 |
struct sk_buff *skb) { sock_recv_timestamp(msg, sk, skb); sock_recv_drops(msg, sk, skb); } |
767dd0336 net: speedup sock... |
767 |
EXPORT_SYMBOL_GPL(__sock_recv_ts_and_drops); |
3b885787e net: Generalize s... |
768 |
|
1b7841404 net: Remove iocb ... |
769 |
static inline int sock_recvmsg_nosec(struct socket *sock, struct msghdr *msg, |
2da62906b [net] drop 'size'... |
770 |
int flags) |
1da177e4c Linux-2.6.12-rc2 |
771 |
{ |
2da62906b [net] drop 'size'... |
772 |
return sock->ops->recvmsg(sock, msg, msg_data_left(msg), flags); |
1da177e4c Linux-2.6.12-rc2 |
773 |
} |
2da62906b [net] drop 'size'... |
774 |
int sock_recvmsg(struct socket *sock, struct msghdr *msg, int flags) |
a2e272554 net: Introduce re... |
775 |
{ |
2da62906b [net] drop 'size'... |
776 |
int err = security_socket_recvmsg(sock, msg, msg_data_left(msg), flags); |
a2e272554 net: Introduce re... |
777 |
|
2da62906b [net] drop 'size'... |
778 |
return err ?: sock_recvmsg_nosec(sock, msg, flags); |
1da177e4c Linux-2.6.12-rc2 |
779 |
} |
c6d409cfd From abbffa2aa9bd... |
780 |
EXPORT_SYMBOL(sock_recvmsg); |
1da177e4c Linux-2.6.12-rc2 |
781 |
|
c1249c0aa net: Document the... |
782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 |
/** * kernel_recvmsg - Receive a message from a socket (kernel space) * @sock: The socket to receive the message from * @msg: Received message * @vec: Input s/g array for message data * @num: Size of input s/g array * @size: Number of bytes to read * @flags: Message flags (MSG_DONTWAIT, etc...) * * On return the msg structure contains the scatter/gather array passed in the * vec argument. The array is modified so that it consists of the unfilled * portion of the original array. * * The returned value is the total number of bytes received, or an error. */ |
89bddce58 [NET] socket: cod... |
797 798 |
int kernel_recvmsg(struct socket *sock, struct msghdr *msg, struct kvec *vec, size_t num, size_t size, int flags) |
1da177e4c Linux-2.6.12-rc2 |
799 800 801 |
{ mm_segment_t oldfs = get_fs(); int result; |
6aa248145 switch kernel_sen... |
802 |
iov_iter_kvec(&msg->msg_iter, READ | ITER_KVEC, vec, num, size); |
1da177e4c Linux-2.6.12-rc2 |
803 |
set_fs(KERNEL_DS); |
2da62906b [net] drop 'size'... |
804 |
result = sock_recvmsg(sock, msg, flags); |
1da177e4c Linux-2.6.12-rc2 |
805 806 807 |
set_fs(oldfs); return result; } |
c6d409cfd From abbffa2aa9bd... |
808 |
EXPORT_SYMBOL(kernel_recvmsg); |
1da177e4c Linux-2.6.12-rc2 |
809 |
|
ce1d4d3e8 [NET]: restructur... |
810 811 |
static ssize_t sock_sendpage(struct file *file, struct page *page, int offset, size_t size, loff_t *ppos, int more) |
1da177e4c Linux-2.6.12-rc2 |
812 |
{ |
1da177e4c Linux-2.6.12-rc2 |
813 814 |
struct socket *sock; int flags; |
ce1d4d3e8 [NET]: restructur... |
815 |
sock = file->private_data; |
35f9c09fe tcp: tcp_sendpage... |
816 817 818 |
flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; /* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */ flags |= more; |
ce1d4d3e8 [NET]: restructur... |
819 |
|
e69495838 Make sock_sendpag... |
820 |
return kernel_sendpage(sock, page, offset, size, flags); |
ce1d4d3e8 [NET]: restructur... |
821 |
} |
1da177e4c Linux-2.6.12-rc2 |
822 |
|
9c55e01c0 [TCP]: Splice rec... |
823 |
static ssize_t sock_splice_read(struct file *file, loff_t *ppos, |
c6d409cfd From abbffa2aa9bd... |
824 |
struct pipe_inode_info *pipe, size_t len, |
9c55e01c0 [TCP]: Splice rec... |
825 826 827 |
unsigned int flags) { struct socket *sock = file->private_data; |
997b37da1 [NET]: Make sure ... |
828 829 |
if (unlikely(!sock->ops->splice_read)) return -EINVAL; |
9c55e01c0 [TCP]: Splice rec... |
830 831 |
return sock->ops->splice_read(sock, ppos, pipe, len, flags); } |
8ae5e030f net: switch socke... |
832 |
static ssize_t sock_read_iter(struct kiocb *iocb, struct iov_iter *to) |
ce1d4d3e8 [NET]: restructur... |
833 |
{ |
6d6523302 net/socket.c: fol... |
834 835 |
struct file *file = iocb->ki_filp; struct socket *sock = file->private_data; |
0345f9313 net: socket: add ... |
836 837 |
struct msghdr msg = {.msg_iter = *to, .msg_iocb = iocb}; |
8ae5e030f net: switch socke... |
838 |
ssize_t res; |
ce1d4d3e8 [NET]: restructur... |
839 |
|
8ae5e030f net: switch socke... |
840 841 842 843 |
if (file->f_flags & O_NONBLOCK) msg.msg_flags = MSG_DONTWAIT; if (iocb->ki_pos != 0) |
1da177e4c Linux-2.6.12-rc2 |
844 |
return -ESPIPE; |
027445c37 [PATCH] Vectorize... |
845 |
|
66ee59af6 fs: remove ki_nbytes |
846 |
if (!iov_iter_count(to)) /* Match SYS5 behaviour */ |
1da177e4c Linux-2.6.12-rc2 |
847 |
return 0; |
2da62906b [net] drop 'size'... |
848 |
res = sock_recvmsg(sock, &msg, msg.msg_flags); |
8ae5e030f net: switch socke... |
849 850 |
*to = msg.msg_iter; return res; |
1da177e4c Linux-2.6.12-rc2 |
851 |
} |
8ae5e030f net: switch socke... |
852 |
static ssize_t sock_write_iter(struct kiocb *iocb, struct iov_iter *from) |
ce1d4d3e8 [NET]: restructur... |
853 |
{ |
6d6523302 net/socket.c: fol... |
854 855 |
struct file *file = iocb->ki_filp; struct socket *sock = file->private_data; |
0345f9313 net: socket: add ... |
856 857 |
struct msghdr msg = {.msg_iter = *from, .msg_iocb = iocb}; |
8ae5e030f net: switch socke... |
858 |
ssize_t res; |
1da177e4c Linux-2.6.12-rc2 |
859 |
|
8ae5e030f net: switch socke... |
860 |
if (iocb->ki_pos != 0) |
ce1d4d3e8 [NET]: restructur... |
861 |
return -ESPIPE; |
027445c37 [PATCH] Vectorize... |
862 |
|
8ae5e030f net: switch socke... |
863 864 |
if (file->f_flags & O_NONBLOCK) msg.msg_flags = MSG_DONTWAIT; |
6d6523302 net/socket.c: fol... |
865 866 |
if (sock->type == SOCK_SEQPACKET) msg.msg_flags |= MSG_EOR; |
d8725c86a get rid of the si... |
867 |
res = sock_sendmsg(sock, &msg); |
8ae5e030f net: switch socke... |
868 869 |
*from = msg.msg_iter; return res; |
1da177e4c Linux-2.6.12-rc2 |
870 |
} |
1da177e4c Linux-2.6.12-rc2 |
871 872 873 874 |
/* * Atomic setting of ioctl hooks to avoid race * with module unload. */ |
4a3e2f711 [NET] sem2mutex: ... |
875 |
static DEFINE_MUTEX(br_ioctl_mutex); |
c6d409cfd From abbffa2aa9bd... |
876 |
static int (*br_ioctl_hook) (struct net *, unsigned int cmd, void __user *arg); |
1da177e4c Linux-2.6.12-rc2 |
877 |
|
881d966b4 [NET]: Make the d... |
878 |
void brioctl_set(int (*hook) (struct net *, unsigned int, void __user *)) |
1da177e4c Linux-2.6.12-rc2 |
879 |
{ |
4a3e2f711 [NET] sem2mutex: ... |
880 |
mutex_lock(&br_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
881 |
br_ioctl_hook = hook; |
4a3e2f711 [NET] sem2mutex: ... |
882 |
mutex_unlock(&br_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
883 884 |
} EXPORT_SYMBOL(brioctl_set); |
4a3e2f711 [NET] sem2mutex: ... |
885 |
static DEFINE_MUTEX(vlan_ioctl_mutex); |
881d966b4 [NET]: Make the d... |
886 |
static int (*vlan_ioctl_hook) (struct net *, void __user *arg); |
1da177e4c Linux-2.6.12-rc2 |
887 |
|
881d966b4 [NET]: Make the d... |
888 |
void vlan_ioctl_set(int (*hook) (struct net *, void __user *)) |
1da177e4c Linux-2.6.12-rc2 |
889 |
{ |
4a3e2f711 [NET] sem2mutex: ... |
890 |
mutex_lock(&vlan_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
891 |
vlan_ioctl_hook = hook; |
4a3e2f711 [NET] sem2mutex: ... |
892 |
mutex_unlock(&vlan_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
893 894 |
} EXPORT_SYMBOL(vlan_ioctl_set); |
4a3e2f711 [NET] sem2mutex: ... |
895 |
static DEFINE_MUTEX(dlci_ioctl_mutex); |
89bddce58 [NET] socket: cod... |
896 |
static int (*dlci_ioctl_hook) (unsigned int, void __user *); |
1da177e4c Linux-2.6.12-rc2 |
897 |
|
89bddce58 [NET] socket: cod... |
898 |
void dlci_ioctl_set(int (*hook) (unsigned int, void __user *)) |
1da177e4c Linux-2.6.12-rc2 |
899 |
{ |
4a3e2f711 [NET] sem2mutex: ... |
900 |
mutex_lock(&dlci_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
901 |
dlci_ioctl_hook = hook; |
4a3e2f711 [NET] sem2mutex: ... |
902 |
mutex_unlock(&dlci_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
903 904 |
} EXPORT_SYMBOL(dlci_ioctl_set); |
6b96018b2 compat: move sock... |
905 906 907 908 909 910 911 912 913 914 915 916 |
static long sock_do_ioctl(struct net *net, struct socket *sock, unsigned int cmd, unsigned long arg) { int err; void __user *argp = (void __user *)arg; err = sock->ops->ioctl(sock, cmd, arg); /* * If this ioctl is unknown try to hand it down * to the NIC driver. */ |
36fd633ec net: separate SIO... |
917 918 |
if (err != -ENOIOCTLCMD) return err; |
6b96018b2 compat: move sock... |
919 |
|
36fd633ec net: separate SIO... |
920 921 922 923 924 925 926 927 928 |
if (cmd == SIOCGIFCONF) { struct ifconf ifc; if (copy_from_user(&ifc, argp, sizeof(struct ifconf))) return -EFAULT; rtnl_lock(); err = dev_ifconf(net, &ifc, sizeof(struct ifreq)); rtnl_unlock(); if (!err && copy_to_user(argp, &ifc, sizeof(struct ifconf))) err = -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
929 930 931 932 933 934 935 936 937 |
} else { struct ifreq ifr; bool need_copyout; if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) return -EFAULT; err = dev_ioctl(net, cmd, &ifr, &need_copyout); if (!err && need_copyout) if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) return -EFAULT; |
36fd633ec net: separate SIO... |
938 |
} |
6b96018b2 compat: move sock... |
939 940 |
return err; } |
1da177e4c Linux-2.6.12-rc2 |
941 942 943 944 |
/* * With an ioctl, arg may well be a user mode pointer, but we don't know * what to do with it - that's up to the protocol still. */ |
d8d211a2a net: Make extern ... |
945 |
struct ns_common *get_net_ns(struct ns_common *ns) |
c62cce2ca net: add an ioctl... |
946 947 948 |
{ return &get_net(container_of(ns, struct net, ns))->ns; } |
d8d211a2a net: Make extern ... |
949 |
EXPORT_SYMBOL_GPL(get_net_ns); |
c62cce2ca net: add an ioctl... |
950 |
|
1da177e4c Linux-2.6.12-rc2 |
951 952 953 |
static long sock_ioctl(struct file *file, unsigned cmd, unsigned long arg) { struct socket *sock; |
881d966b4 [NET]: Make the d... |
954 |
struct sock *sk; |
1da177e4c Linux-2.6.12-rc2 |
955 956 |
void __user *argp = (void __user *)arg; int pid, err; |
881d966b4 [NET]: Make the d... |
957 |
struct net *net; |
1da177e4c Linux-2.6.12-rc2 |
958 |
|
b69aee04f [NET]: Use file->... |
959 |
sock = file->private_data; |
881d966b4 [NET]: Make the d... |
960 |
sk = sock->sk; |
3b1e0a655 [NET] NETNS: Omit... |
961 |
net = sock_net(sk); |
44c02a2c3 dev_ioctl(): move... |
962 963 964 965 966 967 968 969 970 |
if (unlikely(cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15))) { struct ifreq ifr; bool need_copyout; if (copy_from_user(&ifr, argp, sizeof(struct ifreq))) return -EFAULT; err = dev_ioctl(net, cmd, &ifr, &need_copyout); if (!err && need_copyout) if (copy_to_user(argp, &ifr, sizeof(struct ifreq))) return -EFAULT; |
1da177e4c Linux-2.6.12-rc2 |
971 |
} else |
3d23e349d wext: refactor |
972 |
#ifdef CONFIG_WEXT_CORE |
1da177e4c Linux-2.6.12-rc2 |
973 |
if (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST) { |
b1b0c2450 lift handling of ... |
974 |
err = wext_handle_ioctl(net, cmd, argp); |
1da177e4c Linux-2.6.12-rc2 |
975 |
} else |
3d23e349d wext: refactor |
976 |
#endif |
89bddce58 [NET] socket: cod... |
977 |
switch (cmd) { |
1da177e4c Linux-2.6.12-rc2 |
978 979 980 981 982 |
case FIOSETOWN: case SIOCSPGRP: err = -EFAULT; if (get_user(pid, (int __user *)argp)) break; |
393cc3f51 fs/fcntl: f_setow... |
983 |
err = f_setown(sock->file, pid, 1); |
1da177e4c Linux-2.6.12-rc2 |
984 985 986 |
break; case FIOGETOWN: case SIOCGPGRP: |
609d7fa95 [PATCH] file: mod... |
987 |
err = put_user(f_getown(sock->file), |
89bddce58 [NET] socket: cod... |
988 |
(int __user *)argp); |
1da177e4c Linux-2.6.12-rc2 |
989 990 991 992 993 994 995 996 |
break; case SIOCGIFBR: case SIOCSIFBR: case SIOCBRADDBR: case SIOCBRDELBR: err = -ENOPKG; if (!br_ioctl_hook) request_module("bridge"); |
4a3e2f711 [NET] sem2mutex: ... |
997 |
mutex_lock(&br_ioctl_mutex); |
89bddce58 [NET] socket: cod... |
998 |
if (br_ioctl_hook) |
881d966b4 [NET]: Make the d... |
999 |
err = br_ioctl_hook(net, cmd, argp); |
4a3e2f711 [NET] sem2mutex: ... |
1000 |
mutex_unlock(&br_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1001 1002 1003 1004 1005 1006 |
break; case SIOCGIFVLAN: case SIOCSIFVLAN: err = -ENOPKG; if (!vlan_ioctl_hook) request_module("8021q"); |
4a3e2f711 [NET] sem2mutex: ... |
1007 |
mutex_lock(&vlan_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1008 |
if (vlan_ioctl_hook) |
881d966b4 [NET]: Make the d... |
1009 |
err = vlan_ioctl_hook(net, argp); |
4a3e2f711 [NET] sem2mutex: ... |
1010 |
mutex_unlock(&vlan_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1011 |
break; |
1da177e4c Linux-2.6.12-rc2 |
1012 1013 1014 1015 1016 |
case SIOCADDDLCI: case SIOCDELDLCI: err = -ENOPKG; if (!dlci_ioctl_hook) request_module("dlci"); |
7512cbf6e [DLCI]: Fix tiny ... |
1017 1018 |
mutex_lock(&dlci_ioctl_mutex); if (dlci_ioctl_hook) |
1da177e4c Linux-2.6.12-rc2 |
1019 |
err = dlci_ioctl_hook(cmd, argp); |
7512cbf6e [DLCI]: Fix tiny ... |
1020 |
mutex_unlock(&dlci_ioctl_mutex); |
1da177e4c Linux-2.6.12-rc2 |
1021 |
break; |
c62cce2ca net: add an ioctl... |
1022 1023 1024 1025 1026 1027 1028 |
case SIOCGSKNS: err = -EPERM; if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) break; err = open_related_ns(&net->ns, get_net_ns); break; |
1da177e4c Linux-2.6.12-rc2 |
1029 |
default: |
6b96018b2 compat: move sock... |
1030 |
err = sock_do_ioctl(net, sock, cmd, arg); |
1da177e4c Linux-2.6.12-rc2 |
1031 |
break; |
89bddce58 [NET] socket: cod... |
1032 |
} |
1da177e4c Linux-2.6.12-rc2 |
1033 1034 1035 1036 1037 1038 1039 |
return err; } int sock_create_lite(int family, int type, int protocol, struct socket **res) { int err; struct socket *sock = NULL; |
89bddce58 [NET] socket: cod... |
1040 |
|
1da177e4c Linux-2.6.12-rc2 |
1041 1042 1043 1044 1045 1046 1047 1048 1049 |
err = security_socket_create(family, type, protocol, 1); if (err) goto out; sock = sock_alloc(); if (!sock) { err = -ENOMEM; goto out; } |
1da177e4c Linux-2.6.12-rc2 |
1050 |
sock->type = type; |
7420ed23a [NetLabel]: SELin... |
1051 1052 1053 |
err = security_socket_post_create(sock, family, type, protocol, 1); if (err) goto out_release; |
1da177e4c Linux-2.6.12-rc2 |
1054 1055 1056 |
out: *res = sock; return err; |
7420ed23a [NetLabel]: SELin... |
1057 1058 1059 1060 |
out_release: sock_release(sock); sock = NULL; goto out; |
1da177e4c Linux-2.6.12-rc2 |
1061 |
} |
c6d409cfd From abbffa2aa9bd... |
1062 |
EXPORT_SYMBOL(sock_create_lite); |
1da177e4c Linux-2.6.12-rc2 |
1063 |
|
152524231 net: add support ... |
1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 |
static struct wait_queue_head *sock_get_poll_head(struct file *file, __poll_t events) { struct socket *sock = file->private_data; if (!sock->ops->poll_mask) return NULL; sock_poll_busy_loop(sock, events); return sk_sleep(sock->sk); } static __poll_t sock_poll_mask(struct file *file, __poll_t events) { struct socket *sock = file->private_data; /* * We need to be sure we are in sync with the socket flags modification. * * This memory barrier is paired in the wq_has_sleeper. */ smp_mb(); /* this socket can poll_ll so tell the system call */ return sock->ops->poll_mask(sock, events) | (sk_can_busy_loop(sock->sk) ? POLL_BUSY_LOOP : 0); } |
1da177e4c Linux-2.6.12-rc2 |
1090 |
/* No kernel lock held - perfect */ |
ade994f4f net: annotate ->p... |
1091 |
static __poll_t sock_poll(struct file *file, poll_table *wait) |
1da177e4c Linux-2.6.12-rc2 |
1092 |
{ |
3cafb3763 net: refactor soc... |
1093 |
struct socket *sock = file->private_data; |
152524231 net: add support ... |
1094 1095 1096 1097 1098 1099 1100 1101 1102 |
__poll_t events = poll_requested_events(wait), mask = 0; if (sock->ops->poll) { sock_poll_busy_loop(sock, events); mask = sock->ops->poll(file, sock, wait); } else if (sock->ops->poll_mask) { sock_poll_wait(file, sock_get_poll_head(file, events), wait); mask = sock->ops->poll_mask(sock, events); } |
2d48d67fa net: poll/select ... |
1103 |
|
152524231 net: add support ... |
1104 |
return mask | sock_poll_busy_flag(sock); |
1da177e4c Linux-2.6.12-rc2 |
1105 |
} |
89bddce58 [NET] socket: cod... |
1106 |
static int sock_mmap(struct file *file, struct vm_area_struct *vma) |
1da177e4c Linux-2.6.12-rc2 |
1107 |
{ |
b69aee04f [NET]: Use file->... |
1108 |
struct socket *sock = file->private_data; |
1da177e4c Linux-2.6.12-rc2 |
1109 1110 1111 |
return sock->ops->mmap(file, sock, vma); } |
20380731b [NET]: Fix sparse... |
1112 |
static int sock_close(struct inode *inode, struct file *filp) |
1da177e4c Linux-2.6.12-rc2 |
1113 |
{ |
6d8c50dcb socket: close rac... |
1114 |
__sock_release(SOCKET_I(inode), inode); |
1da177e4c Linux-2.6.12-rc2 |
1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 |
return 0; } /* * Update the socket async list * * Fasync_list locking strategy. * * 1. fasync_list is modified only under process context socket lock * i.e. under semaphore. * 2. fasync_list is used under read_lock(&sk->sk_callback_lock) |
989a29792 fasync: RCU and f... |
1126 |
* or under socket lock |
1da177e4c Linux-2.6.12-rc2 |
1127 1128 1129 1130 |
*/ static int sock_fasync(int fd, struct file *filp, int on) { |
989a29792 fasync: RCU and f... |
1131 1132 |
struct socket *sock = filp->private_data; struct sock *sk = sock->sk; |
eaefd1105 net: add __rcu an... |
1133 |
struct socket_wq *wq; |
1da177e4c Linux-2.6.12-rc2 |
1134 |
|
989a29792 fasync: RCU and f... |
1135 |
if (sk == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1136 |
return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
1137 1138 |
lock_sock(sk); |
1e1d04e67 net: introduce lo... |
1139 |
wq = rcu_dereference_protected(sock->wq, lockdep_sock_is_held(sk)); |
eaefd1105 net: add __rcu an... |
1140 |
fasync_helper(fd, filp, on, &wq->fasync_list); |
1da177e4c Linux-2.6.12-rc2 |
1141 |
|
eaefd1105 net: add __rcu an... |
1142 |
if (!wq->fasync_list) |
989a29792 fasync: RCU and f... |
1143 1144 |
sock_reset_flag(sk, SOCK_FASYNC); else |
bcdce7195 net: speedup sk_w... |
1145 |
sock_set_flag(sk, SOCK_FASYNC); |
1da177e4c Linux-2.6.12-rc2 |
1146 |
|
989a29792 fasync: RCU and f... |
1147 |
release_sock(sk); |
1da177e4c Linux-2.6.12-rc2 |
1148 1149 |
return 0; } |
ceb5d58b2 net: fix sock_wak... |
1150 |
/* This function may be called only under rcu_lock */ |
1da177e4c Linux-2.6.12-rc2 |
1151 |
|
ceb5d58b2 net: fix sock_wak... |
1152 |
int sock_wake_async(struct socket_wq *wq, int how, int band) |
1da177e4c Linux-2.6.12-rc2 |
1153 |
{ |
ceb5d58b2 net: fix sock_wak... |
1154 |
if (!wq || !wq->fasync_list) |
1da177e4c Linux-2.6.12-rc2 |
1155 |
return -1; |
ceb5d58b2 net: fix sock_wak... |
1156 |
|
89bddce58 [NET] socket: cod... |
1157 |
switch (how) { |
8d8ad9d7c [NET]: Name magic... |
1158 |
case SOCK_WAKE_WAITD: |
ceb5d58b2 net: fix sock_wak... |
1159 |
if (test_bit(SOCKWQ_ASYNC_WAITDATA, &wq->flags)) |
1da177e4c Linux-2.6.12-rc2 |
1160 1161 |
break; goto call_kill; |
8d8ad9d7c [NET]: Name magic... |
1162 |
case SOCK_WAKE_SPACE: |
ceb5d58b2 net: fix sock_wak... |
1163 |
if (!test_and_clear_bit(SOCKWQ_ASYNC_NOSPACE, &wq->flags)) |
1da177e4c Linux-2.6.12-rc2 |
1164 1165 |
break; /* fall through */ |
8d8ad9d7c [NET]: Name magic... |
1166 |
case SOCK_WAKE_IO: |
89bddce58 [NET] socket: cod... |
1167 |
call_kill: |
438154823 net: sock_def_rea... |
1168 |
kill_fasync(&wq->fasync_list, SIGIO, band); |
1da177e4c Linux-2.6.12-rc2 |
1169 |
break; |
8d8ad9d7c [NET]: Name magic... |
1170 |
case SOCK_WAKE_URG: |
438154823 net: sock_def_rea... |
1171 |
kill_fasync(&wq->fasync_list, SIGURG, band); |
1da177e4c Linux-2.6.12-rc2 |
1172 |
} |
ceb5d58b2 net: fix sock_wak... |
1173 |
|
1da177e4c Linux-2.6.12-rc2 |
1174 1175 |
return 0; } |
c6d409cfd From abbffa2aa9bd... |
1176 |
EXPORT_SYMBOL(sock_wake_async); |
1da177e4c Linux-2.6.12-rc2 |
1177 |
|
721db93a5 net: Export __soc... |
1178 |
int __sock_create(struct net *net, int family, int type, int protocol, |
89bddce58 [NET] socket: cod... |
1179 |
struct socket **res, int kern) |
1da177e4c Linux-2.6.12-rc2 |
1180 1181 1182 |
{ int err; struct socket *sock; |
55737fda0 [NET]: socket fam... |
1183 |
const struct net_proto_family *pf; |
1da177e4c Linux-2.6.12-rc2 |
1184 1185 |
/* |
89bddce58 [NET] socket: cod... |
1186 |
* Check protocol is in range |
1da177e4c Linux-2.6.12-rc2 |
1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 |
*/ if (family < 0 || family >= NPROTO) return -EAFNOSUPPORT; if (type < 0 || type >= SOCK_MAX) return -EINVAL; /* Compatibility. This uglymoron is moved from INET layer to here to avoid deadlock in module load. */ if (family == PF_INET && type == SOCK_PACKET) { |
f3c986908 net: socket: use ... |
1199 1200 1201 |
pr_info_once("%s uses obsolete (PF_INET,SOCK_PACKET) ", current->comm); |
1da177e4c Linux-2.6.12-rc2 |
1202 1203 1204 1205 1206 1207 |
family = PF_PACKET; } err = security_socket_create(family, type, protocol, kern); if (err) return err; |
89bddce58 [NET] socket: cod... |
1208 |
|
55737fda0 [NET]: socket fam... |
1209 1210 1211 1212 1213 1214 1215 |
/* * Allocate the socket and allow the family to set things up. if * the protocol is 0, the family is instructed to select an appropriate * default. */ sock = sock_alloc(); if (!sock) { |
e87cc4728 net: Convert net_... |
1216 1217 |
net_warn_ratelimited("socket: no more sockets "); |
55737fda0 [NET]: socket fam... |
1218 1219 1220 1221 1222 |
return -ENFILE; /* Not exactly a match, but its the closest posix thing */ } sock->type = type; |
95a5afca4 net: Remove CONFI... |
1223 |
#ifdef CONFIG_MODULES |
89bddce58 [NET] socket: cod... |
1224 1225 1226 |
/* Attempt to load a protocol module if the find failed. * * 12/09/1996 Marcin: But! this makes REALLY only sense, if the user |
1da177e4c Linux-2.6.12-rc2 |
1227 1228 1229 |
* requested real, full-featured networking support upon configuration. * Otherwise module support will break! */ |
190683a9d net: net_families... |
1230 |
if (rcu_access_pointer(net_families[family]) == NULL) |
89bddce58 [NET] socket: cod... |
1231 |
request_module("net-pf-%d", family); |
1da177e4c Linux-2.6.12-rc2 |
1232 |
#endif |
55737fda0 [NET]: socket fam... |
1233 1234 1235 1236 1237 |
rcu_read_lock(); pf = rcu_dereference(net_families[family]); err = -EAFNOSUPPORT; if (!pf) goto out_release; |
1da177e4c Linux-2.6.12-rc2 |
1238 1239 1240 1241 1242 |
/* * We will call the ->create function, that possibly is in a loadable * module, so we have to bump that loadable module refcnt first. */ |
55737fda0 [NET]: socket fam... |
1243 |
if (!try_module_get(pf->owner)) |
1da177e4c Linux-2.6.12-rc2 |
1244 |
goto out_release; |
55737fda0 [NET]: socket fam... |
1245 1246 |
/* Now protected by module ref count */ rcu_read_unlock(); |
3f378b684 net: pass kern to... |
1247 |
err = pf->create(net, sock, protocol, kern); |
55737fda0 [NET]: socket fam... |
1248 |
if (err < 0) |
1da177e4c Linux-2.6.12-rc2 |
1249 |
goto out_module_put; |
a79af59ef [NET]: Fix module... |
1250 |
|
1da177e4c Linux-2.6.12-rc2 |
1251 1252 1253 1254 |
/* * Now to bump the refcnt of the [loadable] module that owns this * socket at sock_release time we decrement its refcnt. */ |
55737fda0 [NET]: socket fam... |
1255 1256 |
if (!try_module_get(sock->ops->owner)) goto out_module_busy; |
1da177e4c Linux-2.6.12-rc2 |
1257 1258 1259 1260 |
/* * Now that we're done with the ->create function, the [loadable] * module can have its refcnt decremented */ |
55737fda0 [NET]: socket fam... |
1261 |
module_put(pf->owner); |
7420ed23a [NetLabel]: SELin... |
1262 1263 |
err = security_socket_post_create(sock, family, type, protocol, kern); if (err) |
3b1855255 [NET]: Fix unbala... |
1264 |
goto out_sock_release; |
55737fda0 [NET]: socket fam... |
1265 |
*res = sock; |
1da177e4c Linux-2.6.12-rc2 |
1266 |
|
55737fda0 [NET]: socket fam... |
1267 1268 1269 1270 |
return 0; out_module_busy: err = -EAFNOSUPPORT; |
1da177e4c Linux-2.6.12-rc2 |
1271 |
out_module_put: |
55737fda0 [NET]: socket fam... |
1272 1273 1274 |
sock->ops = NULL; module_put(pf->owner); out_sock_release: |
1da177e4c Linux-2.6.12-rc2 |
1275 |
sock_release(sock); |
55737fda0 [NET]: socket fam... |
1276 1277 1278 1279 1280 |
return err; out_release: rcu_read_unlock(); goto out_sock_release; |
1da177e4c Linux-2.6.12-rc2 |
1281 |
} |
721db93a5 net: Export __soc... |
1282 |
EXPORT_SYMBOL(__sock_create); |
1da177e4c Linux-2.6.12-rc2 |
1283 1284 1285 |
int sock_create(int family, int type, int protocol, struct socket **res) { |
1b8d7ae42 [NET]: Make socke... |
1286 |
return __sock_create(current->nsproxy->net_ns, family, type, protocol, res, 0); |
1da177e4c Linux-2.6.12-rc2 |
1287 |
} |
c6d409cfd From abbffa2aa9bd... |
1288 |
EXPORT_SYMBOL(sock_create); |
1da177e4c Linux-2.6.12-rc2 |
1289 |
|
eeb1bd5c4 net: Add a struct... |
1290 |
int sock_create_kern(struct net *net, int family, int type, int protocol, struct socket **res) |
1da177e4c Linux-2.6.12-rc2 |
1291 |
{ |
eeb1bd5c4 net: Add a struct... |
1292 |
return __sock_create(net, family, type, protocol, res, 1); |
1da177e4c Linux-2.6.12-rc2 |
1293 |
} |
c6d409cfd From abbffa2aa9bd... |
1294 |
EXPORT_SYMBOL(sock_create_kern); |
1da177e4c Linux-2.6.12-rc2 |
1295 |
|
9d6a15c3f net: socket: add ... |
1296 |
int __sys_socket(int family, int type, int protocol) |
1da177e4c Linux-2.6.12-rc2 |
1297 1298 1299 |
{ int retval; struct socket *sock; |
a677a039b flag parameters: ... |
1300 |
int flags; |
e38b36f32 flag parameters: ... |
1301 1302 1303 1304 1305 |
/* Check the SOCK_* constants for consistency. */ BUILD_BUG_ON(SOCK_CLOEXEC != O_CLOEXEC); BUILD_BUG_ON((SOCK_MAX | SOCK_TYPE_MASK) != SOCK_TYPE_MASK); BUILD_BUG_ON(SOCK_CLOEXEC & SOCK_TYPE_MASK); BUILD_BUG_ON(SOCK_NONBLOCK & SOCK_TYPE_MASK); |
a677a039b flag parameters: ... |
1306 |
flags = type & ~SOCK_TYPE_MASK; |
77d272005 flag parameters: ... |
1307 |
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) |
a677a039b flag parameters: ... |
1308 1309 |
return -EINVAL; type &= SOCK_TYPE_MASK; |
1da177e4c Linux-2.6.12-rc2 |
1310 |
|
aaca0bdca flag parameters: ... |
1311 1312 |
if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
1313 1314 |
retval = sock_create(family, type, protocol, &sock); if (retval < 0) |
8e1611e23 make sock_alloc_f... |
1315 |
return retval; |
1da177e4c Linux-2.6.12-rc2 |
1316 |
|
8e1611e23 make sock_alloc_f... |
1317 |
return sock_map_fd(sock, flags & (O_CLOEXEC | O_NONBLOCK)); |
1da177e4c Linux-2.6.12-rc2 |
1318 |
} |
9d6a15c3f net: socket: add ... |
1319 1320 1321 1322 |
SYSCALL_DEFINE3(socket, int, family, int, type, int, protocol) { return __sys_socket(family, type, protocol); } |
1da177e4c Linux-2.6.12-rc2 |
1323 1324 1325 |
/* * Create a pair of connected sockets. */ |
6debc8d83 net: socket: add ... |
1326 |
int __sys_socketpair(int family, int type, int protocol, int __user *usockvec) |
1da177e4c Linux-2.6.12-rc2 |
1327 1328 1329 |
{ struct socket *sock1, *sock2; int fd1, fd2, err; |
db3495099 [PATCH] AUDIT_FD_... |
1330 |
struct file *newfile1, *newfile2; |
a677a039b flag parameters: ... |
1331 1332 1333 |
int flags; flags = type & ~SOCK_TYPE_MASK; |
77d272005 flag parameters: ... |
1334 |
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) |
a677a039b flag parameters: ... |
1335 1336 |
return -EINVAL; type &= SOCK_TYPE_MASK; |
1da177e4c Linux-2.6.12-rc2 |
1337 |
|
aaca0bdca flag parameters: ... |
1338 1339 |
if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; |
1da177e4c Linux-2.6.12-rc2 |
1340 |
/* |
016a266bd socketpair(): all... |
1341 1342 1343 1344 1345 1346 1347 1348 1349 1350 1351 1352 1353 1354 1355 1356 1357 1358 1359 1360 1361 1362 |
* reserve descriptors and make sure we won't fail * to return them to userland. */ fd1 = get_unused_fd_flags(flags); if (unlikely(fd1 < 0)) return fd1; fd2 = get_unused_fd_flags(flags); if (unlikely(fd2 < 0)) { put_unused_fd(fd1); return fd2; } err = put_user(fd1, &usockvec[0]); if (err) goto out; err = put_user(fd2, &usockvec[1]); if (err) goto out; /* |
1da177e4c Linux-2.6.12-rc2 |
1363 1364 1365 1366 1367 |
* Obtain the first socket and check if the underlying protocol * supports the socketpair call. */ err = sock_create(family, type, protocol, &sock1); |
016a266bd socketpair(): all... |
1368 |
if (unlikely(err < 0)) |
1da177e4c Linux-2.6.12-rc2 |
1369 1370 1371 |
goto out; err = sock_create(family, type, protocol, &sock2); |
016a266bd socketpair(): all... |
1372 1373 1374 |
if (unlikely(err < 0)) { sock_release(sock1); goto out; |
bf3c23d17 [NET]: Fix error ... |
1375 |
} |
d73aa2867 net: handle error... |
1376 |
|
d47cd9450 net: hook socketp... |
1377 1378 1379 1380 1381 1382 |
err = security_socket_socketpair(sock1, sock2); if (unlikely(err)) { sock_release(sock2); sock_release(sock1); goto out; } |
016a266bd socketpair(): all... |
1383 1384 1385 1386 1387 |
err = sock1->ops->socketpair(sock1, sock2); if (unlikely(err < 0)) { sock_release(sock2); sock_release(sock1); goto out; |
284076305 take descriptor h... |
1388 |
} |
aab174f0d Merge branch 'for... |
1389 |
newfile1 = sock_alloc_file(sock1, flags, NULL); |
b5ffe6344 net: Drop unlikel... |
1390 |
if (IS_ERR(newfile1)) { |
284076305 take descriptor h... |
1391 |
err = PTR_ERR(newfile1); |
016a266bd socketpair(): all... |
1392 1393 |
sock_release(sock2); goto out; |
284076305 take descriptor h... |
1394 |
} |
aab174f0d Merge branch 'for... |
1395 |
newfile2 = sock_alloc_file(sock2, flags, NULL); |
284076305 take descriptor h... |
1396 1397 |
if (IS_ERR(newfile2)) { err = PTR_ERR(newfile2); |
016a266bd socketpair(): all... |
1398 1399 |
fput(newfile1); goto out; |
db3495099 [PATCH] AUDIT_FD_... |
1400 |
} |
157cf649a sanitize audit_fd... |
1401 |
audit_fd_pair(fd1, fd2); |
d73aa2867 net: handle error... |
1402 |
|
db3495099 [PATCH] AUDIT_FD_... |
1403 1404 |
fd_install(fd1, newfile1); fd_install(fd2, newfile2); |
d73aa2867 net: handle error... |
1405 |
return 0; |
1da177e4c Linux-2.6.12-rc2 |
1406 |
|
016a266bd socketpair(): all... |
1407 |
out: |
d73aa2867 net: handle error... |
1408 |
put_unused_fd(fd2); |
d73aa2867 net: handle error... |
1409 |
put_unused_fd(fd1); |
1da177e4c Linux-2.6.12-rc2 |
1410 1411 |
return err; } |
6debc8d83 net: socket: add ... |
1412 1413 1414 1415 1416 |
SYSCALL_DEFINE4(socketpair, int, family, int, type, int, protocol, int __user *, usockvec) { return __sys_socketpair(family, type, protocol, usockvec); } |
1da177e4c Linux-2.6.12-rc2 |
1417 1418 1419 1420 1421 1422 1423 |
/* * Bind a name to a socket. Nothing much to do here since it's * the protocol's responsibility to handle the local address. * * We move the socket address to kernel space before we call * the protocol layer (having also checked the address is ok). */ |
a87d35d87 net: socket: add ... |
1424 |
int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen) |
1da177e4c Linux-2.6.12-rc2 |
1425 1426 |
{ struct socket *sock; |
230b18392 net: Use standard... |
1427 |
struct sockaddr_storage address; |
6cb153cab [NET]: use fget_l... |
1428 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1429 |
|
89bddce58 [NET] socket: cod... |
1430 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
e71a4783a [NET] core: white... |
1431 |
if (sock) { |
43db362d3 net: get rid of s... |
1432 |
err = move_addr_to_kernel(umyaddr, addrlen, &address); |
89bddce58 [NET] socket: cod... |
1433 1434 |
if (err >= 0) { err = security_socket_bind(sock, |
230b18392 net: Use standard... |
1435 |
(struct sockaddr *)&address, |
89bddce58 [NET] socket: cod... |
1436 |
addrlen); |
6cb153cab [NET]: use fget_l... |
1437 1438 |
if (!err) err = sock->ops->bind(sock, |
89bddce58 [NET] socket: cod... |
1439 |
(struct sockaddr *) |
230b18392 net: Use standard... |
1440 |
&address, addrlen); |
1da177e4c Linux-2.6.12-rc2 |
1441 |
} |
6cb153cab [NET]: use fget_l... |
1442 |
fput_light(sock->file, fput_needed); |
89bddce58 [NET] socket: cod... |
1443 |
} |
1da177e4c Linux-2.6.12-rc2 |
1444 1445 |
return err; } |
a87d35d87 net: socket: add ... |
1446 1447 1448 1449 |
SYSCALL_DEFINE3(bind, int, fd, struct sockaddr __user *, umyaddr, int, addrlen) { return __sys_bind(fd, umyaddr, addrlen); } |
1da177e4c Linux-2.6.12-rc2 |
1450 1451 1452 1453 1454 |
/* * Perform a listen. Basically, we allow the protocol to do anything * necessary for a listen, and if that works, we mark the socket as * ready for listening. */ |
25e290eed net: socket: add ... |
1455 |
int __sys_listen(int fd, int backlog) |
1da177e4c Linux-2.6.12-rc2 |
1456 1457 |
{ struct socket *sock; |
6cb153cab [NET]: use fget_l... |
1458 |
int err, fput_needed; |
b8e1f9b5c [NET] sysctl: mak... |
1459 |
int somaxconn; |
89bddce58 [NET] socket: cod... |
1460 1461 1462 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock) { |
8efa6e93c [NETNS]: Introduc... |
1463 |
somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn; |
95c961747 net: cleanup unsi... |
1464 |
if ((unsigned int)backlog > somaxconn) |
b8e1f9b5c [NET] sysctl: mak... |
1465 |
backlog = somaxconn; |
1da177e4c Linux-2.6.12-rc2 |
1466 1467 |
err = security_socket_listen(sock, backlog); |
6cb153cab [NET]: use fget_l... |
1468 1469 |
if (!err) err = sock->ops->listen(sock, backlog); |
1da177e4c Linux-2.6.12-rc2 |
1470 |
|
6cb153cab [NET]: use fget_l... |
1471 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1472 1473 1474 |
} return err; } |
25e290eed net: socket: add ... |
1475 1476 1477 1478 |
SYSCALL_DEFINE2(listen, int, fd, int, backlog) { return __sys_listen(fd, backlog); } |
1da177e4c Linux-2.6.12-rc2 |
1479 1480 1481 1482 1483 1484 1485 1486 1487 |
/* * For accept, we attempt to create a new socket, set up the link * with the client, wake up the client, then return the new * connected fd. We collect the address of the connector in kernel * space and move it to user at the very end. This is unclean because * we open the socket then return an error. * * 1003.1g adds the ability to recvmsg() to query connection pending * status to recvmsg. We need to add that support in a way thats |
b903036aa net: Spelling s/s... |
1488 |
* clean when we restructure accept also. |
1da177e4c Linux-2.6.12-rc2 |
1489 |
*/ |
4541e8056 net: socket: add ... |
1490 1491 |
int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr, int __user *upeer_addrlen, int flags) |
1da177e4c Linux-2.6.12-rc2 |
1492 1493 |
{ struct socket *sock, *newsock; |
39d8c1b6f [NET]: Do not los... |
1494 |
struct file *newfile; |
6cb153cab [NET]: use fget_l... |
1495 |
int err, len, newfd, fput_needed; |
230b18392 net: Use standard... |
1496 |
struct sockaddr_storage address; |
1da177e4c Linux-2.6.12-rc2 |
1497 |
|
77d272005 flag parameters: ... |
1498 |
if (flags & ~(SOCK_CLOEXEC | SOCK_NONBLOCK)) |
aaca0bdca flag parameters: ... |
1499 1500 1501 1502 |
return -EINVAL; if (SOCK_NONBLOCK != O_NONBLOCK && (flags & SOCK_NONBLOCK)) flags = (flags & ~SOCK_NONBLOCK) | O_NONBLOCK; |
6cb153cab [NET]: use fget_l... |
1503 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1504 1505 1506 1507 |
if (!sock) goto out; err = -ENFILE; |
c6d409cfd From abbffa2aa9bd... |
1508 1509 |
newsock = sock_alloc(); if (!newsock) |
1da177e4c Linux-2.6.12-rc2 |
1510 1511 1512 1513 |
goto out_put; newsock->type = sock->type; newsock->ops = sock->ops; |
1da177e4c Linux-2.6.12-rc2 |
1514 1515 1516 1517 1518 |
/* * We don't need try_module_get here, as the listening socket (sock) * has the protocol module (sock->ops->owner) held. */ __module_get(newsock->ops->owner); |
284076305 take descriptor h... |
1519 |
newfd = get_unused_fd_flags(flags); |
39d8c1b6f [NET]: Do not los... |
1520 1521 |
if (unlikely(newfd < 0)) { err = newfd; |
9a1875e60 [NET]: Fully fix ... |
1522 1523 |
sock_release(newsock); goto out_put; |
39d8c1b6f [NET]: Do not los... |
1524 |
} |
aab174f0d Merge branch 'for... |
1525 |
newfile = sock_alloc_file(newsock, flags, sock->sk->sk_prot_creator->name); |
b5ffe6344 net: Drop unlikel... |
1526 |
if (IS_ERR(newfile)) { |
284076305 take descriptor h... |
1527 1528 |
err = PTR_ERR(newfile); put_unused_fd(newfd); |
284076305 take descriptor h... |
1529 1530 |
goto out_put; } |
39d8c1b6f [NET]: Do not los... |
1531 |
|
a79af59ef [NET]: Fix module... |
1532 1533 |
err = security_socket_accept(sock, newsock); if (err) |
39d8c1b6f [NET]: Do not los... |
1534 |
goto out_fd; |
a79af59ef [NET]: Fix module... |
1535 |
|
cdfbabfb2 net: Work around ... |
1536 |
err = sock->ops->accept(sock, newsock, sock->file->f_flags, false); |
1da177e4c Linux-2.6.12-rc2 |
1537 |
if (err < 0) |
39d8c1b6f [NET]: Do not los... |
1538 |
goto out_fd; |
1da177e4c Linux-2.6.12-rc2 |
1539 1540 |
if (upeer_sockaddr) { |
9b2c45d47 net: make getname... |
1541 1542 1543 |
len = newsock->ops->getname(newsock, (struct sockaddr *)&address, 2); if (len < 0) { |
1da177e4c Linux-2.6.12-rc2 |
1544 |
err = -ECONNABORTED; |
39d8c1b6f [NET]: Do not los... |
1545 |
goto out_fd; |
1da177e4c Linux-2.6.12-rc2 |
1546 |
} |
43db362d3 net: get rid of s... |
1547 |
err = move_addr_to_user(&address, |
230b18392 net: Use standard... |
1548 |
len, upeer_sockaddr, upeer_addrlen); |
1da177e4c Linux-2.6.12-rc2 |
1549 |
if (err < 0) |
39d8c1b6f [NET]: Do not los... |
1550 |
goto out_fd; |
1da177e4c Linux-2.6.12-rc2 |
1551 1552 1553 |
} /* File flags are not inherited via accept() unlike another OSes. */ |
39d8c1b6f [NET]: Do not los... |
1554 1555 |
fd_install(newfd, newfile); err = newfd; |
1da177e4c Linux-2.6.12-rc2 |
1556 |
|
1da177e4c Linux-2.6.12-rc2 |
1557 |
out_put: |
6cb153cab [NET]: use fget_l... |
1558 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1559 1560 |
out: return err; |
39d8c1b6f [NET]: Do not los... |
1561 |
out_fd: |
9606a2163 [NET]: Fix dentry... |
1562 |
fput(newfile); |
39d8c1b6f [NET]: Do not los... |
1563 |
put_unused_fd(newfd); |
1da177e4c Linux-2.6.12-rc2 |
1564 1565 |
goto out_put; } |
4541e8056 net: socket: add ... |
1566 1567 1568 1569 1570 |
SYSCALL_DEFINE4(accept4, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen, int, flags) { return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, flags); } |
20f37034f [CVE-2009-0029] S... |
1571 1572 |
SYSCALL_DEFINE3(accept, int, fd, struct sockaddr __user *, upeer_sockaddr, int __user *, upeer_addrlen) |
aaca0bdca flag parameters: ... |
1573 |
{ |
4541e8056 net: socket: add ... |
1574 |
return __sys_accept4(fd, upeer_sockaddr, upeer_addrlen, 0); |
aaca0bdca flag parameters: ... |
1575 |
} |
1da177e4c Linux-2.6.12-rc2 |
1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 |
/* * Attempt to connect to a socket with the server address. The address * is in user space so we verify it is OK and move it to kernel space. * * For 1003.1g we need to add clean support for a bind to AF_UNSPEC to * break bindings * * NOTE: 1003.1g draft 6.3 is broken with respect to AX.25/NetROM and * other SEQPACKET protocols that take time to connect() as it doesn't * include the -EINPROGRESS status for such sockets. */ |
1387c2c2f net: socket: add ... |
1587 |
int __sys_connect(int fd, struct sockaddr __user *uservaddr, int addrlen) |
1da177e4c Linux-2.6.12-rc2 |
1588 1589 |
{ struct socket *sock; |
230b18392 net: Use standard... |
1590 |
struct sockaddr_storage address; |
6cb153cab [NET]: use fget_l... |
1591 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1592 |
|
6cb153cab [NET]: use fget_l... |
1593 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1594 1595 |
if (!sock) goto out; |
43db362d3 net: get rid of s... |
1596 |
err = move_addr_to_kernel(uservaddr, addrlen, &address); |
1da177e4c Linux-2.6.12-rc2 |
1597 1598 |
if (err < 0) goto out_put; |
89bddce58 [NET] socket: cod... |
1599 |
err = |
230b18392 net: Use standard... |
1600 |
security_socket_connect(sock, (struct sockaddr *)&address, addrlen); |
1da177e4c Linux-2.6.12-rc2 |
1601 1602 |
if (err) goto out_put; |
230b18392 net: Use standard... |
1603 |
err = sock->ops->connect(sock, (struct sockaddr *)&address, addrlen, |
1da177e4c Linux-2.6.12-rc2 |
1604 1605 |
sock->file->f_flags); out_put: |
6cb153cab [NET]: use fget_l... |
1606 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1607 1608 1609 |
out: return err; } |
1387c2c2f net: socket: add ... |
1610 1611 1612 1613 1614 |
SYSCALL_DEFINE3(connect, int, fd, struct sockaddr __user *, uservaddr, int, addrlen) { return __sys_connect(fd, uservaddr, addrlen); } |
1da177e4c Linux-2.6.12-rc2 |
1615 1616 1617 1618 |
/* * Get the local address ('name') of a socket object. Move the obtained * name to user space. */ |
8882a107b net: socket: add ... |
1619 1620 |
int __sys_getsockname(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len) |
1da177e4c Linux-2.6.12-rc2 |
1621 1622 |
{ struct socket *sock; |
230b18392 net: Use standard... |
1623 |
struct sockaddr_storage address; |
9b2c45d47 net: make getname... |
1624 |
int err, fput_needed; |
89bddce58 [NET] socket: cod... |
1625 |
|
6cb153cab [NET]: use fget_l... |
1626 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1627 1628 1629 1630 1631 1632 |
if (!sock) goto out; err = security_socket_getsockname(sock); if (err) goto out_put; |
9b2c45d47 net: make getname... |
1633 1634 |
err = sock->ops->getname(sock, (struct sockaddr *)&address, 0); if (err < 0) |
1da177e4c Linux-2.6.12-rc2 |
1635 |
goto out_put; |
9b2c45d47 net: make getname... |
1636 1637 |
/* "err" is actually length in this case */ err = move_addr_to_user(&address, err, usockaddr, usockaddr_len); |
1da177e4c Linux-2.6.12-rc2 |
1638 1639 |
out_put: |
6cb153cab [NET]: use fget_l... |
1640 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1641 1642 1643 |
out: return err; } |
8882a107b net: socket: add ... |
1644 1645 1646 1647 1648 |
SYSCALL_DEFINE3(getsockname, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { return __sys_getsockname(fd, usockaddr, usockaddr_len); } |
1da177e4c Linux-2.6.12-rc2 |
1649 1650 1651 1652 |
/* * Get the remote address ('name') of a socket object. Move the obtained * name to user space. */ |
b21c8f838 net: socket: add ... |
1653 1654 |
int __sys_getpeername(int fd, struct sockaddr __user *usockaddr, int __user *usockaddr_len) |
1da177e4c Linux-2.6.12-rc2 |
1655 1656 |
{ struct socket *sock; |
230b18392 net: Use standard... |
1657 |
struct sockaddr_storage address; |
9b2c45d47 net: make getname... |
1658 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1659 |
|
89bddce58 [NET] socket: cod... |
1660 1661 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock != NULL) { |
1da177e4c Linux-2.6.12-rc2 |
1662 1663 |
err = security_socket_getpeername(sock); if (err) { |
6cb153cab [NET]: use fget_l... |
1664 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1665 1666 |
return err; } |
9b2c45d47 net: make getname... |
1667 1668 1669 1670 |
err = sock->ops->getname(sock, (struct sockaddr *)&address, 1); if (err >= 0) /* "err" is actually length in this case */ err = move_addr_to_user(&address, err, usockaddr, |
89bddce58 [NET] socket: cod... |
1671 |
usockaddr_len); |
6cb153cab [NET]: use fget_l... |
1672 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1673 1674 1675 |
} return err; } |
b21c8f838 net: socket: add ... |
1676 1677 1678 1679 1680 |
SYSCALL_DEFINE3(getpeername, int, fd, struct sockaddr __user *, usockaddr, int __user *, usockaddr_len) { return __sys_getpeername(fd, usockaddr, usockaddr_len); } |
1da177e4c Linux-2.6.12-rc2 |
1681 1682 1683 1684 1685 |
/* * Send a datagram to a given address. We move the address into kernel * space and check the user space data area is readable before invoking * the protocol. */ |
211b634b7 net: socket: add ... |
1686 1687 |
int __sys_sendto(int fd, void __user *buff, size_t len, unsigned int flags, struct sockaddr __user *addr, int addr_len) |
1da177e4c Linux-2.6.12-rc2 |
1688 1689 |
{ struct socket *sock; |
230b18392 net: Use standard... |
1690 |
struct sockaddr_storage address; |
1da177e4c Linux-2.6.12-rc2 |
1691 1692 1693 |
int err; struct msghdr msg; struct iovec iov; |
6cb153cab [NET]: use fget_l... |
1694 |
int fput_needed; |
6cb153cab [NET]: use fget_l... |
1695 |
|
602bd0e90 net: switch sendt... |
1696 1697 1698 |
err = import_single_range(WRITE, buff, len, &iov, &msg.msg_iter); if (unlikely(err)) return err; |
de0fa95c1 [NET]: Use sockfd... |
1699 1700 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) |
4387ff75f [NET]: Fix net/so... |
1701 |
goto out; |
6cb153cab [NET]: use fget_l... |
1702 |
|
89bddce58 [NET] socket: cod... |
1703 |
msg.msg_name = NULL; |
89bddce58 [NET] socket: cod... |
1704 1705 1706 |
msg.msg_control = NULL; msg.msg_controllen = 0; msg.msg_namelen = 0; |
6cb153cab [NET]: use fget_l... |
1707 |
if (addr) { |
43db362d3 net: get rid of s... |
1708 |
err = move_addr_to_kernel(addr, addr_len, &address); |
1da177e4c Linux-2.6.12-rc2 |
1709 1710 |
if (err < 0) goto out_put; |
230b18392 net: Use standard... |
1711 |
msg.msg_name = (struct sockaddr *)&address; |
89bddce58 [NET] socket: cod... |
1712 |
msg.msg_namelen = addr_len; |
1da177e4c Linux-2.6.12-rc2 |
1713 1714 1715 1716 |
} if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; msg.msg_flags = flags; |
d8725c86a get rid of the si... |
1717 |
err = sock_sendmsg(sock, &msg); |
1da177e4c Linux-2.6.12-rc2 |
1718 |
|
89bddce58 [NET] socket: cod... |
1719 |
out_put: |
de0fa95c1 [NET]: Use sockfd... |
1720 |
fput_light(sock->file, fput_needed); |
4387ff75f [NET]: Fix net/so... |
1721 |
out: |
1da177e4c Linux-2.6.12-rc2 |
1722 1723 |
return err; } |
211b634b7 net: socket: add ... |
1724 1725 1726 1727 1728 1729 |
SYSCALL_DEFINE6(sendto, int, fd, void __user *, buff, size_t, len, unsigned int, flags, struct sockaddr __user *, addr, int, addr_len) { return __sys_sendto(fd, buff, len, flags, addr, addr_len); } |
1da177e4c Linux-2.6.12-rc2 |
1730 |
/* |
89bddce58 [NET] socket: cod... |
1731 |
* Send a datagram down a socket. |
1da177e4c Linux-2.6.12-rc2 |
1732 |
*/ |
3e0fa65f8 [CVE-2009-0029] S... |
1733 |
SYSCALL_DEFINE4(send, int, fd, void __user *, buff, size_t, len, |
95c961747 net: cleanup unsi... |
1734 |
unsigned int, flags) |
1da177e4c Linux-2.6.12-rc2 |
1735 |
{ |
211b634b7 net: socket: add ... |
1736 |
return __sys_sendto(fd, buff, len, flags, NULL, 0); |
1da177e4c Linux-2.6.12-rc2 |
1737 1738 1739 |
} /* |
89bddce58 [NET] socket: cod... |
1740 |
* Receive a frame from the socket and optionally record the address of the |
1da177e4c Linux-2.6.12-rc2 |
1741 1742 1743 |
* sender. We verify the buffers are writable and if needed move the * sender address from kernel to user space. */ |
7a09e1eb9 net: socket: add ... |
1744 1745 |
int __sys_recvfrom(int fd, void __user *ubuf, size_t size, unsigned int flags, struct sockaddr __user *addr, int __user *addr_len) |
1da177e4c Linux-2.6.12-rc2 |
1746 1747 1748 1749 |
{ struct socket *sock; struct iovec iov; struct msghdr msg; |
230b18392 net: Use standard... |
1750 |
struct sockaddr_storage address; |
89bddce58 [NET] socket: cod... |
1751 |
int err, err2; |
6cb153cab [NET]: use fget_l... |
1752 |
int fput_needed; |
602bd0e90 net: switch sendt... |
1753 1754 1755 |
err = import_single_range(READ, ubuf, size, &iov, &msg.msg_iter); if (unlikely(err)) return err; |
de0fa95c1 [NET]: Use sockfd... |
1756 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1757 |
if (!sock) |
de0fa95c1 [NET]: Use sockfd... |
1758 |
goto out; |
1da177e4c Linux-2.6.12-rc2 |
1759 |
|
89bddce58 [NET] socket: cod... |
1760 1761 |
msg.msg_control = NULL; msg.msg_controllen = 0; |
f3d334260 net: rework recvm... |
1762 1763 1764 1765 |
/* Save some cycles and don't copy the address if not needed */ msg.msg_name = addr ? (struct sockaddr *)&address : NULL; /* We assume all kernel code knows the size of sockaddr_storage */ msg.msg_namelen = 0; |
130ed5d10 net: fix uninitia... |
1766 |
msg.msg_iocb = NULL; |
9f138fa60 net: initialize m... |
1767 |
msg.msg_flags = 0; |
1da177e4c Linux-2.6.12-rc2 |
1768 1769 |
if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; |
2da62906b [net] drop 'size'... |
1770 |
err = sock_recvmsg(sock, &msg, flags); |
1da177e4c Linux-2.6.12-rc2 |
1771 |
|
89bddce58 [NET] socket: cod... |
1772 |
if (err >= 0 && addr != NULL) { |
43db362d3 net: get rid of s... |
1773 |
err2 = move_addr_to_user(&address, |
230b18392 net: Use standard... |
1774 |
msg.msg_namelen, addr, addr_len); |
89bddce58 [NET] socket: cod... |
1775 1776 |
if (err2 < 0) err = err2; |
1da177e4c Linux-2.6.12-rc2 |
1777 |
} |
de0fa95c1 [NET]: Use sockfd... |
1778 1779 |
fput_light(sock->file, fput_needed); |
4387ff75f [NET]: Fix net/so... |
1780 |
out: |
1da177e4c Linux-2.6.12-rc2 |
1781 1782 |
return err; } |
7a09e1eb9 net: socket: add ... |
1783 1784 1785 1786 1787 1788 |
SYSCALL_DEFINE6(recvfrom, int, fd, void __user *, ubuf, size_t, size, unsigned int, flags, struct sockaddr __user *, addr, int __user *, addr_len) { return __sys_recvfrom(fd, ubuf, size, flags, addr, addr_len); } |
1da177e4c Linux-2.6.12-rc2 |
1789 |
/* |
89bddce58 [NET] socket: cod... |
1790 |
* Receive a datagram from a socket. |
1da177e4c Linux-2.6.12-rc2 |
1791 |
*/ |
b7c0ddf5f net: use SYSCALL_... |
1792 1793 |
SYSCALL_DEFINE4(recv, int, fd, void __user *, ubuf, size_t, size, unsigned int, flags) |
1da177e4c Linux-2.6.12-rc2 |
1794 |
{ |
7a09e1eb9 net: socket: add ... |
1795 |
return __sys_recvfrom(fd, ubuf, size, flags, NULL, NULL); |
1da177e4c Linux-2.6.12-rc2 |
1796 1797 1798 1799 1800 1801 |
} /* * Set a socket option. Because we don't know the option lengths we have * to pass the user mode parameter for the protocols to sort out. */ |
cc36dca0d net: socket: add ... |
1802 1803 |
static int __sys_setsockopt(int fd, int level, int optname, char __user *optval, int optlen) |
1da177e4c Linux-2.6.12-rc2 |
1804 |
{ |
6cb153cab [NET]: use fget_l... |
1805 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1806 1807 1808 1809 |
struct socket *sock; if (optlen < 0) return -EINVAL; |
89bddce58 [NET] socket: cod... |
1810 1811 1812 1813 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock != NULL) { err = security_socket_setsockopt(sock, level, optname); |
6cb153cab [NET]: use fget_l... |
1814 1815 |
if (err) goto out_put; |
1da177e4c Linux-2.6.12-rc2 |
1816 1817 |
if (level == SOL_SOCKET) |
89bddce58 [NET] socket: cod... |
1818 1819 1820 |
err = sock_setsockopt(sock, level, optname, optval, optlen); |
1da177e4c Linux-2.6.12-rc2 |
1821 |
else |
89bddce58 [NET] socket: cod... |
1822 1823 1824 |
err = sock->ops->setsockopt(sock, level, optname, optval, optlen); |
6cb153cab [NET]: use fget_l... |
1825 1826 |
out_put: fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1827 1828 1829 |
} return err; } |
cc36dca0d net: socket: add ... |
1830 1831 1832 1833 1834 |
SYSCALL_DEFINE5(setsockopt, int, fd, int, level, int, optname, char __user *, optval, int, optlen) { return __sys_setsockopt(fd, level, optname, optval, optlen); } |
1da177e4c Linux-2.6.12-rc2 |
1835 1836 1837 1838 |
/* * Get a socket option. Because we don't know the option lengths we have * to pass a user mode parameter for the protocols to sort out. */ |
13a2d70e2 net: socket: add ... |
1839 1840 |
static int __sys_getsockopt(int fd, int level, int optname, char __user *optval, int __user *optlen) |
1da177e4c Linux-2.6.12-rc2 |
1841 |
{ |
6cb153cab [NET]: use fget_l... |
1842 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1843 |
struct socket *sock; |
89bddce58 [NET] socket: cod... |
1844 1845 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock != NULL) { |
6cb153cab [NET]: use fget_l... |
1846 1847 1848 |
err = security_socket_getsockopt(sock, level, optname); if (err) goto out_put; |
1da177e4c Linux-2.6.12-rc2 |
1849 1850 |
if (level == SOL_SOCKET) |
89bddce58 [NET] socket: cod... |
1851 1852 1853 |
err = sock_getsockopt(sock, level, optname, optval, optlen); |
1da177e4c Linux-2.6.12-rc2 |
1854 |
else |
89bddce58 [NET] socket: cod... |
1855 1856 1857 |
err = sock->ops->getsockopt(sock, level, optname, optval, optlen); |
6cb153cab [NET]: use fget_l... |
1858 1859 |
out_put: fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1860 1861 1862 |
} return err; } |
13a2d70e2 net: socket: add ... |
1863 1864 1865 1866 1867 |
SYSCALL_DEFINE5(getsockopt, int, fd, int, level, int, optname, char __user *, optval, int __user *, optlen) { return __sys_getsockopt(fd, level, optname, optval, optlen); } |
1da177e4c Linux-2.6.12-rc2 |
1868 1869 1870 |
/* * Shutdown a socket. */ |
005a1aeac net: socket: add ... |
1871 |
int __sys_shutdown(int fd, int how) |
1da177e4c Linux-2.6.12-rc2 |
1872 |
{ |
6cb153cab [NET]: use fget_l... |
1873 |
int err, fput_needed; |
1da177e4c Linux-2.6.12-rc2 |
1874 |
struct socket *sock; |
89bddce58 [NET] socket: cod... |
1875 1876 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); if (sock != NULL) { |
1da177e4c Linux-2.6.12-rc2 |
1877 |
err = security_socket_shutdown(sock, how); |
6cb153cab [NET]: use fget_l... |
1878 1879 1880 |
if (!err) err = sock->ops->shutdown(sock, how); fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
1881 1882 1883 |
} return err; } |
005a1aeac net: socket: add ... |
1884 1885 1886 1887 |
SYSCALL_DEFINE2(shutdown, int, fd, int, how) { return __sys_shutdown(fd, how); } |
89bddce58 [NET] socket: cod... |
1888 |
/* A couple of helpful macros for getting the address of the 32/64 bit |
1da177e4c Linux-2.6.12-rc2 |
1889 1890 1891 1892 1893 |
* fields which are the same type (int / unsigned) on our platforms. */ #define COMPAT_MSG(msg, member) ((MSG_CMSG_COMPAT & flags) ? &msg##_compat->member : &msg->member) #define COMPAT_NAMELEN(msg) COMPAT_MSG(msg, msg_namelen) #define COMPAT_FLAGS(msg) COMPAT_MSG(msg, msg_flags) |
c71d8ebe7 net: Fix security... |
1894 1895 1896 1897 |
struct used_address { struct sockaddr_storage name; unsigned int name_len; }; |
da1842849 net: switch impor... |
1898 1899 1900 1901 |
static int copy_msghdr_from_user(struct msghdr *kmsg, struct user_msghdr __user *umsg, struct sockaddr __user **save_addr, struct iovec **iov) |
1661bf364 net: heap overflo... |
1902 |
{ |
ffb07550c copy_msghdr_from_... |
1903 |
struct user_msghdr msg; |
08adb7dab fold verify_iovec... |
1904 |
ssize_t err; |
ffb07550c copy_msghdr_from_... |
1905 |
if (copy_from_user(&msg, umsg, sizeof(*umsg))) |
1661bf364 net: heap overflo... |
1906 |
return -EFAULT; |
dbb490b96 net: socket: erro... |
1907 |
|
864d96642 net/socket: fix t... |
1908 |
kmsg->msg_control = (void __force *)msg.msg_control; |
ffb07550c copy_msghdr_from_... |
1909 1910 1911 1912 1913 |
kmsg->msg_controllen = msg.msg_controllen; kmsg->msg_flags = msg.msg_flags; kmsg->msg_namelen = msg.msg_namelen; if (!msg.msg_name) |
6a2a2b3ae net:socket: set m... |
1914 |
kmsg->msg_namelen = 0; |
dbb490b96 net: socket: erro... |
1915 1916 |
if (kmsg->msg_namelen < 0) return -EINVAL; |
1661bf364 net: heap overflo... |
1917 |
if (kmsg->msg_namelen > sizeof(struct sockaddr_storage)) |
db31c55a6 net: clamp ->msg_... |
1918 |
kmsg->msg_namelen = sizeof(struct sockaddr_storage); |
08adb7dab fold verify_iovec... |
1919 1920 |
if (save_addr) |
ffb07550c copy_msghdr_from_... |
1921 |
*save_addr = msg.msg_name; |
08adb7dab fold verify_iovec... |
1922 |
|
ffb07550c copy_msghdr_from_... |
1923 |
if (msg.msg_name && kmsg->msg_namelen) { |
08adb7dab fold verify_iovec... |
1924 |
if (!save_addr) { |
864d96642 net/socket: fix t... |
1925 1926 |
err = move_addr_to_kernel(msg.msg_name, kmsg->msg_namelen, |
08adb7dab fold verify_iovec... |
1927 1928 1929 1930 1931 1932 1933 1934 |
kmsg->msg_name); if (err < 0) return err; } } else { kmsg->msg_name = NULL; kmsg->msg_namelen = 0; } |
ffb07550c copy_msghdr_from_... |
1935 |
if (msg.msg_iovlen > UIO_MAXIOV) |
08adb7dab fold verify_iovec... |
1936 |
return -EMSGSIZE; |
0345f9313 net: socket: add ... |
1937 |
kmsg->msg_iocb = NULL; |
ffb07550c copy_msghdr_from_... |
1938 1939 |
return import_iovec(save_addr ? READ : WRITE, msg.msg_iov, msg.msg_iovlen, |
da1842849 net: switch impor... |
1940 |
UIO_FASTIOV, iov, &kmsg->msg_iter); |
1661bf364 net: heap overflo... |
1941 |
} |
666547ff5 separate kernel- ... |
1942 |
static int ___sys_sendmsg(struct socket *sock, struct user_msghdr __user *msg, |
95c961747 net: cleanup unsi... |
1943 |
struct msghdr *msg_sys, unsigned int flags, |
28a94d8fb net: Allow MSG_EO... |
1944 1945 |
struct used_address *used_address, unsigned int allowed_msghdr_flags) |
1da177e4c Linux-2.6.12-rc2 |
1946 |
{ |
89bddce58 [NET] socket: cod... |
1947 1948 |
struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; |
230b18392 net: Use standard... |
1949 |
struct sockaddr_storage address; |
1da177e4c Linux-2.6.12-rc2 |
1950 |
struct iovec iovstack[UIO_FASTIOV], *iov = iovstack; |
b9d717a7b [NET]: Make sure ... |
1951 |
unsigned char ctl[sizeof(struct cmsghdr) + 20] |
846cc1231 net: socket: pref... |
1952 |
__aligned(sizeof(__kernel_size_t)); |
89bddce58 [NET] socket: cod... |
1953 |
/* 20 is size of ipv6_pktinfo */ |
1da177e4c Linux-2.6.12-rc2 |
1954 |
unsigned char *ctl_buf = ctl; |
d8725c86a get rid of the si... |
1955 |
int ctl_len; |
08adb7dab fold verify_iovec... |
1956 |
ssize_t err; |
89bddce58 [NET] socket: cod... |
1957 |
|
08adb7dab fold verify_iovec... |
1958 |
msg_sys->msg_name = &address; |
1da177e4c Linux-2.6.12-rc2 |
1959 |
|
084493200 {compat_,}verify_... |
1960 |
if (MSG_CMSG_COMPAT & flags) |
08adb7dab fold verify_iovec... |
1961 |
err = get_compat_msghdr(msg_sys, msg_compat, NULL, &iov); |
084493200 {compat_,}verify_... |
1962 |
else |
08adb7dab fold verify_iovec... |
1963 |
err = copy_msghdr_from_user(msg_sys, msg, NULL, &iov); |
89bddce58 [NET] socket: cod... |
1964 |
if (err < 0) |
da1842849 net: switch impor... |
1965 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
1966 1967 |
err = -ENOBUFS; |
228e548e6 net: Add sendmmsg... |
1968 |
if (msg_sys->msg_controllen > INT_MAX) |
1da177e4c Linux-2.6.12-rc2 |
1969 |
goto out_freeiov; |
28a94d8fb net: Allow MSG_EO... |
1970 |
flags |= (msg_sys->msg_flags & allowed_msghdr_flags); |
228e548e6 net: Add sendmmsg... |
1971 |
ctl_len = msg_sys->msg_controllen; |
1da177e4c Linux-2.6.12-rc2 |
1972 |
if ((MSG_CMSG_COMPAT & flags) && ctl_len) { |
89bddce58 [NET] socket: cod... |
1973 |
err = |
228e548e6 net: Add sendmmsg... |
1974 |
cmsghdr_from_user_compat_to_kern(msg_sys, sock->sk, ctl, |
89bddce58 [NET] socket: cod... |
1975 |
sizeof(ctl)); |
1da177e4c Linux-2.6.12-rc2 |
1976 1977 |
if (err) goto out_freeiov; |
228e548e6 net: Add sendmmsg... |
1978 1979 |
ctl_buf = msg_sys->msg_control; ctl_len = msg_sys->msg_controllen; |
1da177e4c Linux-2.6.12-rc2 |
1980 |
} else if (ctl_len) { |
ac4340fc3 net: Assert at bu... |
1981 1982 |
BUILD_BUG_ON(sizeof(struct cmsghdr) != CMSG_ALIGN(sizeof(struct cmsghdr))); |
89bddce58 [NET] socket: cod... |
1983 |
if (ctl_len > sizeof(ctl)) { |
1da177e4c Linux-2.6.12-rc2 |
1984 |
ctl_buf = sock_kmalloc(sock->sk, ctl_len, GFP_KERNEL); |
89bddce58 [NET] socket: cod... |
1985 |
if (ctl_buf == NULL) |
1da177e4c Linux-2.6.12-rc2 |
1986 1987 1988 1989 |
goto out_freeiov; } err = -EFAULT; /* |
228e548e6 net: Add sendmmsg... |
1990 |
* Careful! Before this, msg_sys->msg_control contains a user pointer. |
1da177e4c Linux-2.6.12-rc2 |
1991 1992 1993 |
* Afterwards, it will be a kernel pointer. Thus the compiler-assisted * checking falls down on this. */ |
fb8621bb6 net: remove addre... |
1994 |
if (copy_from_user(ctl_buf, |
228e548e6 net: Add sendmmsg... |
1995 |
(void __user __force *)msg_sys->msg_control, |
89bddce58 [NET] socket: cod... |
1996 |
ctl_len)) |
1da177e4c Linux-2.6.12-rc2 |
1997 |
goto out_freectl; |
228e548e6 net: Add sendmmsg... |
1998 |
msg_sys->msg_control = ctl_buf; |
1da177e4c Linux-2.6.12-rc2 |
1999 |
} |
228e548e6 net: Add sendmmsg... |
2000 |
msg_sys->msg_flags = flags; |
1da177e4c Linux-2.6.12-rc2 |
2001 2002 |
if (sock->file->f_flags & O_NONBLOCK) |
228e548e6 net: Add sendmmsg... |
2003 |
msg_sys->msg_flags |= MSG_DONTWAIT; |
c71d8ebe7 net: Fix security... |
2004 2005 2006 2007 2008 2009 |
/* * If this is sendmmsg() and current destination address is same as * previously succeeded address, omit asking LSM's decision. * used_address->name_len is initialized to UINT_MAX so that the first * destination address never matches. */ |
bc909d9dd sendmmsg/sendmsg:... |
2010 2011 2012 |
if (used_address && msg_sys->msg_name && used_address->name_len == msg_sys->msg_namelen && !memcmp(&used_address->name, msg_sys->msg_name, |
c71d8ebe7 net: Fix security... |
2013 |
used_address->name_len)) { |
d8725c86a get rid of the si... |
2014 |
err = sock_sendmsg_nosec(sock, msg_sys); |
c71d8ebe7 net: Fix security... |
2015 2016 |
goto out_freectl; } |
d8725c86a get rid of the si... |
2017 |
err = sock_sendmsg(sock, msg_sys); |
c71d8ebe7 net: Fix security... |
2018 2019 2020 2021 2022 2023 |
/* * If this is sendmmsg() and sending to current destination address was * successful, remember it. */ if (used_address && err >= 0) { used_address->name_len = msg_sys->msg_namelen; |
bc909d9dd sendmmsg/sendmsg:... |
2024 2025 2026 |
if (msg_sys->msg_name) memcpy(&used_address->name, msg_sys->msg_name, used_address->name_len); |
c71d8ebe7 net: Fix security... |
2027 |
} |
1da177e4c Linux-2.6.12-rc2 |
2028 2029 |
out_freectl: |
89bddce58 [NET] socket: cod... |
2030 |
if (ctl_buf != ctl) |
1da177e4c Linux-2.6.12-rc2 |
2031 2032 |
sock_kfree_s(sock->sk, ctl_buf, ctl_len); out_freeiov: |
da1842849 net: switch impor... |
2033 |
kfree(iov); |
228e548e6 net: Add sendmmsg... |
2034 2035 2036 2037 2038 2039 |
return err; } /* * BSD sendmsg interface */ |
e1834a329 net: socket: move... |
2040 2041 |
long __sys_sendmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, bool forbid_cmsg_compat) |
228e548e6 net: Add sendmmsg... |
2042 2043 2044 |
{ int fput_needed, err; struct msghdr msg_sys; |
1be374a05 net: Block MSG_CM... |
2045 |
struct socket *sock; |
e1834a329 net: socket: move... |
2046 2047 |
if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) return -EINVAL; |
1be374a05 net: Block MSG_CM... |
2048 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
228e548e6 net: Add sendmmsg... |
2049 2050 |
if (!sock) goto out; |
28a94d8fb net: Allow MSG_EO... |
2051 |
err = ___sys_sendmsg(sock, msg, &msg_sys, flags, NULL, 0); |
228e548e6 net: Add sendmmsg... |
2052 |
|
6cb153cab [NET]: use fget_l... |
2053 |
fput_light(sock->file, fput_needed); |
89bddce58 [NET] socket: cod... |
2054 |
out: |
1da177e4c Linux-2.6.12-rc2 |
2055 2056 |
return err; } |
666547ff5 separate kernel- ... |
2057 |
SYSCALL_DEFINE3(sendmsg, int, fd, struct user_msghdr __user *, msg, unsigned int, flags) |
a7526eb5d net: Unbreak comp... |
2058 |
{ |
e1834a329 net: socket: move... |
2059 |
return __sys_sendmsg(fd, msg, flags, true); |
a7526eb5d net: Unbreak comp... |
2060 |
} |
228e548e6 net: Add sendmmsg... |
2061 2062 2063 2064 2065 |
/* * Linux sendmmsg interface */ int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, |
e1834a329 net: socket: move... |
2066 |
unsigned int flags, bool forbid_cmsg_compat) |
228e548e6 net: Add sendmmsg... |
2067 2068 2069 2070 2071 2072 |
{ int fput_needed, err, datagrams; struct socket *sock; struct mmsghdr __user *entry; struct compat_mmsghdr __user *compat_entry; struct msghdr msg_sys; |
c71d8ebe7 net: Fix security... |
2073 |
struct used_address used_address; |
f092276d8 net: Add MSG_BATC... |
2074 |
unsigned int oflags = flags; |
228e548e6 net: Add sendmmsg... |
2075 |
|
e1834a329 net: socket: move... |
2076 2077 |
if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) return -EINVAL; |
98382f419 net: Cap number o... |
2078 2079 |
if (vlen > UIO_MAXIOV) vlen = UIO_MAXIOV; |
228e548e6 net: Add sendmmsg... |
2080 2081 2082 2083 2084 2085 |
datagrams = 0; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) return err; |
c71d8ebe7 net: Fix security... |
2086 |
used_address.name_len = UINT_MAX; |
228e548e6 net: Add sendmmsg... |
2087 2088 |
entry = mmsg; compat_entry = (struct compat_mmsghdr __user *)mmsg; |
728ffb86f net: sendmmsg sho... |
2089 |
err = 0; |
f092276d8 net: Add MSG_BATC... |
2090 |
flags |= MSG_BATCH; |
228e548e6 net: Add sendmmsg... |
2091 2092 |
while (datagrams < vlen) { |
f092276d8 net: Add MSG_BATC... |
2093 2094 |
if (datagrams == vlen - 1) flags = oflags; |
228e548e6 net: Add sendmmsg... |
2095 |
if (MSG_CMSG_COMPAT & flags) { |
666547ff5 separate kernel- ... |
2096 |
err = ___sys_sendmsg(sock, (struct user_msghdr __user *)compat_entry, |
28a94d8fb net: Allow MSG_EO... |
2097 |
&msg_sys, flags, &used_address, MSG_EOR); |
228e548e6 net: Add sendmmsg... |
2098 2099 2100 2101 2102 |
if (err < 0) break; err = __put_user(err, &compat_entry->msg_len); ++compat_entry; } else { |
a7526eb5d net: Unbreak comp... |
2103 |
err = ___sys_sendmsg(sock, |
666547ff5 separate kernel- ... |
2104 |
(struct user_msghdr __user *)entry, |
28a94d8fb net: Allow MSG_EO... |
2105 |
&msg_sys, flags, &used_address, MSG_EOR); |
228e548e6 net: Add sendmmsg... |
2106 2107 2108 2109 2110 2111 2112 2113 2114 |
if (err < 0) break; err = put_user(err, &entry->msg_len); ++entry; } if (err) break; ++datagrams; |
3023898b7 sock: fix sendmms... |
2115 2116 |
if (msg_data_left(&msg_sys)) break; |
a78cb84c6 net: add scheduli... |
2117 |
cond_resched(); |
228e548e6 net: Add sendmmsg... |
2118 |
} |
228e548e6 net: Add sendmmsg... |
2119 |
fput_light(sock->file, fput_needed); |
728ffb86f net: sendmmsg sho... |
2120 2121 |
/* We only return an error if no datagrams were able to be sent */ if (datagrams != 0) |
228e548e6 net: Add sendmmsg... |
2122 |
return datagrams; |
228e548e6 net: Add sendmmsg... |
2123 2124 2125 2126 2127 2128 |
return err; } SYSCALL_DEFINE4(sendmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags) { |
e1834a329 net: socket: move... |
2129 |
return __sys_sendmmsg(fd, mmsg, vlen, flags, true); |
228e548e6 net: Add sendmmsg... |
2130 |
} |
666547ff5 separate kernel- ... |
2131 |
static int ___sys_recvmsg(struct socket *sock, struct user_msghdr __user *msg, |
95c961747 net: cleanup unsi... |
2132 |
struct msghdr *msg_sys, unsigned int flags, int nosec) |
1da177e4c Linux-2.6.12-rc2 |
2133 |
{ |
89bddce58 [NET] socket: cod... |
2134 2135 |
struct compat_msghdr __user *msg_compat = (struct compat_msghdr __user *)msg; |
1da177e4c Linux-2.6.12-rc2 |
2136 |
struct iovec iovstack[UIO_FASTIOV]; |
89bddce58 [NET] socket: cod... |
2137 |
struct iovec *iov = iovstack; |
1da177e4c Linux-2.6.12-rc2 |
2138 |
unsigned long cmsg_ptr; |
2da62906b [net] drop 'size'... |
2139 |
int len; |
08adb7dab fold verify_iovec... |
2140 |
ssize_t err; |
1da177e4c Linux-2.6.12-rc2 |
2141 2142 |
/* kernel mode address */ |
230b18392 net: Use standard... |
2143 |
struct sockaddr_storage addr; |
1da177e4c Linux-2.6.12-rc2 |
2144 2145 2146 |
/* user mode address pointers */ struct sockaddr __user *uaddr; |
08adb7dab fold verify_iovec... |
2147 |
int __user *uaddr_len = COMPAT_NAMELEN(msg); |
89bddce58 [NET] socket: cod... |
2148 |
|
08adb7dab fold verify_iovec... |
2149 |
msg_sys->msg_name = &addr; |
1da177e4c Linux-2.6.12-rc2 |
2150 |
|
f3d334260 net: rework recvm... |
2151 |
if (MSG_CMSG_COMPAT & flags) |
08adb7dab fold verify_iovec... |
2152 |
err = get_compat_msghdr(msg_sys, msg_compat, &uaddr, &iov); |
f3d334260 net: rework recvm... |
2153 |
else |
08adb7dab fold verify_iovec... |
2154 |
err = copy_msghdr_from_user(msg_sys, msg, &uaddr, &iov); |
1da177e4c Linux-2.6.12-rc2 |
2155 |
if (err < 0) |
da1842849 net: switch impor... |
2156 |
return err; |
1da177e4c Linux-2.6.12-rc2 |
2157 |
|
a2e272554 net: Introduce re... |
2158 2159 |
cmsg_ptr = (unsigned long)msg_sys->msg_control; msg_sys->msg_flags = flags & (MSG_CMSG_CLOEXEC|MSG_CMSG_COMPAT); |
89bddce58 [NET] socket: cod... |
2160 |
|
f3d334260 net: rework recvm... |
2161 2162 |
/* We assume all kernel code knows the size of sockaddr_storage */ msg_sys->msg_namelen = 0; |
1da177e4c Linux-2.6.12-rc2 |
2163 2164 |
if (sock->file->f_flags & O_NONBLOCK) flags |= MSG_DONTWAIT; |
2da62906b [net] drop 'size'... |
2165 |
err = (nosec ? sock_recvmsg_nosec : sock_recvmsg)(sock, msg_sys, flags); |
1da177e4c Linux-2.6.12-rc2 |
2166 2167 2168 2169 2170 |
if (err < 0) goto out_freeiov; len = err; if (uaddr != NULL) { |
43db362d3 net: get rid of s... |
2171 |
err = move_addr_to_user(&addr, |
a2e272554 net: Introduce re... |
2172 |
msg_sys->msg_namelen, uaddr, |
89bddce58 [NET] socket: cod... |
2173 |
uaddr_len); |
1da177e4c Linux-2.6.12-rc2 |
2174 2175 2176 |
if (err < 0) goto out_freeiov; } |
a2e272554 net: Introduce re... |
2177 |
err = __put_user((msg_sys->msg_flags & ~MSG_CMSG_COMPAT), |
37f7f421c [NET]: Do not lea... |
2178 |
COMPAT_FLAGS(msg)); |
1da177e4c Linux-2.6.12-rc2 |
2179 2180 2181 |
if (err) goto out_freeiov; if (MSG_CMSG_COMPAT & flags) |
a2e272554 net: Introduce re... |
2182 |
err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, |
1da177e4c Linux-2.6.12-rc2 |
2183 2184 |
&msg_compat->msg_controllen); else |
a2e272554 net: Introduce re... |
2185 |
err = __put_user((unsigned long)msg_sys->msg_control - cmsg_ptr, |
1da177e4c Linux-2.6.12-rc2 |
2186 2187 2188 2189 2190 2191 |
&msg->msg_controllen); if (err) goto out_freeiov; err = len; out_freeiov: |
da1842849 net: switch impor... |
2192 |
kfree(iov); |
a2e272554 net: Introduce re... |
2193 2194 2195 2196 2197 2198 |
return err; } /* * BSD recvmsg interface */ |
e1834a329 net: socket: move... |
2199 2200 |
long __sys_recvmsg(int fd, struct user_msghdr __user *msg, unsigned int flags, bool forbid_cmsg_compat) |
a2e272554 net: Introduce re... |
2201 2202 2203 |
{ int fput_needed, err; struct msghdr msg_sys; |
1be374a05 net: Block MSG_CM... |
2204 |
struct socket *sock; |
e1834a329 net: socket: move... |
2205 2206 |
if (forbid_cmsg_compat && (flags & MSG_CMSG_COMPAT)) return -EINVAL; |
1be374a05 net: Block MSG_CM... |
2207 |
sock = sockfd_lookup_light(fd, &err, &fput_needed); |
a2e272554 net: Introduce re... |
2208 2209 |
if (!sock) goto out; |
a7526eb5d net: Unbreak comp... |
2210 |
err = ___sys_recvmsg(sock, msg, &msg_sys, flags, 0); |
a2e272554 net: Introduce re... |
2211 |
|
6cb153cab [NET]: use fget_l... |
2212 |
fput_light(sock->file, fput_needed); |
1da177e4c Linux-2.6.12-rc2 |
2213 2214 2215 |
out: return err; } |
666547ff5 separate kernel- ... |
2216 |
SYSCALL_DEFINE3(recvmsg, int, fd, struct user_msghdr __user *, msg, |
a7526eb5d net: Unbreak comp... |
2217 2218 |
unsigned int, flags) { |
e1834a329 net: socket: move... |
2219 |
return __sys_recvmsg(fd, msg, flags, true); |
a7526eb5d net: Unbreak comp... |
2220 |
} |
a2e272554 net: Introduce re... |
2221 2222 2223 2224 2225 2226 2227 2228 2229 2230 |
/* * Linux recvmmsg interface */ int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec *timeout) { int fput_needed, err, datagrams; struct socket *sock; struct mmsghdr __user *entry; |
d7256d0eb net: compat_mmsgh... |
2231 |
struct compat_mmsghdr __user *compat_entry; |
a2e272554 net: Introduce re... |
2232 |
struct msghdr msg_sys; |
766b9f928 fs: poll/select/r... |
2233 2234 |
struct timespec64 end_time; struct timespec64 timeout64; |
a2e272554 net: Introduce re... |
2235 2236 2237 2238 2239 2240 2241 2242 2243 2244 2245 |
if (timeout && poll_select_set_timeout(&end_time, timeout->tv_sec, timeout->tv_nsec)) return -EINVAL; datagrams = 0; sock = sockfd_lookup_light(fd, &err, &fput_needed); if (!sock) return err; |
7797dc414 socket: skip chec... |
2246 2247 2248 2249 2250 2251 |
if (likely(!(flags & MSG_ERRQUEUE))) { err = sock_error(sock->sk); if (err) { datagrams = err; goto out_put; } |
e623a9e9d net: socket: fix ... |
2252 |
} |
a2e272554 net: Introduce re... |
2253 2254 |
entry = mmsg; |
d7256d0eb net: compat_mmsgh... |
2255 |
compat_entry = (struct compat_mmsghdr __user *)mmsg; |
a2e272554 net: Introduce re... |
2256 2257 2258 2259 2260 |
while (datagrams < vlen) { /* * No need to ask LSM for more than the first datagram. */ |
d7256d0eb net: compat_mmsgh... |
2261 |
if (MSG_CMSG_COMPAT & flags) { |
666547ff5 separate kernel- ... |
2262 |
err = ___sys_recvmsg(sock, (struct user_msghdr __user *)compat_entry, |
a7526eb5d net: Unbreak comp... |
2263 2264 |
&msg_sys, flags & ~MSG_WAITFORONE, datagrams); |
d7256d0eb net: compat_mmsgh... |
2265 2266 2267 2268 2269 |
if (err < 0) break; err = __put_user(err, &compat_entry->msg_len); ++compat_entry; } else { |
a7526eb5d net: Unbreak comp... |
2270 |
err = ___sys_recvmsg(sock, |
666547ff5 separate kernel- ... |
2271 |
(struct user_msghdr __user *)entry, |
a7526eb5d net: Unbreak comp... |
2272 2273 |
&msg_sys, flags & ~MSG_WAITFORONE, datagrams); |
d7256d0eb net: compat_mmsgh... |
2274 2275 2276 2277 2278 |
if (err < 0) break; err = put_user(err, &entry->msg_len); ++entry; } |
a2e272554 net: Introduce re... |
2279 2280 |
if (err) break; |
a2e272554 net: Introduce re... |
2281 |
++datagrams; |
71c5c1595 net: Add MSG_WAIT... |
2282 2283 2284 |
/* MSG_WAITFORONE turns on MSG_DONTWAIT after one packet */ if (flags & MSG_WAITFORONE) flags |= MSG_DONTWAIT; |
a2e272554 net: Introduce re... |
2285 |
if (timeout) { |
766b9f928 fs: poll/select/r... |
2286 2287 2288 |
ktime_get_ts64(&timeout64); *timeout = timespec64_to_timespec( timespec64_sub(end_time, timeout64)); |
a2e272554 net: Introduce re... |
2289 2290 2291 2292 2293 2294 2295 2296 2297 2298 2299 2300 2301 |
if (timeout->tv_sec < 0) { timeout->tv_sec = timeout->tv_nsec = 0; break; } /* Timeout, return less than vlen datagrams */ if (timeout->tv_nsec == 0 && timeout->tv_sec == 0) break; } /* Out of band data, return right away */ if (msg_sys.msg_flags & MSG_OOB) break; |
a78cb84c6 net: add scheduli... |
2302 |
cond_resched(); |
a2e272554 net: Introduce re... |
2303 |
} |
a2e272554 net: Introduce re... |
2304 |
if (err == 0) |
34b88a68f net: Fix use afte... |
2305 2306 2307 2308 2309 2310 |
goto out_put; if (datagrams == 0) { datagrams = err; goto out_put; } |
a2e272554 net: Introduce re... |
2311 |
|
34b88a68f net: Fix use afte... |
2312 2313 2314 2315 2316 |
/* * We may return less entries than requested (vlen) if the * sock is non block and there aren't enough datagrams... */ if (err != -EAGAIN) { |
a2e272554 net: Introduce re... |
2317 |
/* |
34b88a68f net: Fix use afte... |
2318 2319 2320 2321 |
* ... or if recvmsg returns an error after we * received some datagrams, where we record the * error to return on the next call or if the * app asks about it using getsockopt(SO_ERROR). |
a2e272554 net: Introduce re... |
2322 |
*/ |
34b88a68f net: Fix use afte... |
2323 |
sock->sk->sk_err = -err; |
a2e272554 net: Introduce re... |
2324 |
} |
34b88a68f net: Fix use afte... |
2325 2326 |
out_put: fput_light(sock->file, fput_needed); |
a2e272554 net: Introduce re... |
2327 |
|
34b88a68f net: Fix use afte... |
2328 |
return datagrams; |
a2e272554 net: Introduce re... |
2329 |
} |
1255e2690 net: socket: add ... |
2330 2331 2332 |
static int do_sys_recvmmsg(int fd, struct mmsghdr __user *mmsg, unsigned int vlen, unsigned int flags, struct timespec __user *timeout) |
a2e272554 net: Introduce re... |
2333 2334 2335 |
{ int datagrams; struct timespec timeout_sys; |
1be374a05 net: Block MSG_CM... |
2336 2337 |
if (flags & MSG_CMSG_COMPAT) return -EINVAL; |
a2e272554 net: Introduce re... |
2338 2339 2340 2341 2342 2343 2344 2345 2346 2347 2348 2349 2350 2351 |
if (!timeout) return __sys_recvmmsg(fd, mmsg, vlen, flags, NULL); if (copy_from_user(&timeout_sys, timeout, sizeof(timeout_sys))) return -EFAULT; datagrams = __sys_recvmmsg(fd, mmsg, vlen, flags, &timeout_sys); if (datagrams > 0 && copy_to_user(timeout, &timeout_sys, sizeof(timeout_sys))) datagrams = -EFAULT; return datagrams; } |
1255e2690 net: socket: add ... |
2352 2353 2354 2355 2356 2357 |
SYSCALL_DEFINE5(recvmmsg, int, fd, struct mmsghdr __user *, mmsg, unsigned int, vlen, unsigned int, flags, struct timespec __user *, timeout) { return do_sys_recvmmsg(fd, mmsg, vlen, flags, timeout); } |
a2e272554 net: Introduce re... |
2358 |
#ifdef __ARCH_WANT_SYS_SOCKETCALL |
1da177e4c Linux-2.6.12-rc2 |
2359 2360 |
/* Argument list sizes for sys_socketcall */ #define AL(x) ((x) * sizeof(unsigned long)) |
228e548e6 net: Add sendmmsg... |
2361 |
static const unsigned char nargs[21] = { |
c6d409cfd From abbffa2aa9bd... |
2362 2363 2364 |
AL(0), AL(3), AL(3), AL(3), AL(2), AL(3), AL(3), AL(3), AL(4), AL(4), AL(4), AL(6), AL(6), AL(2), AL(5), AL(5), AL(3), AL(3), |
228e548e6 net: Add sendmmsg... |
2365 |
AL(4), AL(5), AL(4) |
89bddce58 [NET] socket: cod... |
2366 |
}; |
1da177e4c Linux-2.6.12-rc2 |
2367 2368 2369 |
#undef AL /* |
89bddce58 [NET] socket: cod... |
2370 |
* System call vectors. |
1da177e4c Linux-2.6.12-rc2 |
2371 2372 2373 |
* * Argument checking cleaned up. Saved 20% in size. * This function doesn't need to set the kernel lock because |
89bddce58 [NET] socket: cod... |
2374 |
* it is set by the callees. |
1da177e4c Linux-2.6.12-rc2 |
2375 |
*/ |
3e0fa65f8 [CVE-2009-0029] S... |
2376 |
SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args) |
1da177e4c Linux-2.6.12-rc2 |
2377 |
{ |
2950fa9d3 kernel: audit: be... |
2378 |
unsigned long a[AUDITSC_ARGS]; |
89bddce58 [NET] socket: cod... |
2379 |
unsigned long a0, a1; |
1da177e4c Linux-2.6.12-rc2 |
2380 |
int err; |
47379052b net: Add explicit... |
2381 |
unsigned int len; |
1da177e4c Linux-2.6.12-rc2 |
2382 |
|
228e548e6 net: Add sendmmsg... |
2383 |
if (call < 1 || call > SYS_SENDMMSG) |
1da177e4c Linux-2.6.12-rc2 |
2384 |
return -EINVAL; |
47379052b net: Add explicit... |
2385 2386 2387 |
len = nargs[call]; if (len > sizeof(a)) return -EINVAL; |
1da177e4c Linux-2.6.12-rc2 |
2388 |
/* copy_from_user should be SMP safe. */ |
47379052b net: Add explicit... |
2389 |
if (copy_from_user(a, args, len)) |
1da177e4c Linux-2.6.12-rc2 |
2390 |
return -EFAULT; |
3ec3b2fba AUDIT: Capture sy... |
2391 |
|
2950fa9d3 kernel: audit: be... |
2392 2393 2394 |
err = audit_socketcall(nargs[call] / sizeof(unsigned long), a); if (err) return err; |
3ec3b2fba AUDIT: Capture sy... |
2395 |
|
89bddce58 [NET] socket: cod... |
2396 2397 2398 2399 2400 |
a0 = a[0]; a1 = a[1]; switch (call) { case SYS_SOCKET: |
9d6a15c3f net: socket: add ... |
2401 |
err = __sys_socket(a0, a1, a[2]); |
89bddce58 [NET] socket: cod... |
2402 2403 |
break; case SYS_BIND: |
a87d35d87 net: socket: add ... |
2404 |
err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]); |
89bddce58 [NET] socket: cod... |
2405 2406 |
break; case SYS_CONNECT: |
1387c2c2f net: socket: add ... |
2407 |
err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]); |
89bddce58 [NET] socket: cod... |
2408 2409 |
break; case SYS_LISTEN: |
25e290eed net: socket: add ... |
2410 |
err = __sys_listen(a0, a1); |
89bddce58 [NET] socket: cod... |
2411 2412 |
break; case SYS_ACCEPT: |
4541e8056 net: socket: add ... |
2413 2414 |
err = __sys_accept4(a0, (struct sockaddr __user *)a1, (int __user *)a[2], 0); |
89bddce58 [NET] socket: cod... |
2415 2416 2417 |
break; case SYS_GETSOCKNAME: err = |
8882a107b net: socket: add ... |
2418 2419 |
__sys_getsockname(a0, (struct sockaddr __user *)a1, (int __user *)a[2]); |
89bddce58 [NET] socket: cod... |
2420 2421 2422 |
break; case SYS_GETPEERNAME: err = |
b21c8f838 net: socket: add ... |
2423 2424 |
__sys_getpeername(a0, (struct sockaddr __user *)a1, (int __user *)a[2]); |
89bddce58 [NET] socket: cod... |
2425 2426 |
break; case SYS_SOCKETPAIR: |
6debc8d83 net: socket: add ... |
2427 |
err = __sys_socketpair(a0, a1, a[2], (int __user *)a[3]); |
89bddce58 [NET] socket: cod... |
2428 2429 |
break; case SYS_SEND: |
f3bf896b1 net: socket: repl... |
2430 2431 |
err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], NULL, 0); |
89bddce58 [NET] socket: cod... |
2432 2433 |
break; case SYS_SENDTO: |
211b634b7 net: socket: add ... |
2434 2435 |
err = __sys_sendto(a0, (void __user *)a1, a[2], a[3], (struct sockaddr __user *)a[4], a[5]); |
89bddce58 [NET] socket: cod... |
2436 2437 |
break; case SYS_RECV: |
d27e9afc6 net: socket: repl... |
2438 2439 |
err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], NULL, NULL); |
89bddce58 [NET] socket: cod... |
2440 2441 |
break; case SYS_RECVFROM: |
7a09e1eb9 net: socket: add ... |
2442 2443 2444 |
err = __sys_recvfrom(a0, (void __user *)a1, a[2], a[3], (struct sockaddr __user *)a[4], (int __user *)a[5]); |
89bddce58 [NET] socket: cod... |
2445 2446 |
break; case SYS_SHUTDOWN: |
005a1aeac net: socket: add ... |
2447 |
err = __sys_shutdown(a0, a1); |
89bddce58 [NET] socket: cod... |
2448 2449 |
break; case SYS_SETSOCKOPT: |
cc36dca0d net: socket: add ... |
2450 2451 |
err = __sys_setsockopt(a0, a1, a[2], (char __user *)a[3], a[4]); |
89bddce58 [NET] socket: cod... |
2452 2453 2454 |
break; case SYS_GETSOCKOPT: err = |
13a2d70e2 net: socket: add ... |
2455 2456 |
__sys_getsockopt(a0, a1, a[2], (char __user *)a[3], (int __user *)a[4]); |
89bddce58 [NET] socket: cod... |
2457 2458 |
break; case SYS_SENDMSG: |
e1834a329 net: socket: move... |
2459 2460 |
err = __sys_sendmsg(a0, (struct user_msghdr __user *)a1, a[2], true); |
89bddce58 [NET] socket: cod... |
2461 |
break; |
228e548e6 net: Add sendmmsg... |
2462 |
case SYS_SENDMMSG: |
e1834a329 net: socket: move... |
2463 2464 |
err = __sys_sendmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], true); |
228e548e6 net: Add sendmmsg... |
2465 |
break; |
89bddce58 [NET] socket: cod... |
2466 |
case SYS_RECVMSG: |
e1834a329 net: socket: move... |
2467 2468 |
err = __sys_recvmsg(a0, (struct user_msghdr __user *)a1, a[2], true); |
89bddce58 [NET] socket: cod... |
2469 |
break; |
a2e272554 net: Introduce re... |
2470 |
case SYS_RECVMMSG: |
1255e2690 net: socket: add ... |
2471 2472 |
err = do_sys_recvmmsg(a0, (struct mmsghdr __user *)a1, a[2], a[3], (struct timespec __user *)a[4]); |
a2e272554 net: Introduce re... |
2473 |
break; |
de11defeb reintroduce accept4 |
2474 |
case SYS_ACCEPT4: |
4541e8056 net: socket: add ... |
2475 2476 |
err = __sys_accept4(a0, (struct sockaddr __user *)a1, (int __user *)a[2], a[3]); |
aaca0bdca flag parameters: ... |
2477 |
break; |
89bddce58 [NET] socket: cod... |
2478 2479 2480 |
default: err = -EINVAL; break; |
1da177e4c Linux-2.6.12-rc2 |
2481 2482 2483 |
} return err; } |
89bddce58 [NET] socket: cod... |
2484 |
#endif /* __ARCH_WANT_SYS_SOCKETCALL */ |
1da177e4c Linux-2.6.12-rc2 |
2485 |
|
55737fda0 [NET]: socket fam... |
2486 2487 2488 2489 |
/** * sock_register - add a socket protocol handler * @ops: description of protocol * |
1da177e4c Linux-2.6.12-rc2 |
2490 2491 |
* This function is called by a protocol handler that wants to * advertise its address family, and have it linked into the |
e793c0f70 net: treewide: Fi... |
2492 |
* socket interface. The value ops->family corresponds to the |
55737fda0 [NET]: socket fam... |
2493 |
* socket system call protocol family. |
1da177e4c Linux-2.6.12-rc2 |
2494 |
*/ |
f0fd27d42 [NET]: sock_regis... |
2495 |
int sock_register(const struct net_proto_family *ops) |
1da177e4c Linux-2.6.12-rc2 |
2496 2497 2498 2499 |
{ int err; if (ops->family >= NPROTO) { |
3410f22ea socket: replace s... |
2500 2501 |
pr_crit("protocol %d >= NPROTO(%d) ", ops->family, NPROTO); |
1da177e4c Linux-2.6.12-rc2 |
2502 2503 |
return -ENOBUFS; } |
55737fda0 [NET]: socket fam... |
2504 2505 |
spin_lock(&net_family_lock); |
190683a9d net: net_families... |
2506 2507 |
if (rcu_dereference_protected(net_families[ops->family], lockdep_is_held(&net_family_lock))) |
55737fda0 [NET]: socket fam... |
2508 2509 |
err = -EEXIST; else { |
cf778b00e net: reintroduce ... |
2510 |
rcu_assign_pointer(net_families[ops->family], ops); |
1da177e4c Linux-2.6.12-rc2 |
2511 2512 |
err = 0; } |
55737fda0 [NET]: socket fam... |
2513 |
spin_unlock(&net_family_lock); |
3410f22ea socket: replace s... |
2514 2515 |
pr_info("NET: Registered protocol family %d ", ops->family); |
1da177e4c Linux-2.6.12-rc2 |
2516 2517 |
return err; } |
c6d409cfd From abbffa2aa9bd... |
2518 |
EXPORT_SYMBOL(sock_register); |
1da177e4c Linux-2.6.12-rc2 |
2519 |
|
55737fda0 [NET]: socket fam... |
2520 2521 2522 2523 |
/** * sock_unregister - remove a protocol handler * @family: protocol family to remove * |
1da177e4c Linux-2.6.12-rc2 |
2524 2525 |
* This function is called by a protocol handler that wants to * remove its address family, and have it unlinked from the |
55737fda0 [NET]: socket fam... |
2526 2527 2528 2529 2530 2531 |
* new socket creation. * * If protocol handler is a module, then it can use module reference * counts to protect against new references. If protocol handler is not * a module then it needs to provide its own protection in * the ops->create routine. |
1da177e4c Linux-2.6.12-rc2 |
2532 |
*/ |
f0fd27d42 [NET]: sock_regis... |
2533 |
void sock_unregister(int family) |
1da177e4c Linux-2.6.12-rc2 |
2534 |
{ |
f0fd27d42 [NET]: sock_regis... |
2535 |
BUG_ON(family < 0 || family >= NPROTO); |
1da177e4c Linux-2.6.12-rc2 |
2536 |
|
55737fda0 [NET]: socket fam... |
2537 |
spin_lock(&net_family_lock); |
a9b3cd7f3 rcu: convert uses... |
2538 |
RCU_INIT_POINTER(net_families[family], NULL); |
55737fda0 [NET]: socket fam... |
2539 2540 2541 |
spin_unlock(&net_family_lock); synchronize_rcu(); |
3410f22ea socket: replace s... |
2542 2543 |
pr_info("NET: Unregistered protocol family %d ", family); |
1da177e4c Linux-2.6.12-rc2 |
2544 |
} |
c6d409cfd From abbffa2aa9bd... |
2545 |
EXPORT_SYMBOL(sock_unregister); |
1da177e4c Linux-2.6.12-rc2 |
2546 |
|
bf2ae2e4b sock_diag: reques... |
2547 2548 2549 2550 |
bool sock_is_registered(int family) { return family < NPROTO && rcu_access_pointer(net_families[family]); } |
77d76ea31 [NET]: Small clea... |
2551 |
static int __init sock_init(void) |
1da177e4c Linux-2.6.12-rc2 |
2552 |
{ |
b3e19d924 fs: scale mntget/... |
2553 |
int err; |
2ca794e5e net sysctl: Initi... |
2554 2555 2556 2557 2558 2559 |
/* * Initialize the network sysctl infrastructure. */ err = net_sysctl_init(); if (err) goto out; |
b3e19d924 fs: scale mntget/... |
2560 |
|
1da177e4c Linux-2.6.12-rc2 |
2561 |
/* |
89bddce58 [NET] socket: cod... |
2562 |
* Initialize skbuff SLAB cache |
1da177e4c Linux-2.6.12-rc2 |
2563 2564 |
*/ skb_init(); |
1da177e4c Linux-2.6.12-rc2 |
2565 2566 |
/* |
89bddce58 [NET] socket: cod... |
2567 |
* Initialize the protocols module. |
1da177e4c Linux-2.6.12-rc2 |
2568 2569 2570 |
*/ init_inodecache(); |
b3e19d924 fs: scale mntget/... |
2571 2572 2573 2574 |
err = register_filesystem(&sock_fs_type); if (err) goto out_fs; |
1da177e4c Linux-2.6.12-rc2 |
2575 |
sock_mnt = kern_mount(&sock_fs_type); |
b3e19d924 fs: scale mntget/... |
2576 2577 2578 2579 |
if (IS_ERR(sock_mnt)) { err = PTR_ERR(sock_mnt); goto out_mount; } |
77d76ea31 [NET]: Small clea... |
2580 2581 |
/* The real protocol initialization is performed in later initcalls. |
1da177e4c Linux-2.6.12-rc2 |
2582 2583 2584 |
*/ #ifdef CONFIG_NETFILTER |
6d11cfdba netfilter: don't ... |
2585 2586 2587 |
err = netfilter_init(); if (err) goto out; |
1da177e4c Linux-2.6.12-rc2 |
2588 |
#endif |
cbeb321a6 [NET]: Fix sock_i... |
2589 |
|
408eccce3 net: ptp: move PT... |
2590 |
ptp_classifier_init(); |
c1f19b51d net: support time... |
2591 |
|
b3e19d924 fs: scale mntget/... |
2592 2593 2594 2595 2596 2597 2598 |
out: return err; out_mount: unregister_filesystem(&sock_fs_type); out_fs: goto out; |
1da177e4c Linux-2.6.12-rc2 |
2599 |
} |
77d76ea31 [NET]: Small clea... |
2600 |
core_initcall(sock_init); /* early initcall */ |
1da177e4c Linux-2.6.12-rc2 |
2601 2602 2603 |
#ifdef CONFIG_PROC_FS void socket_seq_show(struct seq_file *seq) { |
648845ab7 sock: Move the so... |
2604 2605 2606 |
seq_printf(seq, "sockets: used %d ", sock_inuse_get(seq->private)); |
1da177e4c Linux-2.6.12-rc2 |
2607 |
} |
89bddce58 [NET] socket: cod... |
2608 |
#endif /* CONFIG_PROC_FS */ |
1da177e4c Linux-2.6.12-rc2 |
2609 |
|
89bbfc95d [NET]: allow 32 b... |
2610 |
#ifdef CONFIG_COMPAT |
6b96018b2 compat: move sock... |
2611 |
static int do_siocgstamp(struct net *net, struct socket *sock, |
644595f89 compat: Handle CO... |
2612 |
unsigned int cmd, void __user *up) |
7a229387d net: copy socket ... |
2613 |
{ |
7a229387d net: copy socket ... |
2614 2615 2616 2617 2618 |
mm_segment_t old_fs = get_fs(); struct timeval ktv; int err; set_fs(KERNEL_DS); |
6b96018b2 compat: move sock... |
2619 |
err = sock_do_ioctl(net, sock, cmd, (unsigned long)&ktv); |
7a229387d net: copy socket ... |
2620 |
set_fs(old_fs); |
644595f89 compat: Handle CO... |
2621 |
if (!err) |
ed6fe9d61 Fix order of argu... |
2622 |
err = compat_put_timeval(&ktv, up); |
644595f89 compat: Handle CO... |
2623 |
|
7a229387d net: copy socket ... |
2624 2625 |
return err; } |
6b96018b2 compat: move sock... |
2626 |
static int do_siocgstampns(struct net *net, struct socket *sock, |
644595f89 compat: Handle CO... |
2627 |
unsigned int cmd, void __user *up) |
7a229387d net: copy socket ... |
2628 |
{ |
7a229387d net: copy socket ... |
2629 2630 2631 2632 2633 |
mm_segment_t old_fs = get_fs(); struct timespec kts; int err; set_fs(KERNEL_DS); |
6b96018b2 compat: move sock... |
2634 |
err = sock_do_ioctl(net, sock, cmd, (unsigned long)&kts); |
7a229387d net: copy socket ... |
2635 |
set_fs(old_fs); |
644595f89 compat: Handle CO... |
2636 |
if (!err) |
ed6fe9d61 Fix order of argu... |
2637 |
err = compat_put_timespec(&kts, up); |
644595f89 compat: Handle CO... |
2638 |
|
7a229387d net: copy socket ... |
2639 2640 |
return err; } |
36fd633ec net: separate SIO... |
2641 |
static int compat_dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) |
7a229387d net: copy socket ... |
2642 |
{ |
6b96018b2 compat: move sock... |
2643 |
struct compat_ifconf ifc32; |
7a229387d net: copy socket ... |
2644 |
struct ifconf ifc; |
7a229387d net: copy socket ... |
2645 |
int err; |
6b96018b2 compat: move sock... |
2646 |
if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) |
7a229387d net: copy socket ... |
2647 |
return -EFAULT; |
36fd633ec net: separate SIO... |
2648 2649 |
ifc.ifc_len = ifc32.ifc_len; ifc.ifc_req = compat_ptr(ifc32.ifcbuf); |
7a229387d net: copy socket ... |
2650 |
|
36fd633ec net: separate SIO... |
2651 2652 2653 |
rtnl_lock(); err = dev_ifconf(net, &ifc, sizeof(struct compat_ifreq)); rtnl_unlock(); |
7a229387d net: copy socket ... |
2654 2655 |
if (err) return err; |
36fd633ec net: separate SIO... |
2656 |
ifc32.ifc_len = ifc.ifc_len; |
6b96018b2 compat: move sock... |
2657 |
if (copy_to_user(uifc32, &ifc32, sizeof(struct compat_ifconf))) |
7a229387d net: copy socket ... |
2658 2659 2660 2661 |
return -EFAULT; return 0; } |
6b96018b2 compat: move sock... |
2662 |
static int ethtool_ioctl(struct net *net, struct compat_ifreq __user *ifr32) |
7a229387d net: copy socket ... |
2663 |
{ |
3a7da39d1 ethtool: Compat h... |
2664 2665 |
struct compat_ethtool_rxnfc __user *compat_rxnfc; bool convert_in = false, convert_out = false; |
44c02a2c3 dev_ioctl(): move... |
2666 2667 2668 |
size_t buf_size = 0; struct ethtool_rxnfc __user *rxnfc = NULL; struct ifreq ifr; |
3a7da39d1 ethtool: Compat h... |
2669 2670 |
u32 rule_cnt = 0, actual_rule_cnt; u32 ethcmd; |
7a229387d net: copy socket ... |
2671 |
u32 data; |
3a7da39d1 ethtool: Compat h... |
2672 |
int ret; |
7a229387d net: copy socket ... |
2673 |
|
3a7da39d1 ethtool: Compat h... |
2674 2675 |
if (get_user(data, &ifr32->ifr_ifru.ifru_data)) return -EFAULT; |
7a229387d net: copy socket ... |
2676 |
|
3a7da39d1 ethtool: Compat h... |
2677 2678 2679 |
compat_rxnfc = compat_ptr(data); if (get_user(ethcmd, &compat_rxnfc->cmd)) |
7a229387d net: copy socket ... |
2680 |
return -EFAULT; |
3a7da39d1 ethtool: Compat h... |
2681 2682 2683 2684 2685 2686 2687 2688 2689 2690 2691 2692 2693 2694 2695 2696 2697 |
/* Most ethtool structures are defined without padding. * Unfortunately struct ethtool_rxnfc is an exception. */ switch (ethcmd) { default: break; case ETHTOOL_GRXCLSRLALL: /* Buffer size is variable */ if (get_user(rule_cnt, &compat_rxnfc->rule_cnt)) return -EFAULT; if (rule_cnt > KMALLOC_MAX_SIZE / sizeof(u32)) return -ENOMEM; buf_size += rule_cnt * sizeof(u32); /* fall through */ case ETHTOOL_GRXRINGS: case ETHTOOL_GRXCLSRLCNT: case ETHTOOL_GRXCLSRULE: |
55664f324 ethtool: Allow dr... |
2698 |
case ETHTOOL_SRXCLSRLINS: |
3a7da39d1 ethtool: Compat h... |
2699 2700 2701 |
convert_out = true; /* fall through */ case ETHTOOL_SRXCLSRLDEL: |
3a7da39d1 ethtool: Compat h... |
2702 2703 |
buf_size += sizeof(struct ethtool_rxnfc); convert_in = true; |
44c02a2c3 dev_ioctl(): move... |
2704 |
rxnfc = compat_alloc_user_space(buf_size); |
3a7da39d1 ethtool: Compat h... |
2705 2706 |
break; } |
44c02a2c3 dev_ioctl(): move... |
2707 |
if (copy_from_user(&ifr.ifr_name, &ifr32->ifr_name, IFNAMSIZ)) |
7a229387d net: copy socket ... |
2708 |
return -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
2709 |
ifr.ifr_data = convert_in ? rxnfc : (void __user *)compat_rxnfc; |
7a229387d net: copy socket ... |
2710 |
|
3a7da39d1 ethtool: Compat h... |
2711 |
if (convert_in) { |
127fe533a v3 ethtool: add n... |
2712 |
/* We expect there to be holes between fs.m_ext and |
3a7da39d1 ethtool: Compat h... |
2713 2714 |
* fs.ring_cookie and at the end of fs, but nowhere else. */ |
127fe533a v3 ethtool: add n... |
2715 2716 2717 2718 |
BUILD_BUG_ON(offsetof(struct compat_ethtool_rxnfc, fs.m_ext) + sizeof(compat_rxnfc->fs.m_ext) != offsetof(struct ethtool_rxnfc, fs.m_ext) + sizeof(rxnfc->fs.m_ext)); |
3a7da39d1 ethtool: Compat h... |
2719 2720 2721 2722 2723 2724 2725 |
BUILD_BUG_ON( offsetof(struct compat_ethtool_rxnfc, fs.location) - offsetof(struct compat_ethtool_rxnfc, fs.ring_cookie) != offsetof(struct ethtool_rxnfc, fs.location) - offsetof(struct ethtool_rxnfc, fs.ring_cookie)); if (copy_in_user(rxnfc, compat_rxnfc, |
954b12445 ethtool: fix spar... |
2726 2727 |
(void __user *)(&rxnfc->fs.m_ext + 1) - (void __user *)rxnfc) || |
3a7da39d1 ethtool: Compat h... |
2728 2729 |
copy_in_user(&rxnfc->fs.ring_cookie, &compat_rxnfc->fs.ring_cookie, |
954b12445 ethtool: fix spar... |
2730 2731 |
(void __user *)(&rxnfc->fs.location + 1) - (void __user *)&rxnfc->fs.ring_cookie) || |
3a7da39d1 ethtool: Compat h... |
2732 2733 2734 2735 |
copy_in_user(&rxnfc->rule_cnt, &compat_rxnfc->rule_cnt, sizeof(rxnfc->rule_cnt))) return -EFAULT; } |
44c02a2c3 dev_ioctl(): move... |
2736 |
ret = dev_ioctl(net, SIOCETHTOOL, &ifr, NULL); |
3a7da39d1 ethtool: Compat h... |
2737 2738 2739 2740 2741 |
if (ret) return ret; if (convert_out) { if (copy_in_user(compat_rxnfc, rxnfc, |
954b12445 ethtool: fix spar... |
2742 2743 |
(const void __user *)(&rxnfc->fs.m_ext + 1) - (const void __user *)rxnfc) || |
3a7da39d1 ethtool: Compat h... |
2744 2745 |
copy_in_user(&compat_rxnfc->fs.ring_cookie, &rxnfc->fs.ring_cookie, |
954b12445 ethtool: fix spar... |
2746 2747 |
(const void __user *)(&rxnfc->fs.location + 1) - (const void __user *)&rxnfc->fs.ring_cookie) || |
3a7da39d1 ethtool: Compat h... |
2748 2749 2750 2751 2752 2753 2754 2755 2756 2757 2758 2759 2760 2761 2762 2763 2764 2765 2766 2767 2768 2769 2770 2771 2772 |
copy_in_user(&compat_rxnfc->rule_cnt, &rxnfc->rule_cnt, sizeof(rxnfc->rule_cnt))) return -EFAULT; if (ethcmd == ETHTOOL_GRXCLSRLALL) { /* As an optimisation, we only copy the actual * number of rules that the underlying * function returned. Since Mallory might * change the rule count in user memory, we * check that it is less than the rule count * originally given (as the user buffer size), * which has been range-checked. */ if (get_user(actual_rule_cnt, &rxnfc->rule_cnt)) return -EFAULT; if (actual_rule_cnt < rule_cnt) rule_cnt = actual_rule_cnt; if (copy_in_user(&compat_rxnfc->rule_locs[0], &rxnfc->rule_locs[0], rule_cnt * sizeof(u32))) return -EFAULT; } } return 0; |
7a229387d net: copy socket ... |
2773 |
} |
7a50a240c net/compat_ioctl:... |
2774 2775 |
static int compat_siocwandev(struct net *net, struct compat_ifreq __user *uifr32) { |
7a50a240c net/compat_ioctl:... |
2776 |
compat_uptr_t uptr32; |
44c02a2c3 dev_ioctl(): move... |
2777 2778 2779 |
struct ifreq ifr; void __user *saved; int err; |
7a50a240c net/compat_ioctl:... |
2780 |
|
44c02a2c3 dev_ioctl(): move... |
2781 |
if (copy_from_user(&ifr, uifr32, sizeof(struct compat_ifreq))) |
7a50a240c net/compat_ioctl:... |
2782 2783 2784 2785 |
return -EFAULT; if (get_user(uptr32, &uifr32->ifr_settings.ifs_ifsu)) return -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
2786 2787 |
saved = ifr.ifr_settings.ifs_ifsu.raw_hdlc; ifr.ifr_settings.ifs_ifsu.raw_hdlc = compat_ptr(uptr32); |
7a229387d net: copy socket ... |
2788 |
|
44c02a2c3 dev_ioctl(): move... |
2789 2790 2791 2792 2793 |
err = dev_ioctl(net, SIOCWANDEV, &ifr, NULL); if (!err) { ifr.ifr_settings.ifs_ifsu.raw_hdlc = saved; if (copy_to_user(uifr32, &ifr, sizeof(struct compat_ifreq))) err = -EFAULT; |
ccbd6a5a4 net: Remove unnec... |
2794 |
} |
44c02a2c3 dev_ioctl(): move... |
2795 |
return err; |
7a229387d net: copy socket ... |
2796 |
} |
590d4693f net/compat: Merge... |
2797 2798 |
/* Handle ioctls that use ifreq::ifr_data and just need struct ifreq converted */ static int compat_ifr_data_ioctl(struct net *net, unsigned int cmd, |
6b96018b2 compat: move sock... |
2799 |
struct compat_ifreq __user *u_ifreq32) |
7a229387d net: copy socket ... |
2800 |
{ |
44c02a2c3 dev_ioctl(): move... |
2801 |
struct ifreq ifreq; |
7a229387d net: copy socket ... |
2802 |
u32 data32; |
44c02a2c3 dev_ioctl(): move... |
2803 |
if (copy_from_user(ifreq.ifr_name, u_ifreq32->ifr_name, IFNAMSIZ)) |
7a229387d net: copy socket ... |
2804 |
return -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
2805 |
if (get_user(data32, &u_ifreq32->ifr_data)) |
7a229387d net: copy socket ... |
2806 |
return -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
2807 |
ifreq.ifr_data = compat_ptr(data32); |
7a229387d net: copy socket ... |
2808 |
|
44c02a2c3 dev_ioctl(): move... |
2809 |
return dev_ioctl(net, cmd, &ifreq, NULL); |
7a229387d net: copy socket ... |
2810 |
} |
a2116ed22 net/compat: fix d... |
2811 2812 2813 2814 2815 |
static int compat_sioc_ifmap(struct net *net, unsigned int cmd, struct compat_ifreq __user *uifr32) { struct ifreq ifr; struct compat_ifmap __user *uifmap32; |
a2116ed22 net/compat: fix d... |
2816 2817 2818 2819 |
int err; uifmap32 = &uifr32->ifr_ifru.ifru_map; err = copy_from_user(&ifr, uifr32, sizeof(ifr.ifr_name)); |
3ddc5b46a kernel-wide: fix ... |
2820 2821 2822 2823 2824 2825 |
err |= get_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); err |= get_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); err |= get_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); err |= get_user(ifr.ifr_map.irq, &uifmap32->irq); err |= get_user(ifr.ifr_map.dma, &uifmap32->dma); err |= get_user(ifr.ifr_map.port, &uifmap32->port); |
a2116ed22 net/compat: fix d... |
2826 2827 |
if (err) return -EFAULT; |
44c02a2c3 dev_ioctl(): move... |
2828 |
err = dev_ioctl(net, cmd, &ifr, NULL); |
a2116ed22 net/compat: fix d... |
2829 2830 2831 |
if (cmd == SIOCGIFMAP && !err) { err = copy_to_user(uifr32, &ifr, sizeof(ifr.ifr_name)); |
3ddc5b46a kernel-wide: fix ... |
2832 2833 2834 2835 2836 2837 |
err |= put_user(ifr.ifr_map.mem_start, &uifmap32->mem_start); err |= put_user(ifr.ifr_map.mem_end, &uifmap32->mem_end); err |= put_user(ifr.ifr_map.base_addr, &uifmap32->base_addr); err |= put_user(ifr.ifr_map.irq, &uifmap32->irq); err |= put_user(ifr.ifr_map.dma, &uifmap32->dma); err |= put_user(ifr.ifr_map.port, &uifmap32->port); |
a2116ed22 net/compat: fix d... |
2838 2839 2840 2841 2842 |
if (err) err = -EFAULT; } return err; } |
7a229387d net: copy socket ... |
2843 |
struct rtentry32 { |
c6d409cfd From abbffa2aa9bd... |
2844 |
u32 rt_pad1; |
7a229387d net: copy socket ... |
2845 2846 2847 |
struct sockaddr rt_dst; /* target address */ struct sockaddr rt_gateway; /* gateway addr (RTF_GATEWAY) */ struct sockaddr rt_genmask; /* target network mask (IP) */ |
c6d409cfd From abbffa2aa9bd... |
2848 2849 2850 2851 2852 2853 2854 |
unsigned short rt_flags; short rt_pad2; u32 rt_pad3; unsigned char rt_tos; unsigned char rt_class; short rt_pad4; short rt_metric; /* +1 for binary compatibility! */ |
7a229387d net: copy socket ... |
2855 |
/* char * */ u32 rt_dev; /* forcing the device at add */ |
c6d409cfd From abbffa2aa9bd... |
2856 2857 |
u32 rt_mtu; /* per route MTU/Window */ u32 rt_window; /* Window clamping */ |
7a229387d net: copy socket ... |
2858 2859 2860 2861 2862 2863 2864 2865 2866 2867 2868 2869 2870 2871 2872 |
unsigned short rt_irtt; /* Initial RTT */ }; struct in6_rtmsg32 { struct in6_addr rtmsg_dst; struct in6_addr rtmsg_src; struct in6_addr rtmsg_gateway; u32 rtmsg_type; u16 rtmsg_dst_len; u16 rtmsg_src_len; u32 rtmsg_metric; u32 rtmsg_info; u32 rtmsg_flags; s32 rtmsg_ifindex; }; |
6b96018b2 compat: move sock... |
2873 2874 |
static int routing_ioctl(struct net *net, struct socket *sock, unsigned int cmd, void __user *argp) |
7a229387d net: copy socket ... |
2875 2876 2877 2878 2879 2880 2881 2882 |
{ int ret; void *r = NULL; struct in6_rtmsg r6; struct rtentry r4; char devname[16]; u32 rtdev; mm_segment_t old_fs = get_fs(); |
6b96018b2 compat: move sock... |
2883 2884 |
if (sock && sock->sk && sock->sk->sk_family == AF_INET6) { /* ipv6 */ struct in6_rtmsg32 __user *ur6 = argp; |
c6d409cfd From abbffa2aa9bd... |
2885 |
ret = copy_from_user(&r6.rtmsg_dst, &(ur6->rtmsg_dst), |
7a229387d net: copy socket ... |
2886 |
3 * sizeof(struct in6_addr)); |
3ddc5b46a kernel-wide: fix ... |
2887 2888 2889 2890 2891 2892 2893 |
ret |= get_user(r6.rtmsg_type, &(ur6->rtmsg_type)); ret |= get_user(r6.rtmsg_dst_len, &(ur6->rtmsg_dst_len)); ret |= get_user(r6.rtmsg_src_len, &(ur6->rtmsg_src_len)); ret |= get_user(r6.rtmsg_metric, &(ur6->rtmsg_metric)); ret |= get_user(r6.rtmsg_info, &(ur6->rtmsg_info)); ret |= get_user(r6.rtmsg_flags, &(ur6->rtmsg_flags)); ret |= get_user(r6.rtmsg_ifindex, &(ur6->rtmsg_ifindex)); |
7a229387d net: copy socket ... |
2894 2895 2896 |
r = (void *) &r6; } else { /* ipv4 */ |
6b96018b2 compat: move sock... |
2897 |
struct rtentry32 __user *ur4 = argp; |
c6d409cfd From abbffa2aa9bd... |
2898 |
ret = copy_from_user(&r4.rt_dst, &(ur4->rt_dst), |
7a229387d net: copy socket ... |
2899 |
3 * sizeof(struct sockaddr)); |
3ddc5b46a kernel-wide: fix ... |
2900 2901 2902 2903 2904 2905 |
ret |= get_user(r4.rt_flags, &(ur4->rt_flags)); ret |= get_user(r4.rt_metric, &(ur4->rt_metric)); ret |= get_user(r4.rt_mtu, &(ur4->rt_mtu)); ret |= get_user(r4.rt_window, &(ur4->rt_window)); ret |= get_user(r4.rt_irtt, &(ur4->rt_irtt)); ret |= get_user(rtdev, &(ur4->rt_dev)); |
7a229387d net: copy socket ... |
2906 |
if (rtdev) { |
c6d409cfd From abbffa2aa9bd... |
2907 |
ret |= copy_from_user(devname, compat_ptr(rtdev), 15); |
c3f52ae6a socket: suppress ... |
2908 2909 |
r4.rt_dev = (char __user __force *)devname; devname[15] = 0; |
7a229387d net: copy socket ... |
2910 2911 2912 2913 2914 2915 2916 2917 2918 2919 |
} else r4.rt_dev = NULL; r = (void *) &r4; } if (ret) { ret = -EFAULT; goto out; } |
c6d409cfd From abbffa2aa9bd... |
2920 |
set_fs(KERNEL_DS); |
6b96018b2 compat: move sock... |
2921 |
ret = sock_do_ioctl(net, sock, cmd, (unsigned long) r); |
c6d409cfd From abbffa2aa9bd... |
2922 |
set_fs(old_fs); |
7a229387d net: copy socket ... |
2923 2924 |
out: |
7a229387d net: copy socket ... |
2925 2926 2927 2928 2929 |
return ret; } /* Since old style bridge ioctl's endup using SIOCDEVPRIVATE * for some operations; this forces use of the newer bridge-utils that |
25985edce Fix common misspe... |
2930 |
* use compatible ioctls |
7a229387d net: copy socket ... |
2931 |
*/ |
6b96018b2 compat: move sock... |
2932 |
static int old_bridge_ioctl(compat_ulong_t __user *argp) |
7a229387d net: copy socket ... |
2933 |
{ |
6b96018b2 compat: move sock... |
2934 |
compat_ulong_t tmp; |
7a229387d net: copy socket ... |
2935 |
|
6b96018b2 compat: move sock... |
2936 |
if (get_user(tmp, argp)) |
7a229387d net: copy socket ... |
2937 2938 2939 2940 2941 |
return -EFAULT; if (tmp == BRCTL_GET_VERSION) return BRCTL_VERSION + 1; return -EINVAL; } |
6b96018b2 compat: move sock... |
2942 2943 2944 2945 2946 2947 |
static int compat_sock_ioctl_trans(struct file *file, struct socket *sock, unsigned int cmd, unsigned long arg) { void __user *argp = compat_ptr(arg); struct sock *sk = sock->sk; struct net *net = sock_net(sk); |
7a229387d net: copy socket ... |
2948 |
|
6b96018b2 compat: move sock... |
2949 |
if (cmd >= SIOCDEVPRIVATE && cmd <= (SIOCDEVPRIVATE + 15)) |
590d4693f net/compat: Merge... |
2950 |
return compat_ifr_data_ioctl(net, cmd, argp); |
6b96018b2 compat: move sock... |
2951 2952 2953 2954 2955 |
switch (cmd) { case SIOCSIFBR: case SIOCGIFBR: return old_bridge_ioctl(argp); |
6b96018b2 compat: move sock... |
2956 |
case SIOCGIFCONF: |
36fd633ec net: separate SIO... |
2957 |
return compat_dev_ifconf(net, argp); |
6b96018b2 compat: move sock... |
2958 2959 |
case SIOCETHTOOL: return ethtool_ioctl(net, argp); |
7a50a240c net/compat_ioctl:... |
2960 2961 |
case SIOCWANDEV: return compat_siocwandev(net, argp); |
a2116ed22 net/compat: fix d... |
2962 2963 2964 |
case SIOCGIFMAP: case SIOCSIFMAP: return compat_sioc_ifmap(net, cmd, argp); |
6b96018b2 compat: move sock... |
2965 2966 2967 2968 2969 2970 2971 |
case SIOCADDRT: case SIOCDELRT: return routing_ioctl(net, sock, cmd, argp); case SIOCGSTAMP: return do_siocgstamp(net, sock, cmd, argp); case SIOCGSTAMPNS: return do_siocgstampns(net, sock, cmd, argp); |
590d4693f net/compat: Merge... |
2972 2973 |
case SIOCBONDSLAVEINFOQUERY: case SIOCBONDINFOQUERY: |
a2116ed22 net/compat: fix d... |
2974 |
case SIOCSHWTSTAMP: |
fd468c74b net_tstamp: Add S... |
2975 |
case SIOCGHWTSTAMP: |
590d4693f net/compat: Merge... |
2976 |
return compat_ifr_data_ioctl(net, cmd, argp); |
6b96018b2 compat: move sock... |
2977 2978 2979 2980 2981 2982 2983 2984 2985 2986 2987 |
case FIOSETOWN: case SIOCSPGRP: case FIOGETOWN: case SIOCGPGRP: case SIOCBRADDBR: case SIOCBRDELBR: case SIOCGIFVLAN: case SIOCSIFVLAN: case SIOCADDDLCI: case SIOCDELDLCI: |
c62cce2ca net: add an ioctl... |
2988 |
case SIOCGSKNS: |
6b96018b2 compat: move sock... |
2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 |
return sock_ioctl(file, cmd, arg); case SIOCGIFFLAGS: case SIOCSIFFLAGS: case SIOCGIFMETRIC: case SIOCSIFMETRIC: case SIOCGIFMTU: case SIOCSIFMTU: case SIOCGIFMEM: case SIOCSIFMEM: case SIOCGIFHWADDR: case SIOCSIFHWADDR: case SIOCADDMULTI: case SIOCDELMULTI: case SIOCGIFINDEX: |
6b96018b2 compat: move sock... |
3004 3005 3006 |
case SIOCGIFADDR: case SIOCSIFADDR: case SIOCSIFHWBROADCAST: |
6b96018b2 compat: move sock... |
3007 |
case SIOCDIFADDR: |
6b96018b2 compat: move sock... |
3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 |
case SIOCGIFBRDADDR: case SIOCSIFBRDADDR: case SIOCGIFDSTADDR: case SIOCSIFDSTADDR: case SIOCGIFNETMASK: case SIOCSIFNETMASK: case SIOCSIFPFLAGS: case SIOCGIFPFLAGS: case SIOCGIFTXQLEN: case SIOCSIFTXQLEN: case SIOCBRADDIF: case SIOCBRDELIF: |
9177efd39 net, compat_ioctl... |
3020 3021 3022 3023 |
case SIOCSIFNAME: case SIOCGMIIPHY: case SIOCGMIIREG: case SIOCSMIIREG: |
6b96018b2 compat: move sock... |
3024 3025 3026 |
case SIOCSARP: case SIOCGARP: case SIOCDARP: |
6b96018b2 compat: move sock... |
3027 |
case SIOCATMARK: |
f92d4fc95 kill bond_ioctl() |
3028 3029 3030 3031 |
case SIOCBONDENSLAVE: case SIOCBONDRELEASE: case SIOCBONDSETHWADDR: case SIOCBONDCHANGEACTIVE: |
4cf808e7a kill dev_ifname32() |
3032 |
case SIOCGIFNAME: |
9177efd39 net, compat_ioctl... |
3033 3034 |
return sock_do_ioctl(net, sock, cmd, arg); } |
6b96018b2 compat: move sock... |
3035 3036 |
return -ENOIOCTLCMD; } |
7a229387d net: copy socket ... |
3037 |
|
95c961747 net: cleanup unsi... |
3038 |
static long compat_sock_ioctl(struct file *file, unsigned int cmd, |
89bddce58 [NET] socket: cod... |
3039 |
unsigned long arg) |
89bbfc95d [NET]: allow 32 b... |
3040 3041 3042 |
{ struct socket *sock = file->private_data; int ret = -ENOIOCTLCMD; |
87de87d5e wext: Dispatch an... |
3043 3044 3045 3046 3047 |
struct sock *sk; struct net *net; sk = sock->sk; net = sock_net(sk); |
89bbfc95d [NET]: allow 32 b... |
3048 3049 3050 |
if (sock->ops->compat_ioctl) ret = sock->ops->compat_ioctl(sock, cmd, arg); |
87de87d5e wext: Dispatch an... |
3051 3052 3053 |
if (ret == -ENOIOCTLCMD && (cmd >= SIOCIWFIRST && cmd <= SIOCIWLAST)) ret = compat_wext_handle_ioctl(net, cmd, arg); |
6b96018b2 compat: move sock... |
3054 3055 |
if (ret == -ENOIOCTLCMD) ret = compat_sock_ioctl_trans(file, sock, cmd, arg); |
89bbfc95d [NET]: allow 32 b... |
3056 3057 3058 |
return ret; } #endif |
ac5a488ef [NET]: Round out ... |
3059 3060 3061 3062 |
int kernel_bind(struct socket *sock, struct sockaddr *addr, int addrlen) { return sock->ops->bind(sock, addr, addrlen); } |
c6d409cfd From abbffa2aa9bd... |
3063 |
EXPORT_SYMBOL(kernel_bind); |
ac5a488ef [NET]: Round out ... |
3064 3065 3066 3067 3068 |
int kernel_listen(struct socket *sock, int backlog) { return sock->ops->listen(sock, backlog); } |
c6d409cfd From abbffa2aa9bd... |
3069 |
EXPORT_SYMBOL(kernel_listen); |
ac5a488ef [NET]: Round out ... |
3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 |
int kernel_accept(struct socket *sock, struct socket **newsock, int flags) { struct sock *sk = sock->sk; int err; err = sock_create_lite(sk->sk_family, sk->sk_type, sk->sk_protocol, newsock); if (err < 0) goto done; |
cdfbabfb2 net: Work around ... |
3080 |
err = sock->ops->accept(sock, *newsock, flags, true); |
ac5a488ef [NET]: Round out ... |
3081 3082 |
if (err < 0) { sock_release(*newsock); |
fa8705b00 [NET]: sanitize k... |
3083 |
*newsock = NULL; |
ac5a488ef [NET]: Round out ... |
3084 3085 3086 3087 |
goto done; } (*newsock)->ops = sock->ops; |
1b08534e5 net: Fix module r... |
3088 |
__module_get((*newsock)->ops->owner); |
ac5a488ef [NET]: Round out ... |
3089 3090 3091 3092 |
done: return err; } |
c6d409cfd From abbffa2aa9bd... |
3093 |
EXPORT_SYMBOL(kernel_accept); |
ac5a488ef [NET]: Round out ... |
3094 3095 |
int kernel_connect(struct socket *sock, struct sockaddr *addr, int addrlen, |
4768fbcbc [NET]: Fix whites... |
3096 |
int flags) |
ac5a488ef [NET]: Round out ... |
3097 3098 3099 |
{ return sock->ops->connect(sock, addr, addrlen, flags); } |
c6d409cfd From abbffa2aa9bd... |
3100 |
EXPORT_SYMBOL(kernel_connect); |
ac5a488ef [NET]: Round out ... |
3101 |
|
9b2c45d47 net: make getname... |
3102 |
int kernel_getsockname(struct socket *sock, struct sockaddr *addr) |
ac5a488ef [NET]: Round out ... |
3103 |
{ |
9b2c45d47 net: make getname... |
3104 |
return sock->ops->getname(sock, addr, 0); |
ac5a488ef [NET]: Round out ... |
3105 |
} |
c6d409cfd From abbffa2aa9bd... |
3106 |
EXPORT_SYMBOL(kernel_getsockname); |
ac5a488ef [NET]: Round out ... |
3107 |
|
9b2c45d47 net: make getname... |
3108 |
int kernel_getpeername(struct socket *sock, struct sockaddr *addr) |
ac5a488ef [NET]: Round out ... |
3109 |
{ |
9b2c45d47 net: make getname... |
3110 |
return sock->ops->getname(sock, addr, 1); |
ac5a488ef [NET]: Round out ... |
3111 |
} |
c6d409cfd From abbffa2aa9bd... |
3112 |
EXPORT_SYMBOL(kernel_getpeername); |
ac5a488ef [NET]: Round out ... |
3113 3114 3115 3116 3117 |
int kernel_getsockopt(struct socket *sock, int level, int optname, char *optval, int *optlen) { mm_segment_t oldfs = get_fs(); |
fb8621bb6 net: remove addre... |
3118 3119 |
char __user *uoptval; int __user *uoptlen; |
ac5a488ef [NET]: Round out ... |
3120 |
int err; |
fb8621bb6 net: remove addre... |
3121 3122 |
uoptval = (char __user __force *) optval; uoptlen = (int __user __force *) optlen; |
ac5a488ef [NET]: Round out ... |
3123 3124 |
set_fs(KERNEL_DS); if (level == SOL_SOCKET) |
fb8621bb6 net: remove addre... |
3125 |
err = sock_getsockopt(sock, level, optname, uoptval, uoptlen); |
ac5a488ef [NET]: Round out ... |
3126 |
else |
fb8621bb6 net: remove addre... |
3127 3128 |
err = sock->ops->getsockopt(sock, level, optname, uoptval, uoptlen); |
ac5a488ef [NET]: Round out ... |
3129 3130 3131 |
set_fs(oldfs); return err; } |
c6d409cfd From abbffa2aa9bd... |
3132 |
EXPORT_SYMBOL(kernel_getsockopt); |
ac5a488ef [NET]: Round out ... |
3133 3134 |
int kernel_setsockopt(struct socket *sock, int level, int optname, |
b7058842c net: Make setsock... |
3135 |
char *optval, unsigned int optlen) |
ac5a488ef [NET]: Round out ... |
3136 3137 |
{ mm_segment_t oldfs = get_fs(); |
fb8621bb6 net: remove addre... |
3138 |
char __user *uoptval; |
ac5a488ef [NET]: Round out ... |
3139 |
int err; |
fb8621bb6 net: remove addre... |
3140 |
uoptval = (char __user __force *) optval; |
ac5a488ef [NET]: Round out ... |
3141 3142 |
set_fs(KERNEL_DS); if (level == SOL_SOCKET) |
fb8621bb6 net: remove addre... |
3143 |
err = sock_setsockopt(sock, level, optname, uoptval, optlen); |
ac5a488ef [NET]: Round out ... |
3144 |
else |
fb8621bb6 net: remove addre... |
3145 |
err = sock->ops->setsockopt(sock, level, optname, uoptval, |
ac5a488ef [NET]: Round out ... |
3146 3147 3148 3149 |
optlen); set_fs(oldfs); return err; } |
c6d409cfd From abbffa2aa9bd... |
3150 |
EXPORT_SYMBOL(kernel_setsockopt); |
ac5a488ef [NET]: Round out ... |
3151 3152 3153 3154 3155 3156 3157 3158 3159 |
int kernel_sendpage(struct socket *sock, struct page *page, int offset, size_t size, int flags) { if (sock->ops->sendpage) return sock->ops->sendpage(sock, page, offset, size, flags); return sock_no_sendpage(sock, page, offset, size, flags); } |
c6d409cfd From abbffa2aa9bd... |
3160 |
EXPORT_SYMBOL(kernel_sendpage); |
ac5a488ef [NET]: Round out ... |
3161 |
|
306b13eb3 proto_ops: Add lo... |
3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 |
int kernel_sendpage_locked(struct sock *sk, struct page *page, int offset, size_t size, int flags) { struct socket *sock = sk->sk_socket; if (sock->ops->sendpage_locked) return sock->ops->sendpage_locked(sk, page, offset, size, flags); return sock_no_sendpage_locked(sk, page, offset, size, flags); } EXPORT_SYMBOL(kernel_sendpage_locked); |
91cf45f02 [NET]: Add the he... |
3174 3175 3176 3177 |
int kernel_sock_shutdown(struct socket *sock, enum sock_shutdown_cmd how) { return sock->ops->shutdown(sock, how); } |
91cf45f02 [NET]: Add the he... |
3178 |
EXPORT_SYMBOL(kernel_sock_shutdown); |
113c30759 New kernel functi... |
3179 3180 3181 3182 |
/* This routine returns the IP overhead imposed by a socket i.e. * the length of the underlying IP header, depending on whether * this is an IPv4 or IPv6 socket and the length from IP options turned |
57240d007 l2tp: device MTU ... |
3183 |
* on at the socket. Assumes that the caller has a lock on the socket. |
113c30759 New kernel functi... |
3184 3185 3186 3187 3188 3189 |
*/ u32 kernel_sock_ip_overhead(struct sock *sk) { struct inet_sock *inet; struct ip_options_rcu *opt; u32 overhead = 0; |
113c30759 New kernel functi... |
3190 3191 3192 3193 3194 3195 3196 |
#if IS_ENABLED(CONFIG_IPV6) struct ipv6_pinfo *np; struct ipv6_txoptions *optv6 = NULL; #endif /* IS_ENABLED(CONFIG_IPV6) */ if (!sk) return overhead; |
113c30759 New kernel functi... |
3197 3198 3199 3200 3201 |
switch (sk->sk_family) { case AF_INET: inet = inet_sk(sk); overhead += sizeof(struct iphdr); opt = rcu_dereference_protected(inet->inet_opt, |
614d79c09 socket: fix set n... |
3202 |
sock_owned_by_user(sk)); |
113c30759 New kernel functi... |
3203 3204 3205 3206 3207 3208 3209 3210 3211 |
if (opt) overhead += opt->opt.optlen; return overhead; #if IS_ENABLED(CONFIG_IPV6) case AF_INET6: np = inet6_sk(sk); overhead += sizeof(struct ipv6hdr); if (np) optv6 = rcu_dereference_protected(np->opt, |
614d79c09 socket: fix set n... |
3212 |
sock_owned_by_user(sk)); |
113c30759 New kernel functi... |
3213 3214 3215 3216 3217 3218 3219 3220 3221 |
if (optv6) overhead += (optv6->opt_flen + optv6->opt_nflen); return overhead; #endif /* IS_ENABLED(CONFIG_IPV6) */ default: /* Returns 0 overhead if the socket is not ipv4 or ipv6 */ return overhead; } } EXPORT_SYMBOL(kernel_sock_ip_overhead); |