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

rxrpc: Use skb_unshare() rather than skb_cow_data()

The in-place decryption routines in AF_RXRPC's rxkad security module
currently call skb_cow_data() to make sure the data isn't shared and that
the skb can be written over. This has a problem, however, as the softirq
handler may be still holding a ref or the Rx ring may be holding multiple
refs when skb_cow_data() is called in rxkad_verify_packet() - and so
skb_shared() returns true and __pskb_pull_tail() dislikes that. If this
occurs, something like the following report will be generated.

kernel BUG at net/core/skbuff.c:1463!
...
RIP: 0010:pskb_expand_head+0x253/0x2b0
...
Call Trace:
__pskb_pull_tail+0x49/0x460
skb_cow_data+0x6f/0x300
rxkad_verify_packet+0x18b/0xb10 [rxrpc]
rxrpc_recvmsg_data.isra.11+0x4a8/0xa10 [rxrpc]
rxrpc_kernel_recv_data+0x126/0x240 [rxrpc]
afs_extract_data+0x51/0x2d0 [kafs]
afs_deliver_fs_fetch_data+0x188/0x400 [kafs]
afs_deliver_to_call+0xac/0x430 [kafs]
afs_wait_for_call_to_complete+0x22f/0x3d0 [kafs]
afs_make_call+0x282/0x3f0 [kafs]
afs_fs_fetch_data+0x164/0x300 [kafs]
afs_fetch_data+0x54/0x130 [kafs]
afs_readpages+0x20d/0x340 [kafs]
read_pages+0x66/0x180
__do_page_cache_readahead+0x188/0x1a0
ondemand_readahead+0x17d/0x2e0
generic_file_read_iter+0x740/0xc10
__vfs_read+0x145/0x1a0
vfs_read+0x8c/0x140
ksys_read+0x4a/0xb0
do_syscall_64+0x43/0xf0
entry_SYSCALL_64_after_hwframe+0x44/0xa9

Fix this by using skb_unshare() instead in the input path for DATA packets
that have a security index != 0. Non-DATA packets don't need in-place
encryption and neither do unencrypted DATA packets.

Fixes: 248f219cb8bc ("rxrpc: Rewrite the data and ack handling code")
Reported-by: Julian Wollrath <jwollrath@web.de>
Signed-off-by: David Howells <dhowells@redhat.com>

