Convert CAN J1939 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 copy_to_user() - Restructure the chained if/else if (which depended on put_user() being an expression) into a nested if/else block now that opt->optlen = len is a statement - Add linux/uio.h for copy_to_iter() Signed-off-by: Breno Leitao <[email protected]> --- net/can/j1939/socket.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/net/can/j1939/socket.c b/net/can/j1939/socket.c index 50a598ef5fd4a..d0c6ce607b0dc 100644 --- a/net/can/j1939/socket.c +++ b/net/can/j1939/socket.c @@ -17,6 +17,7 @@ #include <linux/can/skb.h> #include <linux/errqueue.h> #include <linux/if_arp.h> +#include <linux/uio.h> #include <net/can.h> #include "j1939-priv.h" @@ -767,7 +768,7 @@ static int j1939_sk_setsockopt(struct socket *sock, int level, int optname, } static int j1939_sk_getsockopt(struct socket *sock, int level, int optname, - char __user *optval, int __user *optlen) + sockopt_t *opt) { struct sock *sk = sock->sk; struct j1939_sock *jsk = j1939_sk(sk); @@ -779,8 +780,7 @@ static int j1939_sk_getsockopt(struct socket *sock, int level, int optname, if (level != SOL_CAN_J1939) return -EINVAL; - if (get_user(ulen, optlen)) - return -EFAULT; + ulen = opt->optlen; if (ulen < 0) return -EINVAL; @@ -804,11 +804,16 @@ static int j1939_sk_getsockopt(struct socket *sock, int level, int optname, * but most sockopt's are 'int' properties, and have 'len' & 'val' * left unchanged, but instead modified 'tmp' */ - if (len > ulen) - ret = -EFAULT; - else if (put_user(len, optlen)) + if (len > ulen) { ret = -EFAULT; - else if (copy_to_user(optval, val, len)) + goto no_copy; + } + + opt->optlen = len; + /* Even if the copy below fails, we want to update optlen. This is + * a bit confusing, but, it preserves the original behaviour + */ + if (copy_to_iter(val, len, &opt->iter_out) != len) ret = -EFAULT; else ret = 0; @@ -1385,7 +1390,7 @@ static const struct proto_ops j1939_ops = { .listen = sock_no_listen, .shutdown = sock_no_shutdown, .setsockopt = j1939_sk_setsockopt, - .getsockopt = j1939_sk_getsockopt, + .getsockopt_iter = j1939_sk_getsockopt, .sendmsg = j1939_sk_sendmsg, .recvmsg = j1939_sk_recvmsg, .mmap = sock_no_mmap, -- 2.52.0

