All of lore.kernel.org
 help / color / mirror / Atom feed
From: Dipanjan Das <mail.dipanjan.das@gmail.com>
To: perex@perex.cz, tiwai@suse.com, gregkh@linuxfoundation.org,
	consult.awy@gmail.com, alsa-devel@alsa-project.org,
	linux-kernel@vger.kernel.org
Cc: syzkaller@googlegroups.com, fleischermarius@googlemail.com,
	its.priyanka.bose@gmail.com
Subject: KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params
Date: Fri, 22 Jul 2022 09:37:52 -0700	[thread overview]
Message-ID: <CANX2M5Zw_zW6ez0_wvaXL1pbLnR2jWY=T7MgkT=4a-zNkiwVig@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]

Hi,

We would like to report the following bug which has been found by our
modified version of syzkaller.

======================================================
description: KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params
affected file: sound/core/pcm_native.c
kernel version: 5.10.131
kernel commit: de62055f423f5dcb548f74cebd68f03c8903f73a
git tree: upstream
kernel config: https://syzkaller.appspot.com/x/.config?x=e49433cfed49b7d9
crash reproducer: attached
======================================================
Crash log:
======================================================
BUG: KASAN: vmalloc-out-of-bounds in memset include/linux/string.h:384 [inline]
BUG: KASAN: vmalloc-out-of-bounds in snd_pcm_hw_params+0x19b0/0x1db0
sound/core/pcm_native.c:799
Write of size 2097152 at addr ffffc900113b2000 by task syz-executor.5/14437

CPU: 1 PID: 14437 Comm: syz-executor.5 Tainted: G           OE     5.10.131+ #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x107/0x163 lib/dump_stack.c:118
 print_address_description.constprop.0.cold+0x5/0x4f7 mm/kasan/report.c:385
 __kasan_report mm/kasan/report.c:545 [inline]
 kasan_report.cold+0x1f/0x37 mm/kasan/report.c:562
 check_memory_region_inline mm/kasan/generic.c:194 [inline]
 check_memory_region+0x187/0x1e0 mm/kasan/generic.c:200
 memset+0x20/0x40 mm/kasan/common.c:85
 memset include/linux/string.h:384 [inline]
 snd_pcm_hw_params+0x19b0/0x1db0 sound/core/pcm_native.c:799
 snd_pcm_kernel_ioctl+0xd1/0x240 sound/core/pcm_native.c:3401
 snd_pcm_oss_change_params_locked+0x17b6/0x3aa0 sound/core/oss/pcm_oss.c:965
 snd_pcm_oss_change_params+0x76/0xd0 sound/core/oss/pcm_oss.c:1107
 snd_pcm_oss_make_ready+0xb7/0x170 sound/core/oss/pcm_oss.c:1166
 snd_pcm_oss_set_trigger.isra.0+0x34f/0x770 sound/core/oss/pcm_oss.c:2074
 snd_pcm_oss_poll+0x679/0xb40 sound/core/oss/pcm_oss.c:2858
 vfs_poll include/linux/poll.h:90 [inline]
 do_pollfd fs/select.c:872 [inline]
 do_poll fs/select.c:920 [inline]
 do_sys_poll+0x63c/0xe40 fs/select.c:1014
 __do_sys_poll fs/select.c:1079 [inline]
 __se_sys_poll fs/select.c:1067 [inline]
 __x64_sys_poll+0x18c/0x490 fs/select.c:1067
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f095de4f4ed
Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48
89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d
01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f095bdffbe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000007
RAX: ffffffffffffffda RBX: 00007f095df6df60 RCX: 00007f095de4f4ed
RDX: 0000000000000009 RSI: 0000000000000001 RDI: 00000000200000c0
RBP: 00007f095bdffc40 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000001d
R13: 00007ffff286ceff R14: 00007f095df6df60 R15: 00007f095bdffd80


Memory state around the buggy address:
 ffffc900115b1d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffffc900115b1d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffffc900115b1e00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
                   ^
 ffffc900115b1e80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
 ffffc900115b1f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
==================================================================

-- 
Thanks and Regards,

Dipanjan

