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

Configure Feed

Select the types of activity you want to include in your feed.

rxrpc: Separate the packet length from the data length in rxrpc_txbuf

Separate the packet length from the data length (txb->len) stored in the
rxrpc_txbuf to make security calculations easier. Also store the
allocation size as that's an upper bound on the size of the security
wrapper and change a number of fields to unsigned short as the amount of
data can't exceed the capacity of a UDP packet.

Also, whilst we're at it, use kzalloc() for txbufs.

Signed-off-by: David Howells <dhowells@redhat.com>
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
Link: https://patch.msgid.link/20241204074710.990092-11-dhowells@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

David Howells and committed by
Jakub Kicinski
3d2bdf73 eeaedc54

+36 -32
+5 -3
net/rxrpc/ar-internal.h
··· 821 821 rxrpc_serial_t serial; /* Last serial number transmitted with */ 822 822 unsigned int call_debug_id; 823 823 unsigned int debug_id; 824 - unsigned int len; /* Amount of data in buffer */ 825 - unsigned int space; /* Remaining data space */ 826 - unsigned int offset; /* Offset of fill point */ 824 + unsigned short len; /* Amount of data in buffer */ 825 + unsigned short space; /* Remaining data space */ 826 + unsigned short offset; /* Offset of fill point */ 827 + unsigned short pkt_len; /* Size of packet content */ 828 + unsigned short alloc_size; /* Amount of bufferage allocated */ 827 829 unsigned int flags; 828 830 #define RXRPC_TXBUF_WIRE_FLAGS 0xff /* The wire protocol flags */ 829 831 #define RXRPC_TXBUF_RESENT 0x100 /* Set if has been resent */
+1
net/rxrpc/insecure.c
··· 24 24 25 25 static int none_secure_packet(struct rxrpc_call *call, struct rxrpc_txbuf *txb) 26 26 { 27 + txb->pkt_len = txb->len; 27 28 return 0; 28 29 } 29 30
+4 -3
net/rxrpc/output.c
··· 383 383 enum rxrpc_req_ack_trace why; 384 384 struct rxrpc_connection *conn = call->conn; 385 385 struct kvec *kv = &call->local->kvec[subpkt]; 386 - size_t len = txb->len; 386 + size_t len = txb->pkt_len; 387 387 bool last, more; 388 388 u8 flags; 389 389 390 - _enter("%x,{%d}", txb->seq, txb->len); 390 + _enter("%x,%zd", txb->seq, len); 391 391 392 392 txb->serial = serial; 393 393 ··· 441 441 whdr->cksum = txb->cksum; 442 442 whdr->serviceId = htons(conn->service_id); 443 443 kv->iov_base = whdr; 444 + len += sizeof(*whdr); 444 445 // TODO: Convert into a jumbo header for tail subpackets 445 446 446 447 trace_rxrpc_tx_data(call, txb->seq, txb->serial, flags, false); ··· 510 509 size_t len; 511 510 int ret; 512 511 513 - _enter("%x,{%d}", txb->seq, txb->len); 512 + _enter("%x,{%d}", txb->seq, txb->pkt_len); 514 513 515 514 len = rxrpc_prepare_data_packet(call, txb); 516 515
+24 -20
net/rxrpc/rxkad.c
··· 148 148 static struct rxrpc_txbuf *rxkad_alloc_txbuf(struct rxrpc_call *call, size_t remain, gfp_t gfp) 149 149 { 150 150 struct rxrpc_txbuf *txb; 151 - size_t shdr, space; 151 + size_t shdr, alloc, limit, part; 152 152 153 153 remain = umin(remain, 65535 - sizeof(struct rxrpc_wire_header)); 154 154 155 155 switch (call->conn->security_level) { 156 156 default: 157 - space = umin(remain, RXRPC_JUMBO_DATALEN); 158 - return rxrpc_alloc_data_txbuf(call, space, 1, gfp); 157 + alloc = umin(remain, RXRPC_JUMBO_DATALEN); 158 + return rxrpc_alloc_data_txbuf(call, alloc, 1, gfp); 159 159 case RXRPC_SECURITY_AUTH: 160 160 shdr = sizeof(struct rxkad_level1_hdr); 161 161 break; ··· 164 164 break; 165 165 } 166 166 167 - space = umin(round_down(RXRPC_JUMBO_DATALEN, RXKAD_ALIGN), remain + shdr); 168 - space = round_up(space, RXKAD_ALIGN); 167 + limit = round_down(RXRPC_JUMBO_DATALEN, RXKAD_ALIGN) - shdr; 168 + if (remain < limit) { 169 + part = remain; 170 + alloc = round_up(shdr + part, RXKAD_ALIGN); 171 + } else { 172 + part = limit; 173 + alloc = RXRPC_JUMBO_DATALEN; 174 + } 169 175 170 - txb = rxrpc_alloc_data_txbuf(call, space, RXKAD_ALIGN, gfp); 176 + txb = rxrpc_alloc_data_txbuf(call, alloc, RXKAD_ALIGN, gfp); 171 177 if (!txb) 172 178 return NULL; 173 179 174 180 txb->offset += shdr; 175 - txb->space -= shdr; 181 + txb->space = part; 176 182 return txb; 177 183 } 178 184 ··· 269 263 check = txb->seq ^ call->call_id; 270 264 hdr->data_size = htonl((u32)check << 16 | txb->len); 271 265 272 - txb->len += sizeof(struct rxkad_level1_hdr); 273 - pad = txb->len; 266 + txb->pkt_len = sizeof(struct rxkad_level1_hdr) + txb->len; 267 + pad = txb->pkt_len; 274 268 pad = RXKAD_ALIGN - pad; 275 269 pad &= RXKAD_ALIGN - 1; 276 270 if (pad) { 277 271 memset(txb->kvec[0].iov_base + txb->offset, 0, pad); 278 - txb->len += pad; 272 + txb->pkt_len += pad; 279 273 } 280 274 281 275 /* start the encryption afresh */ ··· 304 298 struct rxkad_level2_hdr *rxkhdr = (void *)(whdr + 1); 305 299 struct rxrpc_crypt iv; 306 300 struct scatterlist sg; 307 - size_t pad; 301 + size_t content, pad; 308 302 u16 check; 309 303 int ret; 310 304 ··· 315 309 rxkhdr->data_size = htonl(txb->len | (u32)check << 16); 316 310 rxkhdr->checksum = 0; 317 311 318 - txb->len += sizeof(struct rxkad_level2_hdr); 319 - pad = txb->len; 320 - pad = RXKAD_ALIGN - pad; 321 - pad &= RXKAD_ALIGN - 1; 322 - if (pad) { 312 + content = sizeof(struct rxkad_level2_hdr) + txb->len; 313 + txb->pkt_len = round_up(content, RXKAD_ALIGN); 314 + pad = txb->pkt_len - content; 315 + if (pad) 323 316 memset(txb->kvec[0].iov_base + txb->offset, 0, pad); 324 - txb->len += pad; 325 - } 326 317 327 318 /* encrypt from the session key */ 328 319 token = call->conn->key->payload.data[0]; 329 320 memcpy(&iv, token->kad->session_key, sizeof(iv)); 330 321 331 - sg_init_one(&sg, rxkhdr, txb->len); 322 + sg_init_one(&sg, rxkhdr, txb->pkt_len); 332 323 skcipher_request_set_sync_tfm(req, call->conn->rxkad.cipher); 333 324 skcipher_request_set_callback(req, 0, NULL, NULL); 334 - skcipher_request_set_crypt(req, &sg, &sg, txb->len, iv.x); 325 + skcipher_request_set_crypt(req, &sg, &sg, txb->pkt_len, iv.x); 335 326 ret = crypto_skcipher_encrypt(req); 336 327 skcipher_request_zero(req); 337 328 return ret; ··· 387 384 388 385 switch (call->conn->security_level) { 389 386 case RXRPC_SECURITY_PLAIN: 387 + txb->pkt_len = txb->len; 390 388 ret = 0; 391 389 break; 392 390 case RXRPC_SECURITY_AUTH:
-1
net/rxrpc/sendmsg.c
··· 391 391 goto out; 392 392 393 393 txb->kvec[0].iov_len += txb->len; 394 - txb->len = txb->kvec[0].iov_len; 395 394 rxrpc_queue_packet(rx, call, txb, notify_end_tx); 396 395 txb = NULL; 397 396 }
+2 -5
net/rxrpc/txbuf.c
··· 24 24 size_t total, hoff; 25 25 void *buf; 26 26 27 - txb = kmalloc(sizeof(*txb), gfp); 27 + txb = kzalloc(sizeof(*txb), gfp); 28 28 if (!txb) 29 29 return NULL; 30 30 ··· 49 49 txb->last_sent = KTIME_MIN; 50 50 txb->call_debug_id = call->debug_id; 51 51 txb->debug_id = atomic_inc_return(&rxrpc_txbuf_debug_ids); 52 + txb->alloc_size = data_size; 52 53 txb->space = data_size; 53 - txb->len = 0; 54 54 txb->offset = sizeof(*whdr); 55 55 txb->flags = call->conn->out_clientflag; 56 - txb->ack_why = 0; 57 56 txb->seq = call->tx_prepared + 1; 58 - txb->serial = 0; 59 - txb->cksum = 0; 60 57 txb->nr_kvec = 1; 61 58 txb->kvec[0].iov_base = whdr; 62 59 txb->kvec[0].iov_len = sizeof(*whdr);