+56 -32
+8 -4
include/trace/events/rxrpc.h
··· 32 32 rxrpc_skb_received, 33 33 rxrpc_skb_rotated, 34 34 rxrpc_skb_seen, 35 + rxrpc_skb_unshared, 36 + rxrpc_skb_unshared_nomem, 35 37 }; 36 38 37 39 enum rxrpc_local_trace { ··· 233 231 EM(rxrpc_skb_purged, "PUR") \ 234 232 EM(rxrpc_skb_received, "RCV") \ 235 233 EM(rxrpc_skb_rotated, "ROT") \ 236 - E_(rxrpc_skb_seen, "SEE") 234 + EM(rxrpc_skb_seen, "SEE") \ 235 + EM(rxrpc_skb_unshared, "UNS") \ 236 + E_(rxrpc_skb_unshared_nomem, "US0") 237 237 238 238 #define rxrpc_local_traces \ 239 239 EM(rxrpc_local_got, "GOT") \ ··· 637 633 638 634 TRACE_EVENT(rxrpc_skb, 639 635 TP_PROTO(struct sk_buff *skb, enum rxrpc_skb_trace op, 640 - int usage, int mod_count, const void *where), 636 + int usage, int mod_count, u8 flags, const void *where), 641 637 642 - TP_ARGS(skb, op, usage, mod_count, where), 638 + TP_ARGS(skb, op, usage, mod_count, flags, where), 643 639 644 640 TP_STRUCT__entry( 645 641 __field(struct sk_buff *, skb ) ··· 652 648 653 649 TP_fast_assign( 654 650 __entry->skb = skb; 655 - __entry->flags = rxrpc_skb(skb)->rx_flags; 651 + __entry->flags = flags; 656 652 __entry->op = op; 657 653 __entry->usage = usage; 658 654 __entry->mod_count = mod_count;
+1
net/rxrpc/ar-internal.h
··· 1110 1110 void rxrpc_packet_destructor(struct sk_buff *); 1111 1111 void rxrpc_new_skb(struct sk_buff *, enum rxrpc_skb_trace); 1112 1112 void rxrpc_see_skb(struct sk_buff *, enum rxrpc_skb_trace); 1113 + void rxrpc_eaten_skb(struct sk_buff *, enum rxrpc_skb_trace); 1113 1114 void rxrpc_get_skb(struct sk_buff *, enum rxrpc_skb_trace); 1114 1115 void rxrpc_free_skb(struct sk_buff *, enum rxrpc_skb_trace); 1115 1116 void rxrpc_purge_queue(struct sk_buff_head *);
+18
net/rxrpc/input.c
··· 1249 1249 goto bad_message; 1250 1250 if (!rxrpc_validate_data(skb)) 1251 1251 goto bad_message; 1252 + 1253 + /* Unshare the packet so that it can be modified for in-place 1254 + * decryption. 1255 + */ 1256 + if (sp->hdr.securityIndex != 0) { 1257 + struct sk_buff *nskb = skb_unshare(skb, GFP_ATOMIC); 1258 + if (!nskb) { 1259 + rxrpc_eaten_skb(skb, rxrpc_skb_unshared_nomem); 1260 + goto out; 1261 + } 1262 + 1263 + if (nskb != skb) { 1264 + rxrpc_eaten_skb(skb, rxrpc_skb_received); 1265 + rxrpc_new_skb(skb, rxrpc_skb_unshared); 1266 + skb = nskb; 1267 + sp = rxrpc_skb(skb); 1268 + } 1269 + } 1252 1270 break; 1253 1271 1254 1272 case RXRPC_PACKET_TYPE_CHALLENGE:
+9 -23
net/rxrpc/rxkad.c
··· 187 187 struct rxrpc_skb_priv *sp; 188 188 struct rxrpc_crypt iv; 189 189 struct scatterlist sg[16]; 190 - struct sk_buff *trailer; 191 190 unsigned int len; 192 191 u16 check; 193 - int nsg; 194 192 int err; 195 193 196 194 sp = rxrpc_skb(skb); ··· 212 214 crypto_skcipher_encrypt(req); 213 215 214 216 /* we want to encrypt the skbuff in-place */ 215 - nsg = skb_cow_data(skb, 0, &trailer); 216 - err = -ENOMEM; 217 - if (nsg < 0 || nsg > 16) 217 + err = -EMSGSIZE; 218 + if (skb_shinfo(skb)->nr_frags > 16) 218 219 goto out; 219 220 220 221 len = data_size + call->conn->size_align - 1; 221 222 len &= ~(call->conn->size_align - 1); 222 223 223 - sg_init_table(sg, nsg); 224 + sg_init_table(sg, ARRAY_SIZE(sg)); 224 225 err = skb_to_sgvec(skb, sg, 0, len); 225 226 if (unlikely(err < 0)) 226 227 goto out; ··· 316 319 struct rxkad_level1_hdr sechdr; 317 320 struct rxrpc_crypt iv; 318 321 struct scatterlist sg[16]; 319 - struct sk_buff *trailer; 320 322 bool aborted; 321 323 u32 data_size, buf; 322 324 u16 check; 323 - int nsg, ret; 325 + int ret; 324 326 325 327 _enter(""); 326 328 ··· 332 336 /* Decrypt the skbuff in-place. TODO: We really want to decrypt 333 337 * directly into the target buffer. 334 338 */ 335 - nsg = skb_cow_data(skb, 0, &trailer); 336 - if (nsg < 0 || nsg > 16) 337 - goto nomem; 338 - 339 - sg_init_table(sg, nsg); 339 + sg_init_table(sg, ARRAY_SIZE(sg)); 340 340 ret = skb_to_sgvec(skb, sg, offset, 8); 341 341 if (unlikely(ret < 0)) 342 342 return ret; ··· 380 388 if (aborted) 381 389 rxrpc_send_abort_packet(call); 382 390 return -EPROTO; 383 - 384 - nomem: 385 - _leave(" = -ENOMEM"); 386 - return -ENOMEM; 387 391 } 388 392 389 393 /* ··· 394 406 struct rxkad_level2_hdr sechdr; 395 407 struct rxrpc_crypt iv; 396 408 struct scatterlist _sg[4], *sg; 397 - struct sk_buff *trailer; 398 409 bool aborted; 399 410 u32 data_size, buf; 400 411 u16 check; ··· 410 423 /* Decrypt the skbuff in-place. TODO: We really want to decrypt 411 424 * directly into the target buffer. 412 425 */ 413 - nsg = skb_cow_data(skb, 0, &trailer); 414 - if (nsg < 0) 415 - goto nomem; 416 - 417 426 sg = _sg; 418 - if (unlikely(nsg > 4)) { 427 + nsg = skb_shinfo(skb)->nr_frags; 428 + if (nsg <= 4) { 429 + nsg = 4; 430 + } else { 419 431 sg = kmalloc_array(nsg, sizeof(*sg), GFP_NOIO); 420 432 if (!sg) 421 433 goto nomem;
+20 -5
net/rxrpc/skbuff.c
··· 24 24 { 25 25 const void *here = __builtin_return_address(0); 26 26 int n = atomic_inc_return(select_skb_count(skb)); 27 - trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here); 27 + trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 28 + rxrpc_skb(skb)->rx_flags, here); 28 29 } 29 30 30 31 /* ··· 36 35 const void *here = __builtin_return_address(0); 37 36 if (skb) { 38 37 int n = atomic_read(select_skb_count(skb)); 39 - trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here); 38 + trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 39 + rxrpc_skb(skb)->rx_flags, here); 40 40 } 41 41 } 42 42 ··· 48 46 { 49 47 const void *here = __builtin_return_address(0); 50 48 int n = atomic_inc_return(select_skb_count(skb)); 51 - trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here); 49 + trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 50 + rxrpc_skb(skb)->rx_flags, here); 52 51 skb_get(skb); 52 + } 53 + 54 + /* 55 + * Note the dropping of a ref on a socket buffer by the core. 56 + */ 57 + void rxrpc_eaten_skb(struct sk_buff *skb, enum rxrpc_skb_trace op) 58 + { 59 + const void *here = __builtin_return_address(0); 60 + int n = atomic_inc_return(&rxrpc_n_rx_skbs); 61 + trace_rxrpc_skb(skb, op, 0, n, 0, here); 53 62 } 54 63 55 64 /* ··· 73 60 int n; 74 61 CHECK_SLAB_OKAY(&skb->users); 75 62 n = atomic_dec_return(select_skb_count(skb)); 76 - trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, here); 63 + trace_rxrpc_skb(skb, op, refcount_read(&skb->users), n, 64 + rxrpc_skb(skb)->rx_flags, here); 77 65 kfree_skb(skb); 78 66 } 79 67 } ··· 89 75 while ((skb = skb_dequeue((list))) != NULL) { 90 76 int n = atomic_dec_return(select_skb_count(skb)); 91 77 trace_rxrpc_skb(skb, rxrpc_skb_purged, 92 - refcount_read(&skb->users), n, here); 78 + refcount_read(&skb->users), n, 79 + rxrpc_skb(skb)->rx_flags, here); 93 80 kfree_skb(skb); 94 81 } 95 82 }