2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

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: ce6289661b ("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>
This commit is contained in:
Arnd Bergmann 2025-06-20 13:22:39 +02:00 committed by Jakub Kicinski
parent 7df6c02455
commit b630c781bc

View File

@ -351,30 +351,10 @@ int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
return found; return found;
} }
static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt) static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp)
{ {
u8 cmdrsp;
u8 cmd;
int ret = -1;
u8 len; u8 len;
u8 param[255];
u8 linkid = 0; u8 linkid = 0;
struct cfctrl *cfctrl = container_obj(layer);
struct cfctrl_request_info rsp, *req;
cmdrsp = cfpkt_extr_head_u8(pkt);
cmd = cmdrsp & CFCTRL_CMD_MASK;
if (cmd != CFCTRL_CMD_LINK_ERR
&& CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)
&& CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) {
if (handle_loop(cfctrl, cmd, pkt) != 0)
cmdrsp |= CFCTRL_ERR_BIT;
}
switch (cmd) {
case CFCTRL_CMD_LINK_SETUP:
{
enum cfctrl_srv serv; enum cfctrl_srv serv;
enum cfctrl_srv servtype; enum cfctrl_srv servtype;
u8 endpoint; u8 endpoint;
@ -384,6 +364,8 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
u8 *cp; u8 *cp;
int i; int i;
struct cfctrl_link_param linkparam; struct cfctrl_link_param linkparam;
struct cfctrl_request_info rsp, *req;
memset(&linkparam, 0, sizeof(linkparam)); memset(&linkparam, 0, sizeof(linkparam));
tmp = cfpkt_extr_head_u8(pkt); tmp = cfpkt_extr_head_u8(pkt);
@ -421,8 +403,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
break; break;
case CFCTRL_SRV_DATAGRAM: case CFCTRL_SRV_DATAGRAM:
linkparam.u.datagram.connid = linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt);
cfpkt_extr_head_u32(pkt);
if (CFCTRL_ERR_BIT & cmdrsp) if (CFCTRL_ERR_BIT & cmdrsp)
break; break;
/* Link ID */ /* Link ID */
@ -433,8 +414,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
* DatagramConnectionID * DatagramConnectionID
* to network format long and copy it out... * to network format long and copy it out...
*/ */
linkparam.u.rfm.connid = linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt);
cfpkt_extr_head_u32(pkt);
cp = (u8 *) linkparam.u.rfm.volume; cp = (u8 *) linkparam.u.rfm.volume;
for (tmp = cfpkt_extr_head_u8(pkt); for (tmp = cfpkt_extr_head_u8(pkt);
cfpkt_more(pkt) && tmp != '\0'; cfpkt_more(pkt) && tmp != '\0';
@ -454,18 +434,14 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
* to network format long and copy it out... * to network format long and copy it out...
*/ */
/* Fifosize KB */ /* Fifosize KB */
linkparam.u.utility.fifosize_kb = linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt);
cfpkt_extr_head_u16(pkt);
/* Fifosize bufs */ /* Fifosize bufs */
linkparam.u.utility.fifosize_bufs = linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt);
cfpkt_extr_head_u16(pkt);
/* name */ /* name */
cp = (u8 *) linkparam.u.utility.name; cp = (u8 *) linkparam.u.utility.name;
caif_assert(sizeof(linkparam.u.utility.name) caif_assert(sizeof(linkparam.u.utility.name)
>= UTILITY_NAME_LENGTH); >= UTILITY_NAME_LENGTH);
for (i = 0; for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) {
i < UTILITY_NAME_LENGTH
&& cfpkt_more(pkt); i++) {
tmp = cfpkt_extr_head_u8(pkt); tmp = cfpkt_extr_head_u8(pkt);
*cp++ = tmp; *cp++ = tmp;
} }
@ -485,15 +461,14 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
/* Length */ /* Length */
len = cfpkt_extr_head_u8(pkt); len = cfpkt_extr_head_u8(pkt);
/* Param Data */ /* Param Data */
cfpkt_extr_head(pkt, &param, len); cfpkt_extr_head(pkt, NULL, len);
break; break;
default: default:
pr_warn("Request setup, invalid type (%d)\n", pr_warn("Request setup, invalid type (%d)\n", serv);
serv); return -1;
goto error;
} }
rsp.cmd = cmd; rsp.cmd = CFCTRL_CMD_LINK_SETUP;
rsp.param = linkparam; rsp.param = linkparam;
spin_lock_bh(&cfctrl->info_list_lock); spin_lock_bh(&cfctrl->info_list_lock);
req = cfctrl_remove_req(cfctrl, &rsp); req = cfctrl_remove_req(cfctrl, &rsp);
@ -502,22 +477,41 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
cfpkt_erroneous(pkt)) { cfpkt_erroneous(pkt)) {
pr_err("Invalid O/E bit or parse error " pr_err("Invalid O/E bit or parse error "
"on CAIF control channel\n"); "on CAIF control channel\n");
cfctrl->res.reject_rsp(cfctrl->serv.layer.up, cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0,
0, req ? req->client_layer : NULL);
req ? req->client_layer
: NULL);
} else { } else {
cfctrl->res.linksetup_rsp(cfctrl->serv. cfctrl->res.linksetup_rsp(cfctrl->serv.layer.up, linkid,
layer.up, linkid,
serv, physlinkid, serv, physlinkid,
req ? req-> req ? req->client_layer : NULL);
client_layer : NULL);
} }
kfree(req); kfree(req);
spin_unlock_bh(&cfctrl->info_list_lock); spin_unlock_bh(&cfctrl->info_list_lock);
return 0;
}
static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
{
u8 cmdrsp;
u8 cmd;
int ret = 0;
u8 linkid = 0;
struct cfctrl *cfctrl = container_obj(layer);
cmdrsp = cfpkt_extr_head_u8(pkt);
cmd = cmdrsp & CFCTRL_CMD_MASK;
if (cmd != CFCTRL_CMD_LINK_ERR
&& CFCTRL_RSP_BIT != (CFCTRL_RSP_BIT & cmdrsp)
&& CFCTRL_ERR_BIT != (CFCTRL_ERR_BIT & cmdrsp)) {
if (handle_loop(cfctrl, cmd, pkt) != 0)
cmdrsp |= CFCTRL_ERR_BIT;
} }
switch (cmd) {
case CFCTRL_CMD_LINK_SETUP:
ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp);
break; break;
case CFCTRL_CMD_LINK_DESTROY: case CFCTRL_CMD_LINK_DESTROY:
linkid = cfpkt_extr_head_u8(pkt); linkid = cfpkt_extr_head_u8(pkt);
@ -544,9 +538,9 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
break; break;
default: default:
pr_err("Unrecognized Control Frame\n"); pr_err("Unrecognized Control Frame\n");
ret = -1;
goto error; goto error;
} }
ret = 0;
error: error:
cfpkt_destroy(pkt); cfpkt_destroy(pkt);
return ret; return ret;