mirror of
https://github.com/torvalds/linux.git
synced 2025-08-15 14:11:42 +02: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:
parent
7df6c02455
commit
b630c781bc
1 changed files with 144 additions and 150 deletions
|
@ -351,17 +351,154 @@ int cfctrl_cancel_req(struct cflayer *layr, struct cflayer *adap_layer)
|
|||
return found;
|
||||
}
|
||||
|
||||
static int cfctrl_link_setup(struct cfctrl *cfctrl, struct cfpkt *pkt, u8 cmdrsp)
|
||||
{
|
||||
u8 len;
|
||||
u8 linkid = 0;
|
||||
enum cfctrl_srv serv;
|
||||
enum cfctrl_srv servtype;
|
||||
u8 endpoint;
|
||||
u8 physlinkid;
|
||||
u8 prio;
|
||||
u8 tmp;
|
||||
u8 *cp;
|
||||
int i;
|
||||
struct cfctrl_link_param linkparam;
|
||||
struct cfctrl_request_info rsp, *req;
|
||||
|
||||
memset(&linkparam, 0, sizeof(linkparam));
|
||||
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
|
||||
serv = tmp & CFCTRL_SRV_MASK;
|
||||
linkparam.linktype = serv;
|
||||
|
||||
servtype = tmp >> 4;
|
||||
linkparam.chtype = servtype;
|
||||
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
physlinkid = tmp & 0x07;
|
||||
prio = tmp >> 3;
|
||||
|
||||
linkparam.priority = prio;
|
||||
linkparam.phyid = physlinkid;
|
||||
endpoint = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.endpoint = endpoint & 0x03;
|
||||
|
||||
switch (serv) {
|
||||
case CFCTRL_SRV_VEI:
|
||||
case CFCTRL_SRV_DBG:
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
case CFCTRL_SRV_VIDEO:
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.u.video.connid = tmp;
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
|
||||
case CFCTRL_SRV_DATAGRAM:
|
||||
linkparam.u.datagram.connid = cfpkt_extr_head_u32(pkt);
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
case CFCTRL_SRV_RFM:
|
||||
/* Construct a frame, convert
|
||||
* DatagramConnectionID
|
||||
* to network format long and copy it out...
|
||||
*/
|
||||
linkparam.u.rfm.connid = cfpkt_extr_head_u32(pkt);
|
||||
cp = (u8 *) linkparam.u.rfm.volume;
|
||||
for (tmp = cfpkt_extr_head_u8(pkt);
|
||||
cfpkt_more(pkt) && tmp != '\0';
|
||||
tmp = cfpkt_extr_head_u8(pkt))
|
||||
*cp++ = tmp;
|
||||
*cp = '\0';
|
||||
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
|
||||
break;
|
||||
case CFCTRL_SRV_UTIL:
|
||||
/* Construct a frame, convert
|
||||
* DatagramConnectionID
|
||||
* to network format long and copy it out...
|
||||
*/
|
||||
/* Fifosize KB */
|
||||
linkparam.u.utility.fifosize_kb = cfpkt_extr_head_u16(pkt);
|
||||
/* Fifosize bufs */
|
||||
linkparam.u.utility.fifosize_bufs = cfpkt_extr_head_u16(pkt);
|
||||
/* name */
|
||||
cp = (u8 *) linkparam.u.utility.name;
|
||||
caif_assert(sizeof(linkparam.u.utility.name)
|
||||
>= UTILITY_NAME_LENGTH);
|
||||
for (i = 0; i < UTILITY_NAME_LENGTH && cfpkt_more(pkt); i++) {
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
*cp++ = tmp;
|
||||
}
|
||||
/* Length */
|
||||
len = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.u.utility.paramlen = len;
|
||||
/* Param Data */
|
||||
cp = linkparam.u.utility.params;
|
||||
while (cfpkt_more(pkt) && len--) {
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
*cp++ = tmp;
|
||||
}
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
/* Length */
|
||||
len = cfpkt_extr_head_u8(pkt);
|
||||
/* Param Data */
|
||||
cfpkt_extr_head(pkt, NULL, len);
|
||||
break;
|
||||
default:
|
||||
pr_warn("Request setup, invalid type (%d)\n", serv);
|
||||
return -1;
|
||||
}
|
||||
|
||||
rsp.cmd = CFCTRL_CMD_LINK_SETUP;
|
||||
rsp.param = linkparam;
|
||||
spin_lock_bh(&cfctrl->info_list_lock);
|
||||
req = cfctrl_remove_req(cfctrl, &rsp);
|
||||
|
||||
if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
|
||||
cfpkt_erroneous(pkt)) {
|
||||
pr_err("Invalid O/E bit or parse error "
|
||||
"on CAIF control channel\n");
|
||||
cfctrl->res.reject_rsp(cfctrl->serv.layer.up, 0,
|
||||
req ? req->client_layer : NULL);
|
||||
} else {
|
||||
cfctrl->res.linksetup_rsp(cfctrl->serv.layer.up, linkid,
|
||||
serv, physlinkid,
|
||||
req ? req->client_layer : NULL);
|
||||
}
|
||||
|
||||
kfree(req);
|
||||
|
||||
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 = -1;
|
||||
u8 len;
|
||||
u8 param[255];
|
||||
int ret = 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;
|
||||
|
@ -374,150 +511,7 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
|
|||
|
||||
switch (cmd) {
|
||||
case CFCTRL_CMD_LINK_SETUP:
|
||||
{
|
||||
enum cfctrl_srv serv;
|
||||
enum cfctrl_srv servtype;
|
||||
u8 endpoint;
|
||||
u8 physlinkid;
|
||||
u8 prio;
|
||||
u8 tmp;
|
||||
u8 *cp;
|
||||
int i;
|
||||
struct cfctrl_link_param linkparam;
|
||||
memset(&linkparam, 0, sizeof(linkparam));
|
||||
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
|
||||
serv = tmp & CFCTRL_SRV_MASK;
|
||||
linkparam.linktype = serv;
|
||||
|
||||
servtype = tmp >> 4;
|
||||
linkparam.chtype = servtype;
|
||||
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
physlinkid = tmp & 0x07;
|
||||
prio = tmp >> 3;
|
||||
|
||||
linkparam.priority = prio;
|
||||
linkparam.phyid = physlinkid;
|
||||
endpoint = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.endpoint = endpoint & 0x03;
|
||||
|
||||
switch (serv) {
|
||||
case CFCTRL_SRV_VEI:
|
||||
case CFCTRL_SRV_DBG:
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
case CFCTRL_SRV_VIDEO:
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.u.video.connid = tmp;
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
|
||||
case CFCTRL_SRV_DATAGRAM:
|
||||
linkparam.u.datagram.connid =
|
||||
cfpkt_extr_head_u32(pkt);
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
break;
|
||||
case CFCTRL_SRV_RFM:
|
||||
/* Construct a frame, convert
|
||||
* DatagramConnectionID
|
||||
* to network format long and copy it out...
|
||||
*/
|
||||
linkparam.u.rfm.connid =
|
||||
cfpkt_extr_head_u32(pkt);
|
||||
cp = (u8 *) linkparam.u.rfm.volume;
|
||||
for (tmp = cfpkt_extr_head_u8(pkt);
|
||||
cfpkt_more(pkt) && tmp != '\0';
|
||||
tmp = cfpkt_extr_head_u8(pkt))
|
||||
*cp++ = tmp;
|
||||
*cp = '\0';
|
||||
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
|
||||
break;
|
||||
case CFCTRL_SRV_UTIL:
|
||||
/* Construct a frame, convert
|
||||
* DatagramConnectionID
|
||||
* to network format long and copy it out...
|
||||
*/
|
||||
/* Fifosize KB */
|
||||
linkparam.u.utility.fifosize_kb =
|
||||
cfpkt_extr_head_u16(pkt);
|
||||
/* Fifosize bufs */
|
||||
linkparam.u.utility.fifosize_bufs =
|
||||
cfpkt_extr_head_u16(pkt);
|
||||
/* name */
|
||||
cp = (u8 *) linkparam.u.utility.name;
|
||||
caif_assert(sizeof(linkparam.u.utility.name)
|
||||
>= UTILITY_NAME_LENGTH);
|
||||
for (i = 0;
|
||||
i < UTILITY_NAME_LENGTH
|
||||
&& cfpkt_more(pkt); i++) {
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
*cp++ = tmp;
|
||||
}
|
||||
/* Length */
|
||||
len = cfpkt_extr_head_u8(pkt);
|
||||
linkparam.u.utility.paramlen = len;
|
||||
/* Param Data */
|
||||
cp = linkparam.u.utility.params;
|
||||
while (cfpkt_more(pkt) && len--) {
|
||||
tmp = cfpkt_extr_head_u8(pkt);
|
||||
*cp++ = tmp;
|
||||
}
|
||||
if (CFCTRL_ERR_BIT & cmdrsp)
|
||||
break;
|
||||
/* Link ID */
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
/* Length */
|
||||
len = cfpkt_extr_head_u8(pkt);
|
||||
/* Param Data */
|
||||
cfpkt_extr_head(pkt, ¶m, len);
|
||||
break;
|
||||
default:
|
||||
pr_warn("Request setup, invalid type (%d)\n",
|
||||
serv);
|
||||
goto error;
|
||||
}
|
||||
|
||||
rsp.cmd = cmd;
|
||||
rsp.param = linkparam;
|
||||
spin_lock_bh(&cfctrl->info_list_lock);
|
||||
req = cfctrl_remove_req(cfctrl, &rsp);
|
||||
|
||||
if (CFCTRL_ERR_BIT == (CFCTRL_ERR_BIT & cmdrsp) ||
|
||||
cfpkt_erroneous(pkt)) {
|
||||
pr_err("Invalid O/E bit or parse error "
|
||||
"on CAIF control channel\n");
|
||||
cfctrl->res.reject_rsp(cfctrl->serv.layer.up,
|
||||
0,
|
||||
req ? req->client_layer
|
||||
: NULL);
|
||||
} else {
|
||||
cfctrl->res.linksetup_rsp(cfctrl->serv.
|
||||
layer.up, linkid,
|
||||
serv, physlinkid,
|
||||
req ? req->
|
||||
client_layer : NULL);
|
||||
}
|
||||
|
||||
kfree(req);
|
||||
|
||||
spin_unlock_bh(&cfctrl->info_list_lock);
|
||||
}
|
||||
ret = cfctrl_link_setup(cfctrl, pkt, cmdrsp);
|
||||
break;
|
||||
case CFCTRL_CMD_LINK_DESTROY:
|
||||
linkid = cfpkt_extr_head_u8(pkt);
|
||||
|
@ -544,9 +538,9 @@ static int cfctrl_recv(struct cflayer *layer, struct cfpkt *pkt)
|
|||
break;
|
||||
default:
|
||||
pr_err("Unrecognized Control Frame\n");
|
||||
ret = -1;
|
||||
goto error;
|
||||
}
|
||||
ret = 0;
|
||||
error:
|
||||
cfpkt_destroy(pkt);
|
||||
return ret;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue