Skip to content

Commit 86348d2

Browse files
Erick Archerkuba-moo
authored andcommitted
net: prestera: Add flex arrays to some structs
The "struct prestera_msg_vtcam_rule_add_req" uses a dynamically sized set of trailing elements. Specifically, it uses an array of structures of type "prestera_msg_acl_action actions_msg". The "struct prestera_msg_flood_domain_ports_set_req" also uses a dynamically sized set of trailing elements. Specifically, it uses an array of structures of type "prestera_msg_acl_action actions_msg". So, use the preferred way in the kernel declaring flexible arrays [1]. At the same time, prepare for the coming implementation by GCC and Clang of the __counted_by attribute. Flexible array members annotated with __counted_by can have their accesses bounds-checked at run-time via CONFIG_UBSAN_BOUNDS (for array indexing) and CONFIG_FORTIFY_SOURCE (for strcpy/memcpy-family functions). In this case, it is important to note that the attribute used is specifically __counted_by_le since the counters are of type __le32. The logic does not need to change since the counters for the flexible arrays are asigned before any access to the arrays. The order in which the structure prestera_msg_vtcam_rule_add_req and the structure prestera_msg_flood_domain_ports_set_req are defined must be changed to avoid incomplete type errors. Also, avoid the open-coded arithmetic in memory allocator functions [2] using the "struct_size" macro. Moreover, the new structure members also allow us to avoid the open- coded arithmetic on pointers. So, take advantage of this refactoring accordingly. This code was detected with the help of Coccinelle, and audited and modified manually. Link: https://www.kernel.org/doc/html/next/process/deprecated.html#zero-length-and-one-element-arrays [1] Link: https://www.kernel.org/doc/html/next/process/deprecated.html#open-coded-arithmetic-in-allocator-arguments [2] Signed-off-by: Erick Archer <[email protected]> Reviewed-by: Simon Horman <[email protected]> Reviewed-by: Kees Cook <[email protected]> Link: https://lore.kernel.org/r/AS8PR02MB7237E8469568A59795F1F0408BE12@AS8PR02MB7237.eurprd02.prod.outlook.com Signed-off-by: Jakub Kicinski <[email protected]>
1 parent a6fb986 commit 86348d2

File tree

1 file changed

+37
-46
lines changed

1 file changed

+37
-46
lines changed

drivers/net/ethernet/marvell/prestera/prestera_hw.c

Lines changed: 37 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -419,15 +419,6 @@ struct prestera_msg_vtcam_destroy_req {
419419
__le32 vtcam_id;
420420
};
421421

422-
struct prestera_msg_vtcam_rule_add_req {
423-
struct prestera_msg_cmd cmd;
424-
__le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
425-
__le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
426-
__le32 vtcam_id;
427-
__le32 prio;
428-
__le32 n_act;
429-
};
430-
431422
struct prestera_msg_vtcam_rule_del_req {
432423
struct prestera_msg_cmd cmd;
433424
__le32 vtcam_id;
@@ -471,6 +462,16 @@ struct prestera_msg_acl_action {
471462
};
472463
};
473464

