Heap OOB write in rds_message_alloc_sgs() CVE-2018-5332 & null pointer dereference in rds_atomic_free_op CVE-2018-5333 & Fix NULL pointer dereference in __rds_rdma_map CVE-2018-7492 in kernel-net-rds
asked 2018-02-14 01:38:22 +0200
This post is a wiki. Anyone with karma >75 is welcome to improve it.
In the Linux kernel through 4.14.13, the rds_message_alloc_sgs() function does not validate a value that is used during DMA page allocation, leading to a heap-based out-of-bounds write (related to the rds_rdma_extra_size function in net/rds/rdma.c). CVSScore 7.8high / local
In the Linux kernel through 4.14.13, the rds_cmsg_atomic function in net/rds/rdma.c mishandles cases where page pinning fails or an invalid address is supplied, leading to an rds_atomic_free_op NULL pointer dereference. CVSScore 5.5medium / local
A NULL pointer dereference was found in the net/rds/rdma.c __rds_rdma_map() function in the Linux kernel before 4.14.7 allowing local attackers to cause a system panic and a denial-of-service, related to RDS_GET_MR and RDS_GET_MR_FOR_DEST.
Upstream-Patches |1| |2| |3| are available and equal to kernel-3.2-patches |1| |2| |3| , so fixing this is easy.
file affected: kernel-adaptation-sbj-3.4.108.20161101.1/net/rds/rdma.c lines 184-190 ; 516-521 ; 852-857
the whole patch should look like:
@@ -184,7 +184,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
long i;
int ret;
- if (rs->rs_bound_addr == 0) {
+ if (rs->rs_bound_addr == 0 || !rs->rs_transport) {
ret = -ENOTCONN; /* XXX not a great errno */
goto out;
}
@@ -516,6 +516,9 @@ int rds_rdma_extra_size(struct rds_rdma_args *args)
local_vec = (struct rds_iovec __user *)(unsigned long) args->local_vec_addr;
+ if (args->nr_local == 0)
+ return -EINVAL;
+
/* figure out the number of pages in the vector */
for (i = 0; i < args->nr_local; i++) {
if (copy_from_user(&vec, &local_vec[i],
@@ -852,6 +855,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
err:
if (page)
put_page(page);
+ rm->atomic.op_active = 0;
kfree(rm->atomic.op_notifier);
return ret;