diff options
-rw-r--r-- | include/linux/net.h | 6 | ||||
-rw-r--r-- | net/socket.c | 21 |
2 files changed, 27 insertions, 0 deletions
diff --git a/include/linux/net.h b/include/linux/net.h index 152fa6551fd8..84a490e5f0a1 100644 --- a/include/linux/net.h +++ b/include/linux/net.h | |||
@@ -143,6 +143,8 @@ struct proto_ops { | |||
143 | struct poll_table_struct *wait); | 143 | struct poll_table_struct *wait); |
144 | int (*ioctl) (struct socket *sock, unsigned int cmd, | 144 | int (*ioctl) (struct socket *sock, unsigned int cmd, |
145 | unsigned long arg); | 145 | unsigned long arg); |
146 | int (*compat_ioctl) (struct socket *sock, unsigned int cmd, | ||
147 | unsigned long arg); | ||
146 | int (*listen) (struct socket *sock, int len); | 148 | int (*listen) (struct socket *sock, int len); |
147 | int (*shutdown) (struct socket *sock, int flags); | 149 | int (*shutdown) (struct socket *sock, int flags); |
148 | int (*setsockopt)(struct socket *sock, int level, | 150 | int (*setsockopt)(struct socket *sock, int level, |
@@ -251,6 +253,8 @@ SOCKCALL_UWRAP(name, poll, (struct file *file, struct socket *sock, struct poll_ | |||
251 | (file, sock, wait)) \ | 253 | (file, sock, wait)) \ |
252 | SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \ | 254 | SOCKCALL_WRAP(name, ioctl, (struct socket *sock, unsigned int cmd, \ |
253 | unsigned long arg), (sock, cmd, arg)) \ | 255 | unsigned long arg), (sock, cmd, arg)) \ |
256 | SOCKCALL_WRAP(name, compat_ioctl, (struct socket *sock, unsigned int cmd, \ | ||
257 | unsigned long arg), (sock, cmd, arg)) \ | ||
254 | SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ | 258 | SOCKCALL_WRAP(name, listen, (struct socket *sock, int len), (sock, len)) \ |
255 | SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ | 259 | SOCKCALL_WRAP(name, shutdown, (struct socket *sock, int flags), (sock, flags)) \ |
256 | SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ | 260 | SOCKCALL_WRAP(name, setsockopt, (struct socket *sock, int level, int optname, \ |
@@ -275,6 +279,7 @@ static const struct proto_ops name##_ops = { \ | |||
275 | .getname = __lock_##name##_getname, \ | 279 | .getname = __lock_##name##_getname, \ |
276 | .poll = __lock_##name##_poll, \ | 280 | .poll = __lock_##name##_poll, \ |
277 | .ioctl = __lock_##name##_ioctl, \ | 281 | .ioctl = __lock_##name##_ioctl, \ |
282 | .compat_ioctl = __lock_##name##_compat_ioctl, \ | ||
278 | .listen = __lock_##name##_listen, \ | 283 | .listen = __lock_##name##_listen, \ |
279 | .shutdown = __lock_##name##_shutdown, \ | 284 | .shutdown = __lock_##name##_shutdown, \ |
280 | .setsockopt = __lock_##name##_setsockopt, \ | 285 | .setsockopt = __lock_##name##_setsockopt, \ |
@@ -283,6 +288,7 @@ static const struct proto_ops name##_ops = { \ | |||
283 | .recvmsg = __lock_##name##_recvmsg, \ | 288 | .recvmsg = __lock_##name##_recvmsg, \ |
284 | .mmap = __lock_##name##_mmap, \ | 289 | .mmap = __lock_##name##_mmap, \ |
285 | }; | 290 | }; |
291 | |||
286 | #endif | 292 | #endif |
287 | 293 | ||
288 | #define MODULE_ALIAS_NETPROTO(proto) \ | 294 | #define MODULE_ALIAS_NETPROTO(proto) \ |
diff --git a/net/socket.c b/net/socket.c index e3c21d5ec288..e2d5bae994de 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -107,6 +107,10 @@ static unsigned int sock_poll(struct file *file, | |||
107 | struct poll_table_struct *wait); | 107 | struct poll_table_struct *wait); |
108 | static long sock_ioctl(struct file *file, | 108 | static long sock_ioctl(struct file *file, |
109 | unsigned int cmd, unsigned long arg); | 109 | unsigned int cmd, unsigned long arg); |
110 | #ifdef CONFIG_COMPAT | ||
111 | static long compat_sock_ioctl(struct file *file, | ||
112 | unsigned int cmd, unsigned long arg); | ||
113 | #endif | ||
110 | static int sock_fasync(int fd, struct file *filp, int on); | 114 | static int sock_fasync(int fd, struct file *filp, int on); |
111 | static ssize_t sock_readv(struct file *file, const struct iovec *vector, | 115 | static ssize_t sock_readv(struct file *file, const struct iovec *vector, |
112 | unsigned long count, loff_t *ppos); | 116 | unsigned long count, loff_t *ppos); |
@@ -128,6 +132,9 @@ static struct file_operations socket_file_ops = { | |||
128 | .aio_write = sock_aio_write, | 132 | .aio_write = sock_aio_write, |
129 | .poll = sock_poll, | 133 | .poll = sock_poll, |
130 | .unlocked_ioctl = sock_ioctl, | 134 | .unlocked_ioctl = sock_ioctl, |
135 | #ifdef CONFIG_COMPAT | ||
136 | .compat_ioctl = compat_sock_ioctl, | ||
137 | #endif | ||
131 | .mmap = sock_mmap, | 138 | .mmap = sock_mmap, |
132 | .open = sock_no_open, /* special open code to disallow open via /proc */ | 139 | .open = sock_no_open, /* special open code to disallow open via /proc */ |
133 | .release = sock_close, | 140 | .release = sock_close, |
@@ -2136,6 +2143,20 @@ void socket_seq_show(struct seq_file *seq) | |||
2136 | } | 2143 | } |
2137 | #endif /* CONFIG_PROC_FS */ | 2144 | #endif /* CONFIG_PROC_FS */ |
2138 | 2145 | ||
2146 | #ifdef CONFIG_COMPAT | ||
2147 | static long compat_sock_ioctl(struct file *file, unsigned cmd, | ||
2148 | unsigned long arg) | ||
2149 | { | ||
2150 | struct socket *sock = file->private_data; | ||
2151 | int ret = -ENOIOCTLCMD; | ||
2152 | |||
2153 | if (sock->ops->compat_ioctl) | ||
2154 | ret = sock->ops->compat_ioctl(sock, cmd, arg); | ||
2155 | |||
2156 | return ret; | ||
2157 | } | ||
2158 | #endif | ||
2159 | |||
2139 | /* ABI emulation layers need these two */ | 2160 | /* ABI emulation layers need these two */ |
2140 | EXPORT_SYMBOL(move_addr_to_kernel); | 2161 | EXPORT_SYMBOL(move_addr_to_kernel); |
2141 | EXPORT_SYMBOL(move_addr_to_user); | 2162 | EXPORT_SYMBOL(move_addr_to_user); |