[-- Attachment #2: repro.syz --]
[-- Type: application/octet-stream, Size: 123 bytes --]

r0 = openat$adsp1(0xffffffffffffff9c, &(0x7f0000000040), 0x0, 0x0)
poll(&(0x7f00000000c0)=[{r0}], 0x1, 0x9) (fail_nth: 11)

[-- Attachment #3: repro.c --]
[-- Type: text/x-csrc, Size: 8786 bytes --]

// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>

static void use_temporary_dir(void)
{
	char tmpdir_template[] = "./syzkaller.XXXXXX";
	char* tmpdir = mkdtemp(tmpdir_template);
	if (!tmpdir)
	exit(1);
	if (chmod(tmpdir, 0777))
	exit(1);
	if (chdir(tmpdir))
	exit(1);
}

static bool write_file(const char* file, const char* what, ...)
{
	char buf[1024];
	va_list args;
	va_start(args, what);
	vsnprintf(buf, sizeof(buf), what, args);
	va_end(args);
	buf[sizeof(buf) - 1] = 0;
	int len = strlen(buf);
	int fd = open(file, O_WRONLY | O_CLOEXEC);
	if (fd == -1)
		return false;
	if (write(fd, buf, len) != len) {
		int err = errno;
		close(fd);
		errno = err;
		return false;
	}
	close(fd);
	return true;
}

struct nlmsg {
	char* pos;
	int nesting;
	struct nlattr* nested[8];
	char buf[4096];
};

static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
			 const void* data, int size)
{
	memset(nlmsg, 0, sizeof(*nlmsg));
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_type = typ;
	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
	memcpy(hdr + 1, data, size);
	nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}

static void netlink_attr(struct nlmsg* nlmsg, int typ,
			 const void* data, int size)
{
	struct nlattr* attr = (struct nlattr*)nlmsg->pos;
	attr->nla_len = sizeof(*attr) + size;
	attr->nla_type = typ;
	if (size > 0)
		memcpy(attr + 1, data, size);
	nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}

static void netlink_nest(struct nlmsg* nlmsg, int typ)
{
	struct nlattr* attr = (struct nlattr*)nlmsg->pos;
	attr->nla_type = typ;
	nlmsg->pos += sizeof(*attr);
	nlmsg->nested[nlmsg->nesting++] = attr;
}

static void netlink_done(struct nlmsg* nlmsg)
{
	struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
	attr->nla_len = nlmsg->pos - (char*)attr;
}

static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
			    uint16_t reply_type, int* reply_len, bool dofail)
{
	if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
	exit(1);
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
	struct sockaddr_nl addr;
	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
	if (n != (ssize_t)hdr->nlmsg_len) {
		if (dofail)
	exit(1);
		return -1;
	}
	n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	if (reply_len)
		*reply_len = 0;
	if (n < 0) {
		if (dofail)
	exit(1);
		return -1;
	}
	if (n < (ssize_t)sizeof(struct nlmsghdr)) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type == NLMSG_DONE)
		return 0;
	if (reply_len && hdr->nlmsg_type == reply_type) {
		*reply_len = n;
		return 0;
	}
	if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type != NLMSG_ERROR) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	errno = -((struct nlmsgerr*)(hdr + 1))->error;
	return -errno;
}

static int netlink_send(struct nlmsg* nlmsg, int sock)
{
	return netlink_send_ext(nlmsg, sock, 0, NULL, true);
}

static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
	struct genlmsghdr genlhdr;
	memset(&genlhdr, 0, sizeof(genlhdr));
	genlhdr.cmd = CTRL_CMD_GETFAMILY;
	netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
	netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
	int n = 0;
	int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
	if (err < 0) {
		return -1;
	}
	uint16_t id = 0;
	struct nlattr* attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr)));
	for (; (char*)attr < nlmsg->buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
		if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
			id = *(uint16_t*)(attr + 1);
			break;
		}
	}
	if (!id) {
		errno = EINVAL;
		return -1;
	}
	recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	return id;
}

static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
				    const char* name)
{
	struct ifinfomsg hdr;
	memset(&hdr, 0, sizeof(hdr));
	netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr, sizeof(hdr));
	if (name)
		netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
	netlink_nest(nlmsg, IFLA_LINKINFO);
	netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
}

