[bug report]infiniband: integer overflow in ib_uverbs_post_send

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

 



This email is sent because the previous one was rejected due to it was in html form.

From: Changming Liu 
Sent: Friday, March 6, 2020 8:50 PM
To: dledford@xxxxxxxxxx; jgg@xxxxxxxxxxxx
Cc: linux-rdma@xxxxxxxxxxxxxxx; yaohway@xxxxxxxxx
Subject: [bug report]infiniband: integer overflow in ib_uverbs_post_send

Hi Doug and Jason:
Greetings, I'm a first year PhD student who is interested in the usage of UBSan in the linux kernel, and with some experiments I found that in
/drivers/infiniband/core/uverbs_cmd.c function ib_uverbs_post_send, there is a unsigned integer overflow which might cause undesired behavior.

More specifically, the cmd structure, after the execution uverbs_request_start, are filled with data from user space. Then two __u32 integers in this structure are multiplied together as shown as followed,

wqes = uverbs_request_next_ptr(&iter, cmd.wqe_size * cmd.wr_count);

Then the result of this multiplication is passed to the second parameter of function uverbs_request_next_ptr which accepts a size_t type of integer which is __u64. 
The result of this multiplication is later checked at

if (iter->cur + len > iter->end)

And used as an offset in 

iter->cur += len;


The problem is, the result of this multiplication can wrap around. Although it's lifted to __u64 in function uverbs_request_next_ptr, it will first wrap around and then be lifted, as shown in the llvm IR:
  %wqe_size = getelementptr inbounds %struct.ib_uverbs_post_send, %struct.ib_uverbs_post_send* %cmd, i64 0, i32 4
  %9 = load i32, i32* %wqe_size, align 4, !tbaa !2404
  %wr_count = getelementptr inbounds %struct.ib_uverbs_post_send, %struct.ib_uverbs_post_send* %cmd, i64 0, i32 2
  %10 = load i32, i32* %wr_count, align 4, !tbaa !2406
  %11 = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 %9, i32 %10), !nosanitize !29
  %12 = extractvalue { i32, i1 } %11, 0, !nosanitize !29
  %conv = zext i32 %12 to i64

So, the check at line 164 may pass due to the wrap around. And the overflown result is later used in line 166. this issue exists in the latest linux kernel i.e. linux-5.5.8 as well.
Due to the lack of knowledge of the interaction between this module and the user space, and how serious the issue can be if the offset in line 166 is calculated wrong, I'm not able to assess if this is security-related problem. I'd be more than happy to hear your valuable opinions and provide more information if needed.

Looking forward to your response!

Best regards,
Changming Liu




[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