Re: sys/net/pf_ioctl.c: out of bounds read in pf_rule_copyin

Alexandr Nedvedicky <[email protected]>
Newsgroups gmane.os.openbsd.tech
Message-ID <[email protected]>
Hello,

On Mon, Jul 06, 2026 at 04:02:48PM +0200, Johann H??pfner wrote:
> >     I'm not sure how diff below helps. My understanding of the crash
> >     is that kasan fuzzer tries to load memory which is shorter than
> >     sizeof (struct pfioc_rule), the pfioc_rule size on amd64 is 3424.
>
> looking at the backtrace from the other kasan implementation running in
> syzbot, the pfioc_rule allocation is at arg index 2 of pioctl valued
> from = 0xffff8000012f0000 and invalid access occurs for address
> from + sizeof(struct pfioc_rule) = 0xffff8000012f0d60. Thus the invalid
> access is the first byte after the end of the allocation.
>
> | panic: Caught invalid memory access at ffff8000012f0d60 size 1 op 0
> | panic(ffffffff82a63def) at panic+0x270 sys/kern/subr_prf.c:198
> | __asan_load1_noabort(ffff8000012f0d60) at __asan_load1_noabort+0xed
> | strlcpy(ffff800000f4c650,ffff8000012f0928,40) at strlcpy+0x19b sys/lib/libkern/strlcpy.c:44
> | pf_rule_copyin(ffff8000012f0810,ffff800000f4c538) at pf_rule_copyin+0x52b sys/net/pf_ioctl.c:4047
> | pfioctl(24900,cd604404,ffff8000012f0000,2,ffff80003533ad28) at pfioctl+0x1b3d sys/net/pf_ioctl.c:-1
>
> > Also I've tried simple shell script on my pf test machine. the machine did
> > not crash.
>
> Yes, that is expected without address sanitizer as there will probably be
> a null-byte somewhere in the rest of the malloc bucket after the 3242
> bytes in from preventing a overflow beyond the mapped page.
>
> From the testing I did last saturday, the error occurs in the implicit
> strlen(src) done by strlcpy and my patch cuts that short. The backtrace
> above implicates exactly the corresponding line (strlcpy.c:44).

    thanks for clarification, after poking to strlcpy():

 37                 }
 38         }
 39
 40         /* Not enough room in dst, add NUL and traverse rest of src. */
 41         if (nleft == 0) {
 42                 if (dsize != 0)
 43                         *dst = '\0';            /* NUL-terminate dst */
 44                 while (*src++)
 45                         ;
 46         }
 47
 48         return(src - osrc - 1); /* count does not include NUL */

I see the problem now. I was not aware of the implicit (stlen()) line 44,
(yes, entirely my ignorance).

your diff makes sense, it is OK by me now.

thanks and
regards
sashan
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.