static void netlink_device_change(struct nlmsg* nlmsg, int sock, const char* name, bool up,
				  const char* master, const void* mac, int macsize,
				  const char* new_name)
{
	struct ifinfomsg hdr;
	memset(&hdr, 0, sizeof(hdr));
	if (up)
		hdr.ifi_flags = hdr.ifi_change = IFF_UP;
	hdr.ifi_index = if_nametoindex(name);
	netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
	if (new_name)
		netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
	if (master) {
		int ifindex = if_nametoindex(master);
		netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
	}
	if (macsize)
		netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
	int err = netlink_send(nlmsg, sock);
	if (err < 0) {
	}
}

static struct nlmsg nlmsg;

static int inject_fault(int nth)
{
	int fd;
	fd = open("/proc/thread-self/fail-nth", O_RDWR);
	if (fd == -1)
	exit(1);
	char buf[16];
	sprintf(buf, "%d", nth);
	if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
	exit(1);
	return fd;
}

static void setup_fault()
{
	static struct {
		const char* file;
		const char* val;
		bool fatal;
	} files[] = {
	    {"/sys/kernel/debug/failslab/ignore-gfp-wait", "N", true},
	    {"/sys/kernel/debug/fail_futex/ignore-private", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-wait", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/min-order", "0", false},
	};
	unsigned i;
	for (i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
		if (!write_file(files[i].file, files[i].val)) {
			if (files[i].fatal)
	exit(1);
		}
	}
}

#define NL802154_CMD_SET_SHORT_ADDR 11
#define NL802154_ATTR_IFINDEX 3
#define NL802154_ATTR_SHORT_ADDR 10

static void setup_802154()
{
	int sock_route = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (sock_route == -1)
	exit(1);
	int sock_generic = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (sock_generic < 0)
	exit(1);
	int nl802154_family_id = netlink_query_family_id(&nlmsg, sock_generic, "nl802154", true);
	for (int i = 0; i < 2; i++) {
		char devname[] = "wpan0";
		devname[strlen(devname) - 1] += i;
		uint64_t hwaddr = 0xaaaaaaaaaaaa0002 + (i << 8);
		uint16_t shortaddr = 0xaaa0 + i;
		int ifindex = if_nametoindex(devname);
		struct genlmsghdr genlhdr;
		memset(&genlhdr, 0, sizeof(genlhdr));
		genlhdr.cmd = NL802154_CMD_SET_SHORT_ADDR;
		netlink_init(&nlmsg, nl802154_family_id, 0, &genlhdr, sizeof(genlhdr));
		netlink_attr(&nlmsg, NL802154_ATTR_IFINDEX, &ifindex, sizeof(ifindex));
		netlink_attr(&nlmsg, NL802154_ATTR_SHORT_ADDR, &shortaddr, sizeof(shortaddr));
		int err = netlink_send(&nlmsg, sock_generic);
		if (err < 0) {
		}
		netlink_device_change(&nlmsg, sock_route, devname, true, 0, &hwaddr, sizeof(hwaddr), 0);
		if (i == 0) {
			netlink_add_device_impl(&nlmsg, "lowpan", "lowpan0");
			netlink_done(&nlmsg);
			netlink_attr(&nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
			int err = netlink_send(&nlmsg, sock_route);
			if (err < 0) {
			}
		}
	}
	close(sock_route);
	close(sock_generic);
}

uint64_t r[1] = {0xffffffffffffffff};

int main(void)
{
		syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	setup_fault();
	setup_802154();
			use_temporary_dir();
				intptr_t res = 0;
memcpy((void*)0x20000040, "/dev/adsp1\000", 11);
	res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000040ul, 0ul, 0ul);
	if (res != -1)
		r[0] = res;
*(uint32_t*)0x200000c0 = r[0];
*(uint16_t*)0x200000c4 = 0;
*(uint16_t*)0x200000c6 = 0;
	inject_fault(11);
	syscall(__NR_poll, 0x200000c0ul, 1ul, 9);
	return 0;
}

WARNING: multiple messages have this Message-ID (diff)
From: Dipanjan Das <mail.dipanjan.das@gmail.com>
To: perex@perex.cz, tiwai@suse.com, gregkh@linuxfoundation.org,
	 consult.awy@gmail.com, alsa-devel@alsa-project.org,
	 linux-kernel@vger.kernel.org
Cc: fleischermarius@googlemail.com, syzkaller@googlegroups.com,
	its.priyanka.bose@gmail.com
Subject: KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params
Date: Fri, 22 Jul 2022 09:37:52 -0700	[thread overview]
Message-ID: <CANX2M5Zw_zW6ez0_wvaXL1pbLnR2jWY=T7MgkT=4a-zNkiwVig@mail.gmail.com> (raw)

