The branch main has been updated by dchagin:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e92b9a9eaa646bc1037af2a838270c43ea607d55

commit e92b9a9eaa646bc1037af2a838270c43ea607d55
Author:     Dmitry Chagin <dcha...@freebsd.org>
AuthorDate: 2022-05-28 20:30:22 +0000
Commit:     Dmitry Chagin <dcha...@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;

Reply via email to