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;
}
next reply other threads:[~2022-07-22 16:38 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-22 16:37 Dipanjan Das [this message]
2022-07-23 7:00 ` KASAN: vmalloc-out-of-bounds Write in snd_pcm_hw_params Greg KH
2022-07-23 10:16 ` Takashi Iwai
2022-07-26 21:40 ` Dipanjan Das
2022-07-27 4:06 ` Lukas Bulwahn
2022-07-27 5:25 ` Takashi Iwai
2022-07-28 23:24 ` Dipanjan Das
2022-07-29 6:07 ` Takashi Iwai
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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).