The branch releng/13.1 has been updated by emaste:

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

commit 9d354cf6e141a55ad1ef0cb85316f39013d594d2
Author:     Vincenzo Maffione <[email protected]>
AuthorDate: 2022-03-16 06:57:54 +0000
Commit:     Ed Maste <[email protected]>
CommitDate: 2022-04-06 03:23:51 +0000

    netmap: Fix integer overflow in nmreq_copyin
    
    An unsanitized field in an option could be abused, causing an integer
    overflow followed by kernel memory corruption. This might be used
    to escape jails/containers.
    
    Reported by: Reno Robert and Lucas Leong (@_wmliang_) of Trend Micro
    Zero Day Initiative
    Security: CVE-2022-23085
    
    (cherry picked from commit 694ea59c7021c25417e6d516362d2f59b4e2c343)
    (cherry picked from commit 9df8dd3ea36c8b3abe8fc182647472ca9cd83efd)
    
    Approved by:    so, re (implicit)
---
 sys/dev/netmap/netmap.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sys/dev/netmap/netmap.c b/sys/dev/netmap/netmap.c
index f9698096b47a..0c04098bb401 100644
--- a/sys/dev/netmap/netmap.c
+++ b/sys/dev/netmap/netmap.c
@@ -3096,7 +3096,7 @@ nmreq_opt_size_by_type(uint32_t nro_reqtype, uint64_t 
nro_size)
 int
 nmreq_copyin(struct nmreq_header *hdr, int nr_body_is_user)
 {
-       size_t rqsz, optsz, bufsz;
+       size_t rqsz, optsz, bufsz, optbodysz;
        int error = 0;
        char *ker = NULL, *p;
        struct nmreq_option **next, *src, **opt_tab;
@@ -3144,8 +3144,18 @@ nmreq_copyin(struct nmreq_header *hdr, int 
nr_body_is_user)
                error = copyin(src, &buf, sizeof(*src));
                if (error)
                        goto out_err;
+               /* Validate nro_size to avoid integer overflow of optsz and 
bufsz. */
+               if (buf.nro_size > NETMAP_REQ_MAXSIZE) {
+                       error = EMSGSIZE;
+                       goto out_err;
+               }
                optsz += sizeof(*src);
-               optsz += nmreq_opt_size_by_type(buf.nro_reqtype, buf.nro_size);
+               optbodysz = nmreq_opt_size_by_type(buf.nro_reqtype, 
buf.nro_size);
+               if (optbodysz > NETMAP_REQ_MAXSIZE) {
+                       error = EMSGSIZE;
+                       goto out_err;
+               }
+               optsz += optbodysz;
                if (rqsz + optsz > NETMAP_REQ_MAXSIZE) {
                        error = EMSGSIZE;
                        goto out_err;

Reply via email to