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.

caif: reduce stack size, again

I tried to fix the stack usage in this function a couple of years ago,
but there is still a problem with the latest gcc versions in some
configurations:

net/caif/cfctrl.c:553:1: error: the frame size of 1296 bytes is larger than 1280 bytes [-Werror=frame-larger-than=]

Reduce this once again, with a separate cfctrl_link_setup() function that
holds the bulk of all the local variables. It also turns out that the
param[] array that takes up a large portion of the stack is write-only
and can be left out here.

Fixes: ce6289661b14 ("caif: reduce stack size with KASAN")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Link: https://patch.msgid.link/20250620112244.3425554-1-arnd@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Arnd Bergmann and committed by
Jakub Kicinski
b630c781 7df6c024

+144 -150
+144 -150
net/caif/cfctrl.c
··· 351 351 return found; 352 352 } 353 353 354 + static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp) 355 + { 356 + u8 len; 357 + u8 linkid = 0; 358 + enum cfctrl_srv serv; 359 + enum cfctrl_srv servtype; 360 + u8 endpoint; 361 + u8 physlinkid; 362 + u8 prio; 363 + u8 tmp; 364 + u8 *cp; 365 + int i; 366 + struct cfctrl_link_param linkparam; 367 + struct cfctrl_request_info rsp, *req; 368 + 369 + memset(&linkparam, 0, sizeof(linkparam)); 370 + 371 + tmp = cfpkt_extr_head_u8(pkt); 372 + 373 + serv = tmp & CFCTRL_SRV_MASK; 374 + linkparam.linktype = serv; 375 + 376 + servtype = tmp >> 4; 377 + linkparam.chtype = servtype; 378 + 379 + tmp = cfpkt_extr_head_u8(pkt); 380 + physlinkid = tmp & 0x07; 381 + prio = tmp >> 3; 382 + 383 + linkparam.priority = prio; 384 + linkparam.phyid = physlinkid; 385 + endpoint = cfpkt_extr_head_u8(pkt); 386 + linkparam.endpoint = endpoint & 0x03; 387 + 388 + switch (serv) { 389 + case CFCTRL_SRV_VEI: 390 + case CFCTRL_SRV_DBG: 391 + if (CFCTRL_ERR_BIT & cmdrsp) 392 + break; 393 + /* Link ID */ 394 + linkid = cfpkt_extr_head_u8(pkt); 395 + break; 396 + case CFCTRL_SRV_VIDEO: 397 + tmp = cfpkt_extr_head_u8(pkt); 398 + linkparam.u.video.connid = tmp; 399 + if (CFCTRL_ERR_BIT & cmdrsp) 400 + break; 401 + /* Link ID */ 402 + linkid = cfpkt_extr_head_u8(pkt); 403 + break; 404 + 405 + case CFCTRL_SRV_DATAGRAM: 406 + linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt); 407 + if (CFCTRL_ERR_BIT & cmdrsp) 408 + break; 409 + /* Link ID */ 410 + linkid = cfpkt_extr_head_u8(pkt); 411 + break; 412 + case CFCTRL_SRV_RFM: 413 + /* Construct a frame, convert 414 + * DatagramConnectionID 415 + * to network format long and copy it out... 416 + */ 417 + linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt); 418 + cp = (u8 *) linkparam.u.rfm.volume; 419 + for (tmp = cfpkt_extr_head_u8(pkt); 420 + cfpkt_more(pkt) && tmp != '\0'; 421 + tmp = cfpkt_extr_head_u8(pkt)) 422 + *cp++ = tmp; 423 + *cp = '\0'; 424 + 425 + if (CFCTRL_ERR_BIT & cmdrsp) 426 + break; 427 + /* Link ID */ 428 + linkid = cfpkt_extr_head_u8(pkt); 429 + 430 + break; 431 + case CFCTRL_SRV_UTIL: 432 + /* Construct a frame, convert 433 + * DatagramConnectionID 434 + * to network format long and copy it out... 435 + */ 436 + /* Fifosize KB */ 437 + linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt); 438 + /* Fifosize bufs */ 439 + linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt); 440 + /* name */ 441 + cp = (u8 *) linkparam.u.utility.name; 442 + caif_assert(sizeof(linkparam.u.utility.name) 443 + >= UTILITY_NAME_LENGTH); 444 + for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) { 445 + tmp = cfpkt_extr_head_u8(pkt); 446 + *cp++ = tmp; 447 + } 448 + /* Length */ 449 + len = cfpkt_extr_head_u8(pkt); 450 + linkparam.u.utility.paramlen = len; 451 + /* Param Data */ 452 + cp = linkparam.u.utility.params; 453 + while (cfpkt_more(pkt) && len--) { 454 + tmp = cfpkt_extr_head_u8(pkt); 455 + *cp++ = tmp; 456 + } 457 + if (CFCTRL_ERR_BIT & cmdrsp) 458 + break; 459 + /* Link ID */ 460 + linkid = cfpkt_extr_head_u8(pkt); 461 + /* Length */ 462 + len = cfpkt_extr_head_u8(pkt); 463 + /* Param Data */ 464 + cfpkt_extr_head(pkt, NULL, len); 465 + break; 466 + default: 467 + pr_warn("Request setup, invalid type (%d)\n", serv); 468 + return -1; 469 + } 470 + 471 + rsp.cmd = CFCTRL_CMD_LINK_SETUP; 472 + rsp.param = linkparam; 473 + spin_lock_bh(&cfctrl->info_list_lock); 474 + req = cfctrl_remove_req(cfctrl, &rsp); 475 + 476 + if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || 477 + cfpkt_erroneous(pkt)) { 478 + pr_err("Invalid O/E bit or parse error " 479 + "on CAIF control channel\n"); 480 + cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0, 481 + req ? req->client_layer : NULL); 482 + } else { 483 + cfctrl->res.linksetup_rsp(cfctrl->serv.layer.up, linkid, 484 + serv, physlinkid, 485 + req ? req->client_layer : NULL); 486 + } 487 + 488 + kfree(req); 489 + 490 + spin_unlock_bh(&cfctrl->info_list_lock); 491 + 492 + return 0; 493 + } 494 + 354 495 static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) 355 496 { 356 497 u8 cmdrsp; 357 498 u8 cmd; 358 - int ret = -1; 359 - u8 len; 360 - u8 param[255]; 499 + int ret = 0; 361 500 u8 linkid = 0; 362 501 struct cfctrl *cfctrl = container_obj(layer); 363 - struct cfctrl_request_info rsp, *req; 364 - 365 502 366 503 cmdrsp = cfpkt_extr_head_u8(pkt); 367 504 cmd = cmdrsp & CFCTRL_CMD_MASK; ··· 511 374 512 375 switch (cmd) { 513 376 case CFCTRL_CMD_LINK_SETUP: 514 - { 515 - enum cfctrl_srv serv; 516 - enum cfctrl_srv servtype; 517 - u8 endpoint; 518 - u8 physlinkid; 519 - u8 prio; 520 - u8 tmp; 521 - u8 *cp; 522 - int i; 523 - struct cfctrl_link_param linkparam; 524 - memset(&linkparam, 0, sizeof(linkparam)); 525 - 526 - tmp = cfpkt_extr_head_u8(pkt); 527 - 528 - serv = tmp & CFCTRL_SRV_MASK; 529 - linkparam.linktype = serv; 530 - 531 - servtype = tmp >> 4; 532 - linkparam.chtype = servtype; 533 - 534 - tmp = cfpkt_extr_head_u8(pkt); 535 - physlinkid = tmp & 0x07; 536 - prio = tmp >> 3; 537 - 538 - linkparam.priority = prio; 539 - linkparam.phyid = physlinkid; 540 - endpoint = cfpkt_extr_head_u8(pkt); 541 - linkparam.endpoint = endpoint & 0x03; 542 - 543 - switch (serv) { 544 - case CFCTRL_SRV_VEI: 545 - case CFCTRL_SRV_DBG: 546 - if (CFCTRL_ERR_BIT & cmdrsp) 547 - break; 548 - /* Link ID */ 549 - linkid = cfpkt_extr_head_u8(pkt); 550 - break; 551 - case CFCTRL_SRV_VIDEO: 552 - tmp = cfpkt_extr_head_u8(pkt); 553 - linkparam.u.video.connid = tmp; 554 - if (CFCTRL_ERR_BIT & cmdrsp) 555 - break; 556 - /* Link ID */ 557 - linkid = cfpkt_extr_head_u8(pkt); 558 - break; 559 - 560 - case CFCTRL_SRV_DATAGRAM: 561 - linkparam.u.datagram.connid = 562 - cfpkt_extr_head_u32(pkt); 563 - if (CFCTRL_ERR_BIT & cmdrsp) 564 - break; 565 - /* Link ID */ 566 - linkid = cfpkt_extr_head_u8(pkt); 567 - break; 568 - case CFCTRL_SRV_RFM: 569 - /* Construct a frame, convert 570 - * DatagramConnectionID 571 - * to network format long and copy it out... 572 - */ 573 - linkparam.u.rfm.connid = 574 - cfpkt_extr_head_u32(pkt); 575 - cp = (u8 *) linkparam.u.rfm.volume; 576 - for (tmp = cfpkt_extr_head_u8(pkt); 577 - cfpkt_more(pkt) && tmp != '\0'; 578 - tmp = cfpkt_extr_head_u8(pkt)) 579 - *cp++ = tmp; 580 - *cp = '\0'; 581 - 582 - if (CFCTRL_ERR_BIT & cmdrsp) 583 - break; 584 - /* Link ID */ 585 - linkid = cfpkt_extr_head_u8(pkt); 586 - 587 - break; 588 - case CFCTRL_SRV_UTIL: 589 - /* Construct a frame, convert 590 - * DatagramConnectionID 591 - * to network format long and copy it out... 592 - */ 593 - /* Fifosize KB */ 594 - linkparam.u.utility.fifosize_kb = 595 - cfpkt_extr_head_u16(pkt); 596 - /* Fifosize bufs */ 597 - linkparam.u.utility.fifosize_bufs = 598 - cfpkt_extr_head_u16(pkt); 599 - /* name */ 600 - cp = (u8 *) linkparam.u.utility.name; 601 - caif_assert(sizeof(linkparam.u.utility.name) 602 - >= UTILITY_NAME_LENGTH); 603 - for (i = 0; 604 - i < UTILITY_NAME_LENGTH 605 - && cfpkt_more(pkt); i++) { 606 - tmp = cfpkt_extr_head_u8(pkt); 607 - *cp++ = tmp; 608 - } 609 - /* Length */ 610 - len = cfpkt_extr_head_u8(pkt); 611 - linkparam.u.utility.paramlen = len; 612 - /* Param Data */ 613 - cp = linkparam.u.utility.params; 614 - while (cfpkt_more(pkt) && len--) { 615 - tmp = cfpkt_extr_head_u8(pkt); 616 - *cp++ = tmp; 617 - } 618 - if (CFCTRL_ERR_BIT & cmdrsp) 619 - break; 620 - /* Link ID */ 621 - linkid = cfpkt_extr_head_u8(pkt); 622 - /* Length */ 623 - len = cfpkt_extr_head_u8(pkt); 624 - /* Param Data */ 625 - cfpkt_extr_head(pkt, &param, len); 626 - break; 627 - default: 628 - pr_warn("Request setup, invalid type (%d)\n", 629 - serv); 630 - goto error; 631 - } 632 - 633 - rsp.cmd = cmd; 634 - rsp.param = linkparam; 635 - spin_lock_bh(&cfctrl->info_list_lock); 636 - req = cfctrl_remove_req(cfctrl, &rsp); 637 - 638 - if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) || 639 - cfpkt_erroneous(pkt)) { 640 - pr_err("Invalid O/E bit or parse error " 641 - "on CAIF control channel\n"); 642 - cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 643 - 0, 644 - req ? req->client_layer 645 - : NULL); 646 - } else { 647 - cfctrl->res.linksetup_rsp(cfctrl->serv. 648 - layer.up, linkid, 649 - serv, physlinkid, 650 - req ? req-> 651 - client_layer : NULL); 652 - } 653 - 654 - kfree(req); 655 - 656 - spin_unlock_bh(&cfctrl->info_list_lock); 657 - } 377 + ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp); 658 378 break; 659 379 case CFCTRL_CMD_LINK_DESTROY: 660 380 linkid = cfpkt_extr_head_u8(pkt); ··· 538 544 break; 539 545 default: 540 546 pr_err("Unrecognized Control Frame\n"); 547 + ret = -1; 541 548 goto error; 542 549 } 543 - ret = 0; 544 550 error: 545 551 cfpkt_destroy(pkt); 546 552 return ret;