Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 26 Aug 2021 18:15:11 GMT
From:      Warner Losh <imp@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 620cf65c2bc4 - main - netinet: prevent NULL pointer dereference in in_aifaddr_ioctl()
Message-ID:  <202108261815.17QIFBTf078441@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by imp:

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

commit 620cf65c2bc4035a07e1152da419a4e60d36ff9b
Author:     Artem Khramov <akhramov@pm.me>
AuthorDate: 2021-08-24 14:26:35 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2021-08-26 18:08:03 +0000

    netinet: prevent NULL pointer dereference in in_aifaddr_ioctl()
    
    It appears that maliciously crafted ifaliasreq can lead to NULL
    pointer dereference in in_aifaddr_ioctl(). In order to replicate
    that, one needs to
    
    1. Ensure that carp(4) is not loaded
    
    2. Issue SIOCAIFADDR call setting ifra_vhid field of the request
       to a negative value.
    
    A repro code would look like this.
    
    int main() {
        struct ifaliasreq req;
        struct sockaddr_in sin, mask;
        int fd, error;
    
        bzero(&sin, sizeof(struct sockaddr_in));
        bzero(&mask, sizeof(struct sockaddr_in));
    
        sin.sin_len = sizeof(struct sockaddr_in);
        sin.sin_family = AF_INET;
        sin.sin_addr.s_addr = inet_addr("192.168.88.2");
    
        mask.sin_len = sizeof(struct sockaddr_in);
        mask.sin_family = AF_INET;
        mask.sin_addr.s_addr = inet_addr("255.255.255.0");
    
        fd = socket(AF_INET, SOCK_DGRAM, 0);
        if (fd < 0)
            return (-1);
    
        memset(&req, 0, sizeof(struct ifaliasreq));
        strlcpy(req.ifra_name, "lo0", sizeof(req.ifra_name));
        memcpy(&req.ifra_addr, &sin, sin.sin_len);
        memcpy(&req.ifra_mask, &mask, mask.sin_len);
        req.ifra_vhid = -1;
    
        return ioctl(fd, SIOCAIFADDR, (char *)&req);
    }
    
    To fix, discard both positive and negative vhid values in
    in_aifaddr_ioctl, if carp(4) is not loaded. This prevents NULL pointer
    dereference and kernel panic.
    
    Reviewed by:    imp@
    Pull Request:   https://github.com/freebsd/freebsd-src/pull/530
---
 sys/netinet/in.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sys/netinet/in.c b/sys/netinet/in.c
index d1dd2b31b6ef..f9b46b414007 100644
--- a/sys/netinet/in.c
+++ b/sys/netinet/in.c
@@ -376,7 +376,7 @@ in_aifaddr_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp, struct thread *td)
 	    (dstaddr->sin_len != sizeof(struct sockaddr_in) ||
 	     dstaddr->sin_addr.s_addr == INADDR_ANY))
 		return (EDESTADDRREQ);
-	if (vhid > 0 && carp_attach_p == NULL)
+	if (vhid != 0 && carp_attach_p == NULL)
 		return (EPROTONOSUPPORT);
 
 	/*



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202108261815.17QIFBTf078441>