Skip to content

Commit d67790d

Browse files
committed
overflow: Add struct_size_t() helper
While struct_size() is normally used in situations where the structure type already has a pointer instance, there are places where no variable is available. In the past, this has been worked around by using a typed NULL first argument, but this is a bit ugly. Add a helper to do this, and replace the handful of instances of the code pattern with it. Instances were found with this Coccinelle script: @struct_size_t@ identifier STRUCT, MEMBER; expression COUNT; @@ - struct_size((struct STRUCT *)\(0\|NULL\), + struct_size_t(struct STRUCT, MEMBER, COUNT) Suggested-by: Christoph Hellwig <hch@infradead.org> Cc: Jesse Brandeburg <jesse.brandeburg@intel.com> Cc: Tony Nguyen <anthony.l.nguyen@intel.com> Cc: "David S. Miller" <davem@davemloft.net> Cc: Eric Dumazet <edumazet@google.com> Cc: Paolo Abeni <pabeni@redhat.com> Cc: James Smart <james.smart@broadcom.com> Cc: Keith Busch <kbusch@kernel.org> Cc: Jens Axboe <axboe@kernel.dk> Cc: Sagi Grimberg <sagi@grimberg.me> Cc: HighPoint Linux Team <linux@highpoint-tech.com> Cc: "James E.J. Bottomley" <jejb@linux.ibm.com> Cc: "Martin K. Petersen" <martin.petersen@oracle.com> Cc: Kashyap Desai <kashyap.desai@broadcom.com> Cc: Sumit Saxena <sumit.saxena@broadcom.com> Cc: Shivasharan S <shivasharan.srikanteshwara@broadcom.com> Cc: Don Brace <don.brace@microchip.com> Cc: "Darrick J. Wong" <djwong@kernel.org> Cc: Dave Chinner <dchinner@redhat.com> Cc: Guo Xuenan <guoxuenan@huawei.com> Cc: Gwan-gyeong Mun <gwan-gyeong.mun@intel.com> Cc: Nick Desaulniers <ndesaulniers@google.com> Cc: Daniel Latypov <dlatypov@google.com> Cc: kernel test robot <lkp@intel.com> Cc: intel-wired-lan@lists.osuosl.org Cc: netdev@vger.kernel.org Cc: linux-nvme@lists.infradead.org Cc: linux-scsi@vger.kernel.org Cc: megaraidlinux.pdl@broadcom.com Cc: storagedev@microchip.com Cc: linux-xfs@vger.kernel.org Cc: linux-hardening@vger.kernel.org Signed-off-by: Kees Cook <keescook@chromium.org> Acked-by: Martin K. Petersen <martin.petersen@oracle.com> Reviewed-by: Darrick J. Wong <djwong@kernel.org> Reviewed-by: Gustavo A. R. Silva <gustavoars@kernel.org> Reviewed-by: Christoph Hellwig <hch@lst.de> Acked-by: Jakub Kicinski <kuba@kernel.org> Reviewed-by: Alexander Lobakin <aleksander.lobakin@intel.com> Link: https://lore.kernel.org/r/20230522211810.never.421-kees@kernel.org
1 parent 7f09a3a commit d67790d

10 files changed

Lines changed: 40 additions & 25 deletions

File tree

drivers/net/ethernet/intel/ice/ice_ddp.h

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct ice_buf_hdr {
185185

186186
#define ICE_MAX_ENTRIES_IN_BUF(hd_sz, ent_sz) \
187187
((ICE_PKG_BUF_SIZE - \
188-
struct_size((struct ice_buf_hdr *)0, section_entry, 1) - (hd_sz)) / \
188+
struct_size_t(struct ice_buf_hdr, section_entry, 1) - (hd_sz)) / \
189189
(ent_sz))
190190

191191
/* ice package section IDs */
@@ -297,7 +297,7 @@ struct ice_label_section {
297297
};
298298

299299
#define ICE_MAX_LABELS_IN_BUF \
300-
ICE_MAX_ENTRIES_IN_BUF(struct_size((struct ice_label_section *)0, \
300+
ICE_MAX_ENTRIES_IN_BUF(struct_size_t(struct ice_label_section, \
301301
label, 1) - \
302302
sizeof(struct ice_label), \
303303
sizeof(struct ice_label))
@@ -352,7 +352,7 @@ struct ice_boost_tcam_section {
352352
};
353353

354354
#define ICE_MAX_BST_TCAMS_IN_BUF \
355-
ICE_MAX_ENTRIES_IN_BUF(struct_size((struct ice_boost_tcam_section *)0, \
355+
ICE_MAX_ENTRIES_IN_BUF(struct_size_t(struct ice_boost_tcam_section, \
356356
tcam, 1) - \
357357
sizeof(struct ice_boost_tcam_entry), \
358358
sizeof(struct ice_boost_tcam_entry))
@@ -372,8 +372,7 @@ struct ice_marker_ptype_tcam_section {
372372
};
373373

374374
#define ICE_MAX_MARKER_PTYPE_TCAMS_IN_BUF \
375-
ICE_MAX_ENTRIES_IN_BUF( \
376-
struct_size((struct ice_marker_ptype_tcam_section *)0, tcam, \
375+
ICE_MAX_ENTRIES_IN_BUF(struct_size_t(struct ice_marker_ptype_tcam_section, tcam, \
377376
1) - \
378377
sizeof(struct ice_marker_ptype_tcam_entry), \
379378
sizeof(struct ice_marker_ptype_tcam_entry))

drivers/nvme/host/fc.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2917,8 +2917,8 @@ nvme_fc_create_io_queues(struct nvme_fc_ctrl *ctrl)
29172917

29182918
ret = nvme_alloc_io_tag_set(&ctrl->ctrl, &ctrl->tag_set,
29192919
&nvme_fc_mq_ops, 1,
2920-
struct_size((struct nvme_fcp_op_w_sgl *)NULL, priv,
2921-
ctrl->lport->ops->fcprqst_priv_sz));
2920+
struct_size_t(struct nvme_fcp_op_w_sgl, priv,
2921+
ctrl->lport->ops->fcprqst_priv_sz));
29222922
if (ret)
29232923
return ret;
29242924

@@ -3536,8 +3536,8 @@ nvme_fc_init_ctrl(struct device *dev, struct nvmf_ctrl_options *opts,
35363536

35373537
ret = nvme_alloc_admin_tag_set(&ctrl->ctrl, &ctrl->admin_tag_set,
35383538
&nvme_fc_admin_mq_ops,
3539-
struct_size((struct nvme_fcp_op_w_sgl *)NULL, priv,
3540-
ctrl->lport->ops->fcprqst_priv_sz));
3539+
struct_size_t(struct nvme_fcp_op_w_sgl, priv,
3540+
ctrl->lport->ops->fcprqst_priv_sz));
35413541
if (ret)
35423542
goto fail_ctrl;
35433543

drivers/scsi/hptiop.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1394,8 +1394,8 @@ static int hptiop_probe(struct pci_dev *pcidev, const struct pci_device_id *id)
13941394
host->cmd_per_lun = le32_to_cpu(iop_config.max_requests);
13951395
host->max_cmd_len = 16;
13961396

1397-
req_size = struct_size((struct hpt_iop_request_scsi_command *)0,
1398-
sg_list, hba->max_sg_descriptors);
1397+
req_size = struct_size_t(struct hpt_iop_request_scsi_command,
1398+
sg_list, hba->max_sg_descriptors);
13991399
if ((req_size & 0x1f) != 0)
14001400
req_size = (req_size + 0x1f) & ~0x1f;
14011401

drivers/scsi/megaraid/megaraid_sas_base.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5153,8 +5153,8 @@ static void megasas_update_ext_vd_details(struct megasas_instance *instance)
51535153
fusion->max_map_sz = ventura_map_sz;
51545154
} else {
51555155
fusion->old_map_sz =
5156-
struct_size((struct MR_FW_RAID_MAP *)0, ldSpanMap,
5157-
instance->fw_supported_vd_count);
5156+
struct_size_t(struct MR_FW_RAID_MAP, ldSpanMap,
5157+
instance->fw_supported_vd_count);
51585158
fusion->new_map_sz = sizeof(struct MR_FW_RAID_MAP_EXT);
51595159

51605160
fusion->max_map_sz =
@@ -5789,8 +5789,8 @@ megasas_setup_jbod_map(struct megasas_instance *instance)
57895789
struct fusion_context *fusion = instance->ctrl_context;
57905790
size_t pd_seq_map_sz;
57915791

5792-
pd_seq_map_sz = struct_size((struct MR_PD_CFG_SEQ_NUM_SYNC *)0, seq,
5793-
MAX_PHYSICAL_DEVICES);
5792+
pd_seq_map_sz = struct_size_t(struct MR_PD_CFG_SEQ_NUM_SYNC, seq,
5793+
MAX_PHYSICAL_DEVICES);
57945794

57955795
instance->use_seqnum_jbod_fp =
57965796
instance->support_seqnum_jbod_fp;
@@ -8033,8 +8033,8 @@ static void megasas_detach_one(struct pci_dev *pdev)
80338033
if (instance->adapter_type != MFI_SERIES) {
80348034
megasas_release_fusion(instance);
80358035
pd_seq_map_sz =
8036-
struct_size((struct MR_PD_CFG_SEQ_NUM_SYNC *)0,
8037-
seq, MAX_PHYSICAL_DEVICES);
8036+
struct_size_t(struct MR_PD_CFG_SEQ_NUM_SYNC,
8037+
seq, MAX_PHYSICAL_DEVICES);
80388038
for (i = 0; i < 2 ; i++) {
80398039
if (fusion->ld_map[i])
80408040
dma_free_coherent(&instance->pdev->dev,

drivers/scsi/megaraid/megaraid_sas_fp.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -326,9 +326,9 @@ u8 MR_ValidateMapInfo(struct megasas_instance *instance, u64 map_id)
326326
else if (instance->supportmax256vd)
327327
expected_size = sizeof(struct MR_FW_RAID_MAP_EXT);
328328
else
329-
expected_size = struct_size((struct MR_FW_RAID_MAP *)0,
330-
ldSpanMap,
331-
le16_to_cpu(pDrvRaidMap->ldCount));
329+
expected_size = struct_size_t(struct MR_FW_RAID_MAP,
330+
ldSpanMap,
331+
le16_to_cpu(pDrvRaidMap->ldCount));
332332

333333
if (le32_to_cpu(pDrvRaidMap->totalSize) != expected_size) {
334334
dev_dbg(&instance->pdev->dev, "megasas: map info structure size 0x%x",

drivers/scsi/smartpqi/smartpqi_init.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5015,7 +5015,7 @@ static int pqi_create_queues(struct pqi_ctrl_info *ctrl_info)
50155015
}
50165016

50175017
#define PQI_REPORT_EVENT_CONFIG_BUFFER_LENGTH \
5018-
struct_size((struct pqi_event_config *)0, descriptors, PQI_MAX_EVENT_DESCRIPTORS)
5018+
struct_size_t(struct pqi_event_config, descriptors, PQI_MAX_EVENT_DESCRIPTORS)
50195019

50205020
static int pqi_configure_events(struct pqi_ctrl_info *ctrl_info,
50215021
bool enable_events)

fs/xfs/libxfs/xfs_btree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ struct xfs_btree_cur
301301
static inline size_t
302302
xfs_btree_cur_sizeof(unsigned int nlevels)
303303
{
304-
return struct_size((struct xfs_btree_cur *)NULL, bc_levels, nlevels);
304+
return struct_size_t(struct xfs_btree_cur, bc_levels, nlevels);
305305
}
306306

307307
/* cursor flags */

fs/xfs/scrub/btree.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ struct xchk_btree {
6060
static inline size_t
6161
xchk_btree_sizeof(unsigned int nlevels)
6262
{
63-
return struct_size((struct xchk_btree *)NULL, lastkey, nlevels - 1);
63+
return struct_size_t(struct xchk_btree, lastkey, nlevels - 1);
6464
}
6565

6666
int xchk_btree(struct xfs_scrub *sc, struct xfs_btree_cur *cur,

include/linux/overflow.h

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
283283
* @member: Name of the array member.
284284
* @count: Number of elements in the array.
285285
*
286-
* Calculates size of memory needed for structure @p followed by an
286+
* Calculates size of memory needed for structure of @p followed by an
287287
* array of @count number of @member elements.
288288
*
289289
* Return: number of bytes needed or SIZE_MAX on overflow.
@@ -293,4 +293,20 @@ static inline size_t __must_check size_sub(size_t minuend, size_t subtrahend)
293293
sizeof(*(p)) + flex_array_size(p, member, count), \
294294
size_add(sizeof(*(p)), flex_array_size(p, member, count)))
295295

296+
/**
297+
* struct_size_t() - Calculate size of structure with trailing flexible array
298+
* @type: structure type name.
299+
* @member: Name of the array member.
300+
* @count: Number of elements in the array.
301+
*
302+
* Calculates size of memory needed for structure @type followed by an
303+
* array of @count number of @member elements. Prefer using struct_size()
304+
* when possible instead, to keep calculations associated with a specific
305+
* instance variable of type @type.
306+
*
307+
* Return: number of bytes needed or SIZE_MAX on overflow.
308+
*/
309+
#define struct_size_t(type, member, count) \
310+
struct_size((type *)NULL, member, count)
311+
296312
#endif /* __LINUX_OVERFLOW_H */

lib/overflow_kunit.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ struct __test_flex_array {
649649
static void overflow_size_helpers_test(struct kunit *test)
650650
{
651651
/* Make sure struct_size() can be used in a constant expression. */
652-
u8 ce_array[struct_size((struct __test_flex_array *)0, data, 55)];
652+
u8 ce_array[struct_size_t(struct __test_flex_array, data, 55)];
653653
struct __test_flex_array *obj;
654654
int count = 0;
655655
int var;

0 commit comments

Comments
 (0)