465+
struct prestera_msg_vtcam_rule_add_req {
466+
struct prestera_msg_cmd cmd;
467+
__le32 key[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
468+
__le32 keymask[__PRESTERA_ACL_RULE_MATCH_TYPE_MAX];
469+
__le32 vtcam_id;
470+
__le32 prio;
471+
__le32 n_act;
472+
struct prestera_msg_acl_action actions_msg[] __counted_by_le(n_act);
473+
};
474+
474475
struct prestera_msg_counter_req {
475476
struct prestera_msg_cmd cmd;
476477
__le32 client;
@@ -702,12 +703,6 @@ struct prestera_msg_flood_domain_destroy_req {
702703
__le32 flood_domain_idx;
703704
};
704705

705-
struct prestera_msg_flood_domain_ports_set_req {
706-
struct prestera_msg_cmd cmd;
707-
__le32 flood_domain_idx;
708-
__le32 ports_num;
709-
};
710-
711706
struct prestera_msg_flood_domain_ports_reset_req {
712707
struct prestera_msg_cmd cmd;
713708
__le32 flood_domain_idx;
@@ -725,6 +720,13 @@ struct prestera_msg_flood_domain_port {
725720
__le16 port_type;
726721
};
727722

723+
struct prestera_msg_flood_domain_ports_set_req {
724+
struct prestera_msg_cmd cmd;
725+
__le32 flood_domain_idx;
726+
__le32 ports_num;
727+
struct prestera_msg_flood_domain_port ports[] __counted_by_le(ports_num);
728+
};
729+
728730
struct prestera_msg_mdb_create_req {
729731
struct prestera_msg_cmd cmd;
730732
__le32 flood_domain_idx;
@@ -1371,31 +1373,26 @@ int prestera_hw_vtcam_rule_add(struct prestera_switch *sw,
13711373
struct prestera_acl_hw_action_info *act,
13721374
u8 n_act, u32 *rule_id)
13731375
{
1374-
struct prestera_msg_acl_action *actions_msg;
13751376
struct prestera_msg_vtcam_rule_add_req *req;
13761377
struct prestera_msg_vtcam_resp resp;
1377-
void *buff;
1378-
u32 size;
1378+
size_t size;
13791379
int err;
13801380
u8 i;
13811381

1382-
size = sizeof(*req) + sizeof(*actions_msg) * n_act;
1383-
1384-
buff = kzalloc(size, GFP_KERNEL);
1385-
if (!buff)
1382+
size = struct_size(req, actions_msg, n_act);
1383+
req = kzalloc(size, GFP_KERNEL);
1384+
if (!req)
13861385
return -ENOMEM;
13871386

1388-
req = buff;
13891387
req->n_act = __cpu_to_le32(n_act);
1390-
actions_msg = buff + sizeof(*req);
13911388

13921389
/* put acl matches into the message */
13931390
memcpy(req->key, key, sizeof(req->key));
13941391
memcpy(req->keymask, keymask, sizeof(req->keymask));
13951392

13961393
/* put acl actions into the message */
13971394
for (i = 0; i < n_act; i++) {
1398-
err = prestera_acl_rule_add_put_action(&actions_msg[i],
1395+
err = prestera_acl_rule_add_put_action(&req->actions_msg[i],
13991396
&act[i]);
14001397
if (err)
14011398
goto free_buff;
@@ -1411,7 +1408,7 @@ int prestera_hw_vtcam_rule_add(struct prestera_switch *sw,
14111408

14121409
*rule_id = __le32_to_cpu(resp.rule_id);
14131410
free_buff:
1414-
kfree(buff);
1411+
kfree(req);
14151412
return err;
14161413
}
14171414

@@ -2461,14 +2458,13 @@ int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain)
24612458
{
24622459
struct prestera_flood_domain_port *flood_domain_port;
24632460
struct prestera_msg_flood_domain_ports_set_req *req;
2464-
struct prestera_msg_flood_domain_port *ports;
24652461
struct prestera_switch *sw = domain->sw;
24662462
struct prestera_port *port;
24672463
u32 ports_num = 0;
2468-
int buf_size;
2469-
void *buff;
2464+
size_t buf_size;
24702465
u16 lag_id;
24712466
int err;
2467+
int i = 0;
24722468

24732469
list_for_each_entry(flood_domain_port, &domain->flood_domain_port_list,
24742470
flood_domain_port_node)
@@ -2477,15 +2473,11 @@ int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain)
24772473
if (!ports_num)
24782474
return -EINVAL;
24792475

2480-
buf_size = sizeof(*req) + sizeof(*ports) * ports_num;
2481-
2482-
buff = kmalloc(buf_size, GFP_KERNEL);
2483-
if (!buff)
2476+
buf_size = struct_size(req, ports, ports_num);
2477+
req = kmalloc(buf_size, GFP_KERNEL);
2478+
if (!req)
24842479
return -ENOMEM;
24852480

2486-
req = buff;
2487-
ports = buff + sizeof(*req);
2488-
24892481
req->flood_domain_idx = __cpu_to_le32(domain->idx);
24902482
req->ports_num = __cpu_to_le32(ports_num);
24912483

@@ -2494,31 +2486,30 @@ int prestera_hw_flood_domain_ports_set(struct prestera_flood_domain *domain)
24942486
if (netif_is_lag_master(flood_domain_port->dev)) {
24952487
if (prestera_lag_id(sw, flood_domain_port->dev,
24962488
&lag_id)) {
2497-
kfree(buff);
2489+
kfree(req);
24982490
return -EINVAL;
24992491
}
25002492

2501-
ports->port_type =
2493+
req->ports[i].port_type =
25022494
__cpu_to_le16(PRESTERA_HW_FLOOD_DOMAIN_PORT_TYPE_LAG);
2503-
ports->lag_id = __cpu_to_le16(lag_id);
2495+
req->ports[i].lag_id = __cpu_to_le16(lag_id);
25042496
} else {
25052497
port = prestera_port_dev_lower_find(flood_domain_port->dev);
25062498

2507-
ports->port_type =
2499+
req->ports[i].port_type =
25082500
__cpu_to_le16(PRESTERA_HW_FDB_ENTRY_TYPE_REG_PORT);
2509-
ports->dev_num = __cpu_to_le32(port->dev_id);
2510-
ports->port_num = __cpu_to_le32(port->hw_id);
2501+
req->ports[i].dev_num = __cpu_to_le32(port->dev_id);
2502+
req->ports[i].port_num = __cpu_to_le32(port->hw_id);
25112503
}
25122504

2513-
ports->vid = __cpu_to_le16(flood_domain_port->vid);
2514-
2515-
ports++;
2505+
req->ports[i].vid = __cpu_to_le16(flood_domain_port->vid);
2506+
i++;
25162507
}
25172508

25182509
err = prestera_cmd(sw, PRESTERA_CMD_TYPE_FLOOD_DOMAIN_PORTS_SET,
25192510
&req->cmd, buf_size);
25202511

2521-
kfree(buff);
2512+
kfree(req);
25222513

25232514
return err;
25242515
}

0 commit comments

Comments
 (0)