drivers/staging/wlan-ng/prism2fw.c:625 mkpdrlist() error: __builtin_memcpy() '&pda->rec[pda->nrec]->data.mfisuprange' too small (8 vs 10)

From: Dan Carpenter
Date: Mon Jan 22 2024 - 03:13:19 EST


tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git master
head: 9d64bf433c53cab2f48a3fff7a1f2a696bc5229a
commit: 049e40ef203ebdf530cb37a3f5f7752d0c07b288 staging: wlan-ng: Remove unused code
config: x86_64-randconfig-161-20240120 (https://download.01.org/0day-ci/archive/20240120/202401202022.g64TD42E-lkp@xxxxxxxxx/config)
compiler: ClangBuiltLinux clang version 17.0.6 (https://github.com/llvm/llvm-project 6009708b4367171ccdbf4b5905cb6a803753fe18)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@xxxxxxxxx>
| Reported-by: Dan Carpenter <dan.carpenter@xxxxxxxxxx>
| Closes: https://lore.kernel.org/r/202401202022.g64TD42E-lkp@xxxxxxxxx/

New smatch warnings:
drivers/staging/wlan-ng/prism2fw.c:625 mkpdrlist() error: __builtin_memcpy() '&pda->rec[pda->nrec]->data.mfisuprange' too small (8 vs 10)
drivers/staging/wlan-ng/prism2fw.c:634 mkpdrlist() error: __builtin_memcpy() '&pda->rec[pda->nrec]->data.cfisuprange' too small (8 vs 10)

Old smatch warnings:
drivers/staging/wlan-ng/prism2fw.c:951 read_fwfile() error: buffer overflow 'tmpinfo' 4 <= 4

vim +625 drivers/staging/wlan-ng/prism2fw.c

ae24e13a6485a6 Devendra Naga 2012-09-09 603 static int mkpdrlist(struct pda *pda)
76e3e7c4095237 Karl Relton 2009-04-17 604 {
76b4580bf4eaf1 Maciek Borzecki 2017-04-08 605 __le16 *pda16 = (__le16 *)pda->buf;
76e3e7c4095237 Karl Relton 2009-04-17 606 int curroff; /* in 'words' */
76e3e7c4095237 Karl Relton 2009-04-17 607
76e3e7c4095237 Karl Relton 2009-04-17 608 pda->nrec = 0;
76e3e7c4095237 Karl Relton 2009-04-17 609 curroff = 0;
4ccb726c728cb4 Tillmann Heidsieck 2015-09-23 610 while (curroff < (HFA384x_PDA_LEN_MAX / 2 - 1) &&
75f49e07520d03 Mithlesh Thukral 2009-05-25 611 le16_to_cpu(pda16[curroff + 1]) != HFA384x_PDR_END_OF_PDA) {
b586fbd3968a32 Sergio Paracuellos 2016-11-07 612 pda->rec[pda->nrec] = (struct hfa384x_pdrec *)&pda16[curroff];
76e3e7c4095237 Karl Relton 2009-04-17 613
cf66823dd22429 Devendra Naga 2012-06-06 614 if (le16_to_cpu(pda->rec[pda->nrec]->code) ==
cf66823dd22429 Devendra Naga 2012-06-06 615 HFA384x_PDR_NICID) {
76e3e7c4095237 Karl Relton 2009-04-17 616 memcpy(&nicid, &pda->rec[pda->nrec]->data.nicid,
76e3e7c4095237 Karl Relton 2009-04-17 617 sizeof(nicid));
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 618 le16_to_cpus(&nicid.id);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 619 le16_to_cpus(&nicid.variant);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 620 le16_to_cpus(&nicid.major);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 621 le16_to_cpus(&nicid.minor);
76e3e7c4095237 Karl Relton 2009-04-17 622 }
76e3e7c4095237 Karl Relton 2009-04-17 623 if (le16_to_cpu(pda->rec[pda->nrec]->code) ==
76e3e7c4095237 Karl Relton 2009-04-17 624 HFA384x_PDR_MFISUPRANGE) {
76e3e7c4095237 Karl Relton 2009-04-17 @625 memcpy(&rfid, &pda->rec[pda->nrec]->data.mfisuprange,
76e3e7c4095237 Karl Relton 2009-04-17 626 sizeof(rfid));

So &pda->rec[pda->nrec]->data is a union which used to hold a bunch of
different types in it. At least two of those types was 60 bytes long.
So when we removed it, then the total size of pda->rec[pda->nrec]->data
became 8 bytes and it triggers a read overflow warning in Smatch.

Here is who ->data is defined now.

drivers/staging/wlan-ng/hfa384x.h
886 struct hfa384x_pdr_mfisuprange {
887 u16 id;
888 u16 variant;
889 u16 bottom;
890 u16 top;
891 } __packed;
892
893 struct hfa384x_pdr_cfisuprange {
894 u16 id;
895 u16 variant;
896 u16 bottom;
897 u16 top;
898 } __packed;
899
900 struct hfa384x_pdr_nicid {
901 u16 id;
902 u16 variant;
903 u16 major;
904 u16 minor;
905 } __packed;
906
907 struct hfa384x_pdrec {
908 __le16 len; /* in words */
909 __le16 code;
910 union pdr {
911 struct hfa384x_pdr_mfisuprange mfisuprange;
912 struct hfa384x_pdr_cfisuprange cfisuprange;
913 struct hfa384x_pdr_nicid nicid;
914
915 } data;
916 } __packed;

And here is how rfid is defined.

359 struct hfa384x_caplevel {
360 u16 role;
361 u16 id;
362 u16 variant;
363 u16 bottom;
364 u16 top;
365 } __packed;

Obviously it doesn't match. So probably the code works, but obviously
something is defined incorrectly.

b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 627 le16_to_cpus(&rfid.id);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 628 le16_to_cpus(&rfid.variant);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 629 le16_to_cpus(&rfid.bottom);
b1bb2e33ae1fa9 Thibaut SAUTEREAU 2017-05-12 630 le16_to_cpus(&rfid.top);
76e3e7c4095237 Karl Relton 2009-04-17 631 }
76e3e7c4095237 Karl Relton 2009-04-17 632 if (le16_to_cpu(pda->rec[pda->nrec]->code) ==
76e3e7c4095237 Karl Relton 2009-04-17 633 HFA384x_PDR_CFISUPRANGE) {
76e3e7c4095237 Karl Relton 2009-04-17 @634 memcpy(&macid, &pda->rec[pda->nrec]->data.cfisuprange,
76e3e7c4095237 Karl Relton 2009-04-17 635 sizeof(macid));

Same thing here.

KTODO: Silence Smatch warning in mkpdrlist()

regards,
dan carpenter

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki