Convert LLC socket's getsockopt implementation to use the new getsockopt_iter callback with sockopt_t.
Key changes: - Replace (char __user *optval, int __user *optlen) with sockopt_t *opt - Use opt->optlen for buffer length (input) and returned size (output) - Use copy_to_iter() instead of put_user()/copy_to_user() - Add linux/uio.h for copy_to_iter() Signed-off-by: Breno Leitao <[email protected]> --- net/llc/af_llc.c | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 1b210db3119e8..7d723f0bd26c2 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -27,6 +27,7 @@ #include <linux/init.h> #include <linux/slab.h> #include <linux/sched/signal.h> +#include <linux/uio.h> #include <net/llc.h> #include <net/llc_sap.h> @@ -1172,19 +1173,16 @@ static int llc_ui_setsockopt(struct socket *sock, int level, int optname, * Get connection specific socket information. */ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) + sockopt_t *opt) { struct sock *sk = sock->sk; struct llc_sock *llc = llc_sk(sk); - int val = 0, len = 0, rc = -EINVAL; + int val = 0, len, rc = -EINVAL; lock_sock(sk); if (unlikely(level != SOL_LLC)) goto out; - rc = get_user(len, optlen); - if (rc) - goto out; - rc = -EINVAL; + len = opt->optlen; if (len != sizeof(int)) goto out; switch (optname) { @@ -1212,7 +1210,8 @@ static int llc_ui_getsockopt(struct socket *sock, int level, int optname, goto out; } rc = 0; - if (put_user(len, optlen) || copy_to_user(optval, &val, len)) + opt->optlen = len; + if (copy_to_iter(&val, len, &opt->iter_out) != len) rc = -EFAULT; out: release_sock(sk); @@ -1239,7 +1238,7 @@ static const struct proto_ops llc_ui_ops = { .listen = llc_ui_listen, .shutdown = llc_ui_shutdown, .setsockopt = llc_ui_setsockopt, - .getsockopt = llc_ui_getsockopt, + .getsockopt_iter = llc_ui_getsockopt, .sendmsg = llc_ui_sendmsg, .recvmsg = llc_ui_recvmsg, .mmap = sock_no_mmap, -- 2.52.0