[-- Attachment #1: Type: text/plain, Size: 3455 bytes --]

Hi,

We would like to report the following bug which has been found by our
modified version of syzkaller.

======================================================
description: KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params
affected file: sound/core/pcm_native.c
kernel version: 5.10.131
kernel commit: de62055f423f5dcb548f74cebd68f03c8903f73a
git tree: upstream
kernel config: https://syzkaller.appspot.com/x/.config?x=e49433cfed49b7d9
crash reproducer: attached
======================================================
Crash log:
======================================================
BUG: KASAN: vmalloc-out-of-bounds in memset include/linux/string.h:384 [inline]
BUG: KASAN: vmalloc-out-of-bounds in snd_pcm_hw_params+0x19b0/0x1db0
sound/core/pcm_native.c:799
Write of size 2097152 at addr ffffc900113b2000 by task syz-executor.5/14437

CPU: 1 PID: 14437 Comm: syz-executor.5 Tainted: G           OE     5.10.131+ #3
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS
1.13.0-1ubuntu1.1 04/01/2014
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x107/0x163 lib/dump_stack.c:118
 print_address_description.constprop.0.cold+0x5/0x4f7 mm/kasan/report.c:385
 __kasan_report mm/kasan/report.c:545 [inline]
 kasan_report.cold+0x1f/0x37 mm/kasan/report.c:562
 check_memory_region_inline mm/kasan/generic.c:194 [inline]
 check_memory_region+0x187/0x1e0 mm/kasan/generic.c:200
 memset+0x20/0x40 mm/kasan/common.c:85
 memset include/linux/string.h:384 [inline]
 snd_pcm_hw_params+0x19b0/0x1db0 sound/core/pcm_native.c:799
 snd_pcm_kernel_ioctl+0xd1/0x240 sound/core/pcm_native.c:3401
 snd_pcm_oss_change_params_locked+0x17b6/0x3aa0 sound/core/oss/pcm_oss.c:965
 snd_pcm_oss_change_params+0x76/0xd0 sound/core/oss/pcm_oss.c:1107
 snd_pcm_oss_make_ready+0xb7/0x170 sound/core/oss/pcm_oss.c:1166
 snd_pcm_oss_set_trigger.isra.0+0x34f/0x770 sound/core/oss/pcm_oss.c:2074
 snd_pcm_oss_poll+0x679/0xb40 sound/core/oss/pcm_oss.c:2858
 vfs_poll include/linux/poll.h:90 [inline]
 do_pollfd fs/select.c:872 [inline]
 do_poll fs/select.c:920 [inline]
 do_sys_poll+0x63c/0xe40 fs/select.c:1014
 __do_sys_poll fs/select.c:1079 [inline]
 __se_sys_poll fs/select.c:1067 [inline]
 __x64_sys_poll+0x18c/0x490 fs/select.c:1067
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x7f095de4f4ed
Code: 02 b8 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa 48 89 f8 48
89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d
01 f0 ff ff 73 01 c3 48 c7 c1 b8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007f095bdffbe8 EFLAGS: 00000246 ORIG_RAX: 0000000000000007
RAX: ffffffffffffffda RBX: 00007f095df6df60 RCX: 00007f095de4f4ed
RDX: 0000000000000009 RSI: 0000000000000001 RDI: 00000000200000c0
RBP: 00007f095bdffc40 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 000000000000001d
R13: 00007ffff286ceff R14: 00007f095df6df60 R15: 00007f095bdffd80


Memory state around the buggy address:
 ffffc900115b1d00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
 ffffc900115b1d80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffffc900115b1e00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
                   ^
 ffffc900115b1e80: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
 ffffc900115b1f00: f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8 f8
==================================================================

-- 
Thanks and Regards,

Dipanjan

[-- Attachment #2: repro.syz --]
[-- Type: application/octet-stream, Size: 123 bytes --]

r0 = openat$adsp1(0xffffffffffffff9c, &(0x7f0000000040), 0x0, 0x0)
poll(&(0x7f00000000c0)=[{r0}], 0x1, 0x9) (fail_nth: 11)

[-- Attachment #3: repro.c --]
[-- Type: text/x-csrc, Size: 8786 bytes --]

// autogenerated by syzkaller (https://github.com/google/syzkaller)

#define _GNU_SOURCE 

#include <arpa/inet.h>
#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include <linux/genetlink.h>
#include <linux/if_addr.h>
#include <linux/if_link.h>
#include <linux/in6.h>
#include <linux/neighbour.h>
#include <linux/net.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <linux/veth.h>

static void use_temporary_dir(void)
{
	char tmpdir_template[] = "./syzkaller.XXXXXX";
	char* tmpdir = mkdtemp(tmpdir_template);
	if (!tmpdir)
	exit(1);
	if (chmod(tmpdir, 0777))
	exit(1);
	if (chdir(tmpdir))
	exit(1);
}

static bool write_file(const char* file, const char* what, ...)
{
	char buf[1024];
	va_list args;
	va_start(args, what);
	vsnprintf(buf, sizeof(buf), what, args);
	va_end(args);
	buf[sizeof(buf) - 1] = 0;
	int len = strlen(buf);
	int fd = open(file, O_WRONLY | O_CLOEXEC);
	if (fd == -1)
		return false;
	if (write(fd, buf, len) != len) {
		int err = errno;
		close(fd);
		errno = err;
		return false;
	}
	close(fd);
	return true;
}

struct nlmsg {
	char* pos;
	int nesting;
	struct nlattr* nested[8];
	char buf[4096];
};

static void netlink_init(struct nlmsg* nlmsg, int typ, int flags,
			 const void* data, int size)
{
	memset(nlmsg, 0, sizeof(*nlmsg));
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_type = typ;
	hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK | flags;
	memcpy(hdr + 1, data, size);
	nlmsg->pos = (char*)(hdr + 1) + NLMSG_ALIGN(size);
}

static void netlink_attr(struct nlmsg* nlmsg, int typ,
			 const void* data, int size)
{
	struct nlattr* attr = (struct nlattr*)nlmsg->pos;
	attr->nla_len = sizeof(*attr) + size;
	attr->nla_type = typ;
	if (size > 0)
		memcpy(attr + 1, data, size);
	nlmsg->pos += NLMSG_ALIGN(attr->nla_len);
}

static void netlink_nest(struct nlmsg* nlmsg, int typ)
{
	struct nlattr* attr = (struct nlattr*)nlmsg->pos;
	attr->nla_type = typ;
	nlmsg->pos += sizeof(*attr);
	nlmsg->nested[nlmsg->nesting++] = attr;
}

static void netlink_done(struct nlmsg* nlmsg)
{
	struct nlattr* attr = nlmsg->nested[--nlmsg->nesting];
	attr->nla_len = nlmsg->pos - (char*)attr;
}

static int netlink_send_ext(struct nlmsg* nlmsg, int sock,
			    uint16_t reply_type, int* reply_len, bool dofail)
{
	if (nlmsg->pos > nlmsg->buf + sizeof(nlmsg->buf) || nlmsg->nesting)
	exit(1);
	struct nlmsghdr* hdr = (struct nlmsghdr*)nlmsg->buf;
	hdr->nlmsg_len = nlmsg->pos - nlmsg->buf;
	struct sockaddr_nl addr;
	memset(&addr, 0, sizeof(addr));
	addr.nl_family = AF_NETLINK;
	ssize_t n = sendto(sock, nlmsg->buf, hdr->nlmsg_len, 0, (struct sockaddr*)&addr, sizeof(addr));
	if (n != (ssize_t)hdr->nlmsg_len) {
		if (dofail)
	exit(1);
		return -1;
	}
	n = recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	if (reply_len)
		*reply_len = 0;
	if (n < 0) {
		if (dofail)
	exit(1);
		return -1;
	}
	if (n < (ssize_t)sizeof(struct nlmsghdr)) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type == NLMSG_DONE)
		return 0;
	if (reply_len && hdr->nlmsg_type == reply_type) {
		*reply_len = n;
		return 0;
	}
	if (n < (ssize_t)(sizeof(struct nlmsghdr) + sizeof(struct nlmsgerr))) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	if (hdr->nlmsg_type != NLMSG_ERROR) {
		errno = EINVAL;
		if (dofail)
	exit(1);
		return -1;
	}
	errno = -((struct nlmsgerr*)(hdr + 1))->error;
	return -errno;
}

static int netlink_send(struct nlmsg* nlmsg, int sock)
{
	return netlink_send_ext(nlmsg, sock, 0, NULL, true);
}

static int netlink_query_family_id(struct nlmsg* nlmsg, int sock, const char* family_name, bool dofail)
{
	struct genlmsghdr genlhdr;
	memset(&genlhdr, 0, sizeof(genlhdr));
	genlhdr.cmd = CTRL_CMD_GETFAMILY;
	netlink_init(nlmsg, GENL_ID_CTRL, 0, &genlhdr, sizeof(genlhdr));
	netlink_attr(nlmsg, CTRL_ATTR_FAMILY_NAME, family_name, strnlen(family_name, GENL_NAMSIZ - 1) + 1);
	int n = 0;
	int err = netlink_send_ext(nlmsg, sock, GENL_ID_CTRL, &n, dofail);
	if (err < 0) {
		return -1;
	}
	uint16_t id = 0;
	struct nlattr* attr = (struct nlattr*)(nlmsg->buf + NLMSG_HDRLEN + NLMSG_ALIGN(sizeof(genlhdr)));
	for (; (char*)attr < nlmsg->buf + n; attr = (struct nlattr*)((char*)attr + NLMSG_ALIGN(attr->nla_len))) {
		if (attr->nla_type == CTRL_ATTR_FAMILY_ID) {
			id = *(uint16_t*)(attr + 1);
			break;
		}
	}
	if (!id) {
		errno = EINVAL;
		return -1;
	}
	recv(sock, nlmsg->buf, sizeof(nlmsg->buf), 0);
	return id;
}

static void netlink_add_device_impl(struct nlmsg* nlmsg, const char* type,
				    const char* name)
{
	struct ifinfomsg hdr;
	memset(&hdr, 0, sizeof(hdr));
	netlink_init(nlmsg, RTM_NEWLINK, NLM_F_EXCL | NLM_F_CREATE, &hdr, sizeof(hdr));
	if (name)
		netlink_attr(nlmsg, IFLA_IFNAME, name, strlen(name));
	netlink_nest(nlmsg, IFLA_LINKINFO);
	netlink_attr(nlmsg, IFLA_INFO_KIND, type, strlen(type));
}

static void netlink_device_change(struct nlmsg* nlmsg, int sock, const char* name, bool up,
				  const char* master, const void* mac, int macsize,
				  const char* new_name)
{
	struct ifinfomsg hdr;
	memset(&hdr, 0, sizeof(hdr));
	if (up)
		hdr.ifi_flags = hdr.ifi_change = IFF_UP;
	hdr.ifi_index = if_nametoindex(name);
	netlink_init(nlmsg, RTM_NEWLINK, 0, &hdr, sizeof(hdr));
	if (new_name)
		netlink_attr(nlmsg, IFLA_IFNAME, new_name, strlen(new_name));
	if (master) {
		int ifindex = if_nametoindex(master);
		netlink_attr(nlmsg, IFLA_MASTER, &ifindex, sizeof(ifindex));
	}
	if (macsize)
		netlink_attr(nlmsg, IFLA_ADDRESS, mac, macsize);
	int err = netlink_send(nlmsg, sock);
	if (err < 0) {
	}
}

static struct nlmsg nlmsg;

static int inject_fault(int nth)
{
	int fd;
	fd = open("/proc/thread-self/fail-nth", O_RDWR);
	if (fd == -1)
	exit(1);
	char buf[16];
	sprintf(buf, "%d", nth);
	if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf))
	exit(1);
	return fd;
}

