git: e92b9a9eaa64 - main - linux(4): Add a helper to copyout getsockopt value
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 28 May 2022 20:53:17 UTC
The branch main has been updated by dchagin:
URL: https://cgit.FreeBSD.org/src/commit/?id=e92b9a9eaa646bc1037af2a838270c43ea607d55
commit e92b9a9eaa646bc1037af2a838270c43ea607d55
Author: Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2022-05-28 20:30:22 +0000
Commit: Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-05-28 20:30:22 +0000
linux(4): Add a helper to copyout getsockopt value
For getsockopt(), optlen is a value-result argument, which is modified
on return to indicate the actual size of the value returned.
For some cases this was missed, fixed.
MFC after: 2 weeks
---
sys/compat/linux/linux_socket.c | 33 +++++++++++++++++++++++----------
1 file changed, 23 insertions(+), 10 deletions(-)
diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c
index 8aa425bc14c0..0c003cd5729f 100644
--- a/sys/compat/linux/linux_socket.c
+++ b/sys/compat/linux/linux_socket.c
@@ -1924,6 +1924,18 @@ linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
return (error);
}
+static int
+linux_sockopt_copyout(struct thread *td, void *val, socklen_t len,
+ struct linux_getsockopt_args *args)
+{
+ int error;
+
+ error = copyout(val, PTRIN(args->optval), len);
+ if (error == 0)
+ error = copyout(&len, PTRIN(args->optlen), sizeof(len));
+ return (error);
+}
+
static int
linux_getsockopt_so_peergroups(struct thread *td,
struct linux_getsockopt_args *args)
@@ -1976,13 +1988,11 @@ linux_getsockopt_so_peersec(struct thread *td,
return (error);
}
- error = copyout(SECURITY_CONTEXT_STRING,
- PTRIN(args->optval), sizeof(SECURITY_CONTEXT_STRING));
- if (error == 0)
- error = copyout(&len, PTRIN(args->optlen), sizeof(len));
- return (error);
+ return (linux_sockopt_copyout(td, SECURITY_CONTEXT_STRING,
+ len, args));
}
+
int
linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
{
@@ -2021,8 +2031,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
return (error);
linux_tv.tv_sec = tv.tv_sec;
linux_tv.tv_usec = tv.tv_usec;
- return (copyout(&linux_tv, PTRIN(args->optval),
- sizeof(linux_tv)));
+ return (linux_sockopt_copyout(td, &linux_tv,
+ sizeof(linux_tv), args));
/* NOTREACHED */
case LOCAL_PEERCRED:
if (args->optlen < sizeof(lxu))
@@ -2040,7 +2050,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
lxu.pid = xu.cr_pid;
lxu.uid = xu.cr_uid;
lxu.gid = xu.cr_gid;
- return (copyout(&lxu, PTRIN(args->optval), sizeof(lxu)));
+ return (linux_sockopt_copyout(td, &lxu,
+ sizeof(lxu), args));
/* NOTREACHED */
case SO_ERROR:
len = sizeof(newval);
@@ -2049,7 +2060,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
if (error != 0)
return (error);
newval = -bsd_to_linux_errno(newval);
- return (copyout(&newval, PTRIN(args->optval), len));
+ return (linux_sockopt_copyout(td, &newval,
+ len, args));
/* NOTREACHED */
case SO_DOMAIN:
len = sizeof(newval);
@@ -2060,7 +2072,8 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
newval = bsd_to_linux_domain(newval);
if (newval == -1)
return (ENOPROTOOPT);
- return (copyout(&newval, PTRIN(args->optval), len));
+ return (linux_sockopt_copyout(td, &newval,
+ len, args));
/* NOTREACHED */
default:
break;