mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
atm: convert to getsockopt_iter
Convert the ATM SVC and PVC sockets, along with the shared vcc_getsockopt() helper, 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) - Use copy_to_iter() instead of put_user()/copy_to_user() Acked-by: Stanislav Fomichev <sdf@fomichev.me> Signed-off-by: Breno Leitao <leitao@debian.org> Link: https://patch.msgid.link/20260520-getsock_four-v3-2-b8c0b16b7780@debian.org Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
committed by
Jakub Kicinski
parent
347fdd4df8
commit
4177767daf
@@ -23,6 +23,7 @@
|
||||
#include <net/sock.h> /* struct sock */
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/poll.h>
|
||||
#include <linux/uio.h>
|
||||
|
||||
#include <linux/atomic.h>
|
||||
|
||||
@@ -797,13 +798,13 @@ int vcc_setsockopt(struct socket *sock, int level, int optname,
|
||||
}
|
||||
|
||||
int vcc_getsockopt(struct socket *sock, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
sockopt_t *opt)
|
||||
{
|
||||
struct atm_vcc *vcc;
|
||||
int val;
|
||||
int len;
|
||||
|
||||
if (get_user(len, optlen))
|
||||
return -EFAULT;
|
||||
len = opt->optlen;
|
||||
if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
|
||||
return -EINVAL;
|
||||
|
||||
@@ -812,11 +813,13 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
|
||||
case SO_ATMQOS:
|
||||
if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
|
||||
return -EINVAL;
|
||||
return copy_to_user(optval, &vcc->qos, sizeof(vcc->qos))
|
||||
return copy_to_iter(&vcc->qos, sizeof(vcc->qos),
|
||||
&opt->iter_out) != sizeof(vcc->qos)
|
||||
? -EFAULT : 0;
|
||||
case SO_SETCLP:
|
||||
return put_user(vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0,
|
||||
(unsigned long __user *)optval) ? -EFAULT : 0;
|
||||
val = vcc->atm_options & ATM_ATMOPT_CLP ? 1 : 0;
|
||||
return copy_to_iter(&val, sizeof(val), &opt->iter_out) !=
|
||||
sizeof(val) ? -EFAULT : 0;
|
||||
case SO_ATMPVC:
|
||||
{
|
||||
struct sockaddr_atmpvc pvc;
|
||||
@@ -828,7 +831,8 @@ int vcc_getsockopt(struct socket *sock, int level, int optname,
|
||||
pvc.sap_addr.itf = vcc->dev->number;
|
||||
pvc.sap_addr.vpi = vcc->vpi;
|
||||
pvc.sap_addr.vci = vcc->vci;
|
||||
return copy_to_user(optval, &pvc, sizeof(pvc)) ? -EFAULT : 0;
|
||||
return copy_to_iter(&pvc, sizeof(pvc), &opt->iter_out) !=
|
||||
sizeof(pvc) ? -EFAULT : 0;
|
||||
}
|
||||
default:
|
||||
return -EINVAL;
|
||||
|
||||
@@ -23,7 +23,7 @@ int vcc_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
|
||||
int vcc_setsockopt(struct socket *sock, int level, int optname,
|
||||
sockptr_t optval, unsigned int optlen);
|
||||
int vcc_getsockopt(struct socket *sock, int level, int optname,
|
||||
char __user *optval, int __user *optlen);
|
||||
sockopt_t *opt);
|
||||
void vcc_process_recv_queue(struct atm_vcc *vcc);
|
||||
|
||||
int atmpvc_init(void);
|
||||
|
||||
@@ -75,13 +75,13 @@ static int pvc_setsockopt(struct socket *sock, int level, int optname,
|
||||
}
|
||||
|
||||
static int pvc_getsockopt(struct socket *sock, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
sockopt_t *opt)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
int error;
|
||||
|
||||
lock_sock(sk);
|
||||
error = vcc_getsockopt(sock, level, optname, optval, optlen);
|
||||
error = vcc_getsockopt(sock, level, optname, opt);
|
||||
release_sock(sk);
|
||||
return error;
|
||||
}
|
||||
@@ -122,7 +122,7 @@ static const struct proto_ops pvc_proto_ops = {
|
||||
.listen = sock_no_listen,
|
||||
.shutdown = pvc_shutdown,
|
||||
.setsockopt = pvc_setsockopt,
|
||||
.getsockopt = pvc_getsockopt,
|
||||
.getsockopt_iter = pvc_getsockopt,
|
||||
.sendmsg = vcc_sendmsg,
|
||||
.recvmsg = vcc_recvmsg,
|
||||
.mmap = sock_no_mmap,
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <net/sock.h> /* for sock_no_* */
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/uio.h>
|
||||
#include <linux/export.h>
|
||||
|
||||
#include "resources.h"
|
||||
@@ -501,25 +502,23 @@ static int svc_setsockopt(struct socket *sock, int level, int optname,
|
||||
}
|
||||
|
||||
static int svc_getsockopt(struct socket *sock, int level, int optname,
|
||||
char __user *optval, int __user *optlen)
|
||||
sockopt_t *opt)
|
||||
{
|
||||
struct sock *sk = sock->sk;
|
||||
int error = 0, len;
|
||||
|
||||
lock_sock(sk);
|
||||
if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
|
||||
error = vcc_getsockopt(sock, level, optname, optval, optlen);
|
||||
goto out;
|
||||
}
|
||||
if (get_user(len, optlen)) {
|
||||
error = -EFAULT;
|
||||
error = vcc_getsockopt(sock, level, optname, opt);
|
||||
goto out;
|
||||
}
|
||||
len = opt->optlen;
|
||||
if (len != sizeof(struct atm_sap)) {
|
||||
error = -EINVAL;
|
||||
goto out;
|
||||
}
|
||||
if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
|
||||
if (copy_to_iter(&ATM_SD(sock)->sap, sizeof(struct atm_sap),
|
||||
&opt->iter_out) != sizeof(struct atm_sap)) {
|
||||
error = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
@@ -650,7 +649,7 @@ static const struct proto_ops svc_proto_ops = {
|
||||
.listen = svc_listen,
|
||||
.shutdown = svc_shutdown,
|
||||
.setsockopt = svc_setsockopt,
|
||||
.getsockopt = svc_getsockopt,
|
||||
.getsockopt_iter = svc_getsockopt,
|
||||
.sendmsg = vcc_sendmsg,
|
||||
.recvmsg = vcc_recvmsg,
|
||||
.mmap = sock_no_mmap,
|
||||
|
||||
Reference in New Issue
Block a user