static void setup_fault()
{
	static struct {
		const char* file;
		const char* val;
		bool fatal;
	} files[] = {
	    {"/sys/kernel/debug/failslab/ignore-gfp-wait", "N", true},
	    {"/sys/kernel/debug/fail_futex/ignore-private", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-highmem", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/ignore-gfp-wait", "N", false},
	    {"/sys/kernel/debug/fail_page_alloc/min-order", "0", false},
	};
	unsigned i;
	for (i = 0; i < sizeof(files) / sizeof(files[0]); i++) {
		if (!write_file(files[i].file, files[i].val)) {
			if (files[i].fatal)
	exit(1);
		}
	}
}

#define NL802154_CMD_SET_SHORT_ADDR 11
#define NL802154_ATTR_IFINDEX 3
#define NL802154_ATTR_SHORT_ADDR 10

static void setup_802154()
{
	int sock_route = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
	if (sock_route == -1)
	exit(1);
	int sock_generic = socket(AF_NETLINK, SOCK_RAW, NETLINK_GENERIC);
	if (sock_generic < 0)
	exit(1);
	int nl802154_family_id = netlink_query_family_id(&nlmsg, sock_generic, "nl802154", true);
	for (int i = 0; i < 2; i++) {
		char devname[] = "wpan0";
		devname[strlen(devname) - 1] += i;
		uint64_t hwaddr = 0xaaaaaaaaaaaa0002 + (i << 8);
		uint16_t shortaddr = 0xaaa0 + i;
		int ifindex = if_nametoindex(devname);
		struct genlmsghdr genlhdr;
		memset(&genlhdr, 0, sizeof(genlhdr));
		genlhdr.cmd = NL802154_CMD_SET_SHORT_ADDR;
		netlink_init(&nlmsg, nl802154_family_id, 0, &genlhdr, sizeof(genlhdr));
		netlink_attr(&nlmsg, NL802154_ATTR_IFINDEX, &ifindex, sizeof(ifindex));
		netlink_attr(&nlmsg, NL802154_ATTR_SHORT_ADDR, &shortaddr, sizeof(shortaddr));
		int err = netlink_send(&nlmsg, sock_generic);
		if (err < 0) {
		}
		netlink_device_change(&nlmsg, sock_route, devname, true, 0, &hwaddr, sizeof(hwaddr), 0);
		if (i == 0) {
			netlink_add_device_impl(&nlmsg, "lowpan", "lowpan0");
			netlink_done(&nlmsg);
			netlink_attr(&nlmsg, IFLA_LINK, &ifindex, sizeof(ifindex));
			int err = netlink_send(&nlmsg, sock_route);
			if (err < 0) {
			}
		}
	}
	close(sock_route);
	close(sock_generic);
}

