Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/rds: Whitelist rdma_cookie and rx_tstamp for usercopy

Add the RDMA cookie and RX timestamp to the usercopy whitelist.

After the introduction of hardened usercopy whitelisting
(https://lwn.net/Articles/727322/), a warning is displayed when the
RDMA cookie or RX timestamp is copied to userspace:

kernel: WARNING: CPU: 3 PID: 5750 at
mm/usercopy.c:81 usercopy_warn+0x8e/0xa6
[...]
kernel: Call Trace:
kernel: __check_heap_object+0xb8/0x11b
kernel: __check_object_size+0xe3/0x1bc
kernel: put_cmsg+0x95/0x115
kernel: rds_recvmsg+0x43d/0x620 [rds]
kernel: sock_recvmsg+0x43/0x4a
kernel: ___sys_recvmsg+0xda/0x1e6
kernel: ? __handle_mm_fault+0xcae/0xf79
kernel: __sys_recvmsg+0x51/0x8a
kernel: SyS_recvmsg+0x12/0x1c
kernel: do_syscall_64+0x79/0x1ae

When the whitelisting feature was introduced, the memory for the RDMA
cookie and RX timestamp in RDS was not added to the whitelist, causing
the warning above.

Signed-off-by: Dag Moxnes <dag.moxnes@oracle.com>
Tested-by: Jenny <jenny.x.xu@oracle.com>
Acked-by: Santosh Shilimkar <santosh.shilimkar@oracle.com>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Dag Moxnes and committed by
David S. Miller
bf1867db 87cade29

+27 -15
+8 -3
net/rds/ib_recv.c
··· 1048 1048 si_meminfo(&si); 1049 1049 rds_ib_sysctl_max_recv_allocation = si.totalram / 3 * PAGE_SIZE / RDS_FRAG_SIZE; 1050 1050 1051 - rds_ib_incoming_slab = kmem_cache_create("rds_ib_incoming", 1052 - sizeof(struct rds_ib_incoming), 1053 - 0, SLAB_HWCACHE_ALIGN, NULL); 1051 + rds_ib_incoming_slab = 1052 + kmem_cache_create_usercopy("rds_ib_incoming", 1053 + sizeof(struct rds_ib_incoming), 1054 + 0, SLAB_HWCACHE_ALIGN, 1055 + offsetof(struct rds_ib_incoming, 1056 + ii_inc.i_usercopy), 1057 + sizeof(struct rds_inc_usercopy), 1058 + NULL); 1054 1059 if (!rds_ib_incoming_slab) 1055 1060 goto out; 1056 1061
+7 -2
net/rds/rds.h
··· 271 271 #define RDS_MSG_RX_END 2 272 272 #define RDS_MSG_RX_CMSG 3 273 273 274 + /* The following values are whitelisted for usercopy */ 275 + struct rds_inc_usercopy { 276 + rds_rdma_cookie_t rdma_cookie; 277 + ktime_t rx_tstamp; 278 + }; 279 + 274 280 struct rds_incoming { 275 281 refcount_t i_refcount; 276 282 struct list_head i_item; ··· 286 280 unsigned long i_rx_jiffies; 287 281 struct in6_addr i_saddr; 288 282 289 - rds_rdma_cookie_t i_rdma_cookie; 290 - ktime_t i_rx_tstamp; 283 + struct rds_inc_usercopy i_usercopy; 291 284 u64 i_rx_lat_trace[RDS_RX_MAX_TRACES]; 292 285 }; 293 286
+12 -10
net/rds/recv.c
··· 47 47 INIT_LIST_HEAD(&inc->i_item); 48 48 inc->i_conn = conn; 49 49 inc->i_saddr = *saddr; 50 - inc->i_rdma_cookie = 0; 51 - inc->i_rx_tstamp = ktime_set(0, 0); 50 + inc->i_usercopy.rdma_cookie = 0; 51 + inc->i_usercopy.rx_tstamp = ktime_set(0, 0); 52 52 53 53 memset(inc->i_rx_lat_trace, 0, sizeof(inc->i_rx_lat_trace)); 54 54 } ··· 62 62 inc->i_conn = cp->cp_conn; 63 63 inc->i_conn_path = cp; 64 64 inc->i_saddr = *saddr; 65 - inc->i_rdma_cookie = 0; 66 - inc->i_rx_tstamp = ktime_set(0, 0); 65 + inc->i_usercopy.rdma_cookie = 0; 66 + inc->i_usercopy.rx_tstamp = ktime_set(0, 0); 67 67 } 68 68 EXPORT_SYMBOL_GPL(rds_inc_path_init); 69 69 ··· 186 186 case RDS_EXTHDR_RDMA_DEST: 187 187 /* We ignore the size for now. We could stash it 188 188 * somewhere and use it for error checking. */ 189 - inc->i_rdma_cookie = rds_rdma_make_cookie( 189 + inc->i_usercopy.rdma_cookie = rds_rdma_make_cookie( 190 190 be32_to_cpu(buffer.rdma_dest.h_rdma_rkey), 191 191 be32_to_cpu(buffer.rdma_dest.h_rdma_offset)); 192 192 ··· 380 380 be32_to_cpu(inc->i_hdr.h_len), 381 381 inc->i_hdr.h_dport); 382 382 if (sock_flag(sk, SOCK_RCVTSTAMP)) 383 - inc->i_rx_tstamp = ktime_get_real(); 383 + inc->i_usercopy.rx_tstamp = ktime_get_real(); 384 384 rds_inc_addref(inc); 385 385 inc->i_rx_lat_trace[RDS_MSG_RX_END] = local_clock(); 386 386 list_add_tail(&inc->i_item, &rs->rs_recv_queue); ··· 540 540 { 541 541 int ret = 0; 542 542 543 - if (inc->i_rdma_cookie) { 543 + if (inc->i_usercopy.rdma_cookie) { 544 544 ret = put_cmsg(msg, SOL_RDS, RDS_CMSG_RDMA_DEST, 545 - sizeof(inc->i_rdma_cookie), &inc->i_rdma_cookie); 545 + sizeof(inc->i_usercopy.rdma_cookie), 546 + &inc->i_usercopy.rdma_cookie); 546 547 if (ret) 547 548 goto out; 548 549 } 549 550 550 - if ((inc->i_rx_tstamp != 0) && 551 + if ((inc->i_usercopy.rx_tstamp != 0) && 551 552 sock_flag(rds_rs_to_sk(rs), SOCK_RCVTSTAMP)) { 552 - struct __kernel_old_timeval tv = ns_to_kernel_old_timeval(inc->i_rx_tstamp); 553 + struct __kernel_old_timeval tv = 554 + ns_to_kernel_old_timeval(inc->i_usercopy.rx_tstamp); 553 555 554 556 if (!sock_flag(rds_rs_to_sk(rs), SOCK_TSTAMP_NEW)) { 555 557 ret = put_cmsg(msg, SOL_SOCKET, SO_TIMESTAMP_OLD,