#include <linux/rhashtable.h>
#include <linux/sched/signal.h>
+#include <linux/uio.h>
#include <trace/events/sock.h>
#include "core.h"
* @sock: socket structure
* @lvl: option level
* @opt: option identifier
- * @ov: receptacle for option value
- * @ol: receptacle for length of option value
+ * @sopt: socket option container (input buffer length, output value/length)
*
* For stream sockets only, returns 0 length result for all IPPROTO_TCP options
* (to ease compatibility).
* Return: 0 on success, errno otherwise
*/
static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
- char __user *ov, int __user *ol)
+ sockopt_t *sopt)
{
struct sock *sk = sock->sk;
struct tipc_sock *tsk = tipc_sk(sk);
struct tipc_service_range seq;
int len, scope;
+ int res = 0;
u32 value;
- int res;
- if ((lvl == IPPROTO_TCP) && (sock->type == SOCK_STREAM))
- return put_user(0, ol);
+ if (lvl == IPPROTO_TCP && sock->type == SOCK_STREAM) {
+ sopt->optlen = 0;
+ return 0;
+ }
if (lvl != SOL_TIPC)
return -ENOPROTOOPT;
- res = get_user(len, ol);
- if (res)
- return res;
+ len = sopt->optlen;
lock_sock(sk);
break;
case TIPC_CONN_TIMEOUT:
value = tsk->conn_timeout;
- /* no need to set "res", since already 0 at this point */
break;
case TIPC_NODE_RECVQ_DEPTH:
value = 0; /* was tipc_queue_size, now obsolete */
release_sock(sk);
if (res)
- return res; /* "get" failed */
+ return res;
if (len < sizeof(value))
return -EINVAL;
- if (copy_to_user(ov, &value, sizeof(value)))
+ if (copy_to_iter(&value, sizeof(value), &sopt->iter_out) !=
+ sizeof(value))
return -EFAULT;
+ sopt->optlen = sizeof(value);
- return put_user(sizeof(value), ol);
+ return 0;
}
static int tipc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
.listen = sock_no_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_sendmsg,
.recvmsg = tipc_recvmsg,
.mmap = sock_no_mmap,
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_send_packet,
.recvmsg = tipc_recvmsg,
.mmap = sock_no_mmap,
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
- .getsockopt = tipc_getsockopt,
+ .getsockopt_iter = tipc_getsockopt,
.sendmsg = tipc_sendstream,
.recvmsg = tipc_recvstream,
.mmap = sock_no_mmap,