uint64_t r[1] = {0xffffffffffffffff};

int main(void)
{
		syscall(__NR_mmap, 0x1ffff000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x20000000ul, 0x1000000ul, 7ul, 0x32ul, -1, 0ul);
	syscall(__NR_mmap, 0x21000000ul, 0x1000ul, 0ul, 0x32ul, -1, 0ul);
	setup_fault();
	setup_802154();
			use_temporary_dir();
				intptr_t res = 0;
memcpy((void*)0x20000040, "/dev/adsp1\000", 11);
	res = syscall(__NR_openat, 0xffffffffffffff9cul, 0x20000040ul, 0ul, 0ul);
	if (res != -1)
		r[0] = res;
*(uint32_t*)0x200000c0 = r[0];
*(uint16_t*)0x200000c4 = 0;
*(uint16_t*)0x200000c6 = 0;
	inject_fault(11);
	syscall(__NR_poll, 0x200000c0ul, 1ul, 9);
	return 0;
}

             reply	other threads:[~2022-07-22 16:38 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-07-22 16:37 Dipanjan Das [this message]
2022-07-22 16:37 ` KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params Dipanjan Das
2022-07-23  7:00 ` Greg KH
2022-07-23  7:00   ` Greg KH
2022-07-23 10:16   ` Takashi Iwai
2022-07-23 10:16     ` Takashi Iwai
2022-07-26 21:40     ` Dipanjan Das
2022-07-26 21:40       ` Dipanjan Das
2022-07-27  4:06       ` Lukas Bulwahn
2022-07-27  4:06         ` Lukas Bulwahn
2022-07-27  5:25       ` Takashi Iwai
2022-07-27  5:25         ` Takashi Iwai
2022-07-28 23:24         ` Dipanjan Das
2022-07-28 23:24           ` Dipanjan Das
2022-07-29  6:07           ` Takashi Iwai
2022-07-29  6:07             ` Takashi Iwai
2022-07-29  8:13           ` Greg KH
2022-07-29  8:13             ` Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CANX2M5Zw_zW6ez0_wvaXL1pbLnR2jWY=T7MgkT=4a-zNkiwVig@mail.gmail.com' \
    --to=mail.dipanjan.das@gmail.com \
    --cc=alsa-devel@alsa-project.org \
    --cc=consult.awy@gmail.com \
    --cc=fleischermarius@googlemail.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=its.priyanka.bose@gmail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=syzkaller@googlegroups.com \
    --cc=tiwai@suse.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.