Passing wrong size to memcpy/memset
Subsystems (7)
[This is a repost since I posted incorrectly the first time and I didn't get any response.]
Hi,
I'm with the Stanford Metacompilation research group and I wrote a checker that looks for places where people use 'sizeof(ptr)' instead of 'sizeof(*ptr)' as the length argument to memcpy/memset. The problem is that they are trying to copy an entire structure but end up only copying the first 4 bytes. I ran it on the 2.5.69 kernel and came up with 22 errors. These should be really easy to confirm and fix even though the bugs themselves could be really nasty.
I'm going to extend the checker in the next couple of days to account for other functions like memcpy and memset that take length arguments. In addition, I'll modify it to watch for the incorrect use of sizeof as a loop bound. If anyone has any other ideas, I'd appreciate hearing them.
As always, confirmation of these reports is appreciated.
Thanks!
Ken Ashcraft
# Total = 22
# BUGs | File Name
6 | /crypto/tcrypt.c 4 | /drivers/megaraid.c 2 | /crypto/deflate.c 2 | /net/nr_route.c 1 | /drivers/ohci1394.c 1 | /pci/emufx.c 1 | /crypto/md5.c 1 | /hardware/maintidi.c 1 | /fs/md5.c 1 | /net/sdla_chdlc.c 1 | /crypto/md4.c 1 | /net/airo.c
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/deflate.c:111:deflate_decomp_in
it: ERROR:SIZEOF:111:111:passing wrong size to 'memset'
deflate_gfp());
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
Error --->memset(stream->workspace, 0, sizeof(stream->workspace));
ret = zlib_inflateInit2(stream, -DEFLATE_DEF_WINBITS);
if (ret != Z_OK) {
ret = -EINVAL;
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/deflate.c:84:deflate_comp_init:
ERROR:SIZEOF:84:84:passing wrong size to 'memset'
PAGE_KERNEL);
if (!stream->workspace ) {
ret = -ENOMEM;
goto out;
}
Error --->memset(stream->workspace, 0, sizeof(stream->workspace)); ret = zlib_deflateInit2(stream, DEFLATE_DEF_LEVEL, Z_DEFLATED,
-DEFLATE_DEF_WINBITS, DEFLATE_DEF_MEMLEVEL,
Z_DEFAULT_STRATEGY);---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/md4.c:218:md4_final:
ERROR:SIZEOF:218:218:passing wrong size to 'memset' le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
sizeof(u64)) / sizeof(u32));
md4_transform(mctx->hash, mctx->block); cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); memcpy(out, mctx->hash, sizeof(mctx->hash));
Error --->memset(mctx, 0, sizeof(mctx));
}
static struct crypto_alg alg = {
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/md5.c:213:md5_final:
ERROR:SIZEOF:213:213:passing wrong size to 'memset' le32_to_cpu_array(mctx->block, (sizeof(mctx->block) -
sizeof(u64)) / sizeof(u32));
md5_transform(mctx->hash, mctx->block); cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(u32)); memcpy(out, mctx->hash, sizeof(mctx->hash));
Error --->memset(mctx, 0, sizeof(mctx));
}
static struct crypto_alg alg = {
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:1030:test_des:
ERROR:SIZEOF:1030:1030:passing wrong size to 'memset'
printk("setkey() failed flags=%x\n", tfm->crt_flags); goto out;
}
/* setup the dummy buffer first */
Error --->memset(xbuf, 0, sizeof (xbuf));
xbuf[IDX1] = des_tv[i].plaintext[0];
xbuf[IDX2] = des_tv[i].plaintext[1];
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:116:test_md5:
ERROR:SIZEOF:116:116:passing wrong size to 'memset'
}
printk("\ntesting md5 across pages\n");
/* setup the dummy buffer first */
Error --->memset(xbuf, 0, sizeof (xbuf));memcpy(&xbuf[IDX1], "abcdefghijklm", 13);memcpy(&xbuf[IDX2], "nopqrstuvwxyz", 13);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:191:test_hmac_md5:
ERROR:SIZEOF:191:191:passing wrong size to 'memset'
"pass"); }
printk("\ntesting hmac_md5 across pages\n");
Error --->memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], "what do ya want ", 16); memcpy(&xbuf[IDX2], "for nothing?", 12);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:270:test_hmac_sha1:
ERROR:SIZEOF:270:270:passing wrong size to 'memset'
}
printk("\ntesting hmac_sha1 across pages\n");
/* setup the dummy buffer first */
Error --->memset(xbuf, 0, sizeof (xbuf));
memcpy(&xbuf[IDX1], "what do ya want ", 16); memcpy(&xbuf[IDX2], "for nothing?", 12);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:453:test_sha1:
ERROR:SIZEOF:453:453:passing wrong size to 'memset'
}
printk("\ntesting sha1 across pages\n");
/* setup the dummy buffer first */
Error --->memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/crypto/tcrypt.c:528:test_sha256:
ERROR:SIZEOF:528:528:passing wrong size to 'memset'
}
printk("\ntesting sha256 across pages\n");
/* setup the dummy buffer first */
Error --->memset(xbuf, 0, sizeof (xbuf)); memcpy(&xbuf[IDX1], "abcdbcdecdefdefgefghfghighij", 28); memcpy(&xbuf[IDX2], "hijkijkljklmklmnlmnomnopnopq", 28);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/ieee1394/ohci1394.c:3168:ohci_init_config_rom: ERROR:SIZEOF:3168:3168:passing wrong size to 'memset' static void ohci_init_config_rom(struct ti_ohci *ohci)
{
struct config_rom_ptr cr;
memset(&cr, 0, sizeof(cr));
Error --->memset(ohci->csr_config_rom_cpu, 0, sizeof (ohci->csr_config_rom_cpu));
cr.data = ohci->csr_config_rom_cpu;
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/isdn/hardware/eicon/maintidi.c :119:DivaSTraceLibraryCreateInstance: ERROR:SIZEOF:119:119:passing wrong size to 'memset'
if (!pLib) {
return (0);
}
pmem += sizeof(*pLib);
Error --->
memset (pLib, 0x00, sizeof(pLib));
pLib->Adapter = Adapter;
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/net/wan/sdla_chdlc.c:1072:disable_comm: ERROR:SIZEOF:1072:1072:passing wrong size to 'memset'
card->devname,WAN_TTY_MAJOR);
}
card->tty=NULL;
tty_card_map[card->tty_minor]=NULL;
state = &rs_table[card->tty_minor];
Error --->
memset(state,0,sizeof(state));
}
return;
}
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/net/wireless/airo.c:4841:airo_get_range: ERROR:SIZEOF:4841:4841:passing wrong size to 'memset' int k;
readCapabilityRid(local, &cap_rid);
dwrq->length = sizeof(struct iw_range);
Error --->memset(range, 0, sizeof(range));range->min_nwid = 0x0000;range->max_nwid = 0x0000;range->num_channels = 14;
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/scsi/megaraid.c:4667:mega_is_bios_enabled: ERROR:SIZEOF:4667:4667:passing wrong size to 'memset' mbox_t *mbox;
int ret;
mbox = (mbox_t *)raw_mbox;
Error --->memset(mbox, 0, sizeof(mbox));
memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/scsi/megaraid.c:4700:mega_enum _raid_scsi: ERROR:SIZEOF:4700:4700:passing wrong size to 'memset' mbox_t *mbox;
int i;
mbox = (mbox_t *)raw_mbox;
Error --->memset(mbox, 0, sizeof(mbox));
/*
* issue command to find out what channels are raid/scsi
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/scsi/megaraid.c:4821:mega_support_random_del: ERROR:SIZEOF:4821:4821:passing wrong size to 'memset' mbox_t *mbox;
int rval;
mbox = (mbox_t *)raw_mbox;
Error --->memset(mbox, 0, sizeof(mbox));
/*
* issue command
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/drivers/scsi/megaraid.c:4850:mega_support_ext_cdb: ERROR:SIZEOF:4850:4850:passing wrong size to 'memset' mbox_t *mbox;
int rval;
mbox = (mbox_t *)raw_mbox;
Error --->memset(mbox, 0, sizeof (mbox));
/*
* issue command to find out if controller supports extended CDBs. */
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/fs/cifs/md5.c:151:MD5Final:
ERROR:SIZEOF:151:151:passing wrong size to 'memset' ((__u32 *) ctx->in)[15] = ctx->bits[1];
MD5Transform(ctx->buf, (__u32 *) ctx->in);byteReverse((unsigned char *) ctx->buf, 4);memmove(digest, ctx->buf, 16);
Error --->memset(ctx, 0, sizeof (ctx)); /* In case it's sensitive */ }
/* The four core functions - F1 is optimized somewhat */
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/net/netrom/nr_route.c:113:nr_add_node:
ERROR:SIZEOF:113:113:passing wrong size to 'memcpy'
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) ==
NULL) {
kfree(nr_neigh);
return -ENOMEM;
}
Error --->
memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
}
spin_lock_bh(&nr_neigh_lock);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/net/netrom/nr_route.c:390:nr_add_neigh : ERROR:SIZEOF:390:390:passing wrong size to 'memcpy'
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
if ((nr_neigh->digipeat = kmalloc(sizeof(*ax25_digi), GFP_KERNEL)) ==
NULL) {
kfree(nr_neigh);
return -ENOMEM;
}
Error --->
memcpy(nr_neigh->digipeat, ax25_digi, sizeof(ax25_digi));
}
spin_lock_bh(&nr_neigh_lock);
---------------------------------------------------------
[BUG] /dryer/engler/kash/linux/linux-2.5.69/sound/pci/emu10k1/emufx.c:2209:snd_emu 10k1_fx8010_info: ERROR:SIZEOF:2209:2209:passing wrong size to 'memset' {
char **fxbus, **extin, **extout;
unsigned short fxbus_mask, extin_mask, extout_mask;
int res;
Error --->memset(info, 0, sizeof(info));info->card = emu->card_type; info->internal_tram_size = emu->fx8010.itram_size; info->external_tram_size = emu->fx8010.etram_size;
Quoted 4 lines · Ken Ashcraft
I'm with the Stanford Metacompilation research group and I wrote a checker that looks for places where people use 'sizeof(ptr)' instead of '
sizeof(*ptr)' as the length argument to memcpy/memset.
Well they all look like genuine bugs. It could be that some code is just performing overly-paranoid memsets.
I shall submit the below lot unless squeaked at.
25-akpm/crypto/deflate.c | 4 ++-- 25-akpm/crypto/md4.c | 2 +- 25-akpm/crypto/md5.c | 2 +- 25-akpm/crypto/tcrypt.c | 12 ++++++------ 25-akpm/drivers/ieee1394/ohci1394.c | 2 +- 25-akpm/drivers/isdn/hardware/eicon/maintidi.c | 2 +- 25-akpm/drivers/net/wan/sdla_chdlc.c | 2 +- 25-akpm/drivers/net/wireless/airo.c | 2 +- 25-akpm/drivers/scsi/megaraid.c | 8 ++++---- 25-akpm/fs/cifs/md5.c | 2 +- 25-akpm/net/netrom/nr_route.c | 5 +++-- 25-akpm/sound/pci/emu10k1/emufx.c | 2 +- 12 files changed, 23 insertions(+), 22 deletions(-)
crypto/deflate.c renamed from crypto/deflate.c~stanford-memcy-size-fixes +2 -2
@@ -81,7 +81,7 @@ static int deflate_comp_init(struct defl ret = -ENOMEM ; goto out; } -memset (stream->workspace,0 ,sizeof (stream->workspace)); +memset (stream->workspace,0 ,sizeof (*stream->workspace)); ret =zlib_deflateInit2 (stream,DEFLATE_DEF_LEVEL ,Z_DEFLATED , -DEFLATE_DEF_WINBITS ,DEFLATE_DEF_MEMLEVEL ,Z_DEFAULT_STRATEGY );
@@ -108,7 +108,7 @@ static int deflate_decomp_init(struct de ret = -ENOMEM ; goto out; } -memset (stream->workspace,0 ,sizeof (stream->workspace)); +memset (stream->workspace,0 ,sizeof (*stream->workspace)); ret =zlib_inflateInit2 (stream, -DEFLATE_DEF_WINBITS );if (ret !=Z_OK ) { ret = -EINVAL ;
crypto/md4.c renamed from crypto/md4.c~stanford-memcy-size-fixes +1 -1
@@ -215,7 +215,7 @@ static void md4_final(void *ctx, u8 *outmd4_transform (mctx->hash, mctx->block);cpu_to_le32_array (mctx->hash,sizeof (mctx->hash) /sizeof (u32));memcpy (out, mctx->hash,sizeof (mctx->hash)); -memset (mctx,0 ,sizeof (mctx)); +memset (mctx,0 ,sizeof (*mctx)); }static struct crypto_alg alg = {
crypto/md5.c renamed from crypto/md5.c~stanford-memcy-size-fixes +1 -1
@@ -210,7 +210,7 @@ static void md5_final(void *ctx, u8 *outmd5_transform (mctx->hash, mctx->block);cpu_to_le32_array (mctx->hash,sizeof (mctx->hash) /sizeof (u32));memcpy (out, mctx->hash,sizeof (mctx->hash)); -memset (mctx,0 ,sizeof (mctx)); +memset (mctx,0 ,sizeof (*mctx)); }static struct crypto_alg alg = {
crypto/tcrypt.c renamed from crypto/tcrypt.c~stanford-memcy-size-fixes +6 -6
@@ -113,7 +113,7 @@ test_md5(void)printk ("\ntesting md5 across pages\n" );/* setup the dummy buffer first */ -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf));memcpy (&xbuf[IDX1 ],"abcdefghijklm" ,13 );memcpy (&xbuf[IDX2 ],"nopqrstuvwxyz" ,13 );
@@ -188,7 +188,7 @@ test_hmac_md5(void)printk ("\ntesting hmac_md5 across pages\n" ); -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf));memcpy (&xbuf[IDX1 ],"what do ya want " ,16 );memcpy (&xbuf[IDX2 ],"for nothing?" ,12 );
@@ -267,7 +267,7 @@ test_hmac_sha1(void)printk ("\ntesting hmac_sha1 across pages\n" );/* setup the dummy buffer first */ -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf));memcpy (&xbuf[IDX1 ],"what do ya want " ,16 );memcpy (&xbuf[IDX2 ],"for nothing?" ,12 );
@@ -450,7 +450,7 @@ test_sha1(void)printk ("\ntesting sha1 across pages\n" );/* setup the dummy buffer first */ -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf));memcpy (&xbuf[IDX1 ],"abcdbcdecdefdefgefghfghighij" ,28 );memcpy (&xbuf[IDX2 ],"hijkijkljklmklmnlmnomnopnopq" ,28 );
@@ -525,7 +525,7 @@ test_sha256(void)printk ("\ntesting sha256 across pages\n" );/* setup the dummy buffer first */ -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf));memcpy (&xbuf[IDX1 ],"abcdbcdecdefdefgefghfghighij" ,28 );memcpy (&xbuf[IDX2 ],"hijkijkljklmklmnlmnomnopnopq" ,28 );
@@ -1027,7 +1027,7 @@ test_des(void) }/* setup the dummy buffer first */ -memset (xbuf,0 ,sizeof (xbuf)); +memset (xbuf,0 ,sizeof (*xbuf)); xbuf[IDX1 ] = des_tv[i].plaintext[0 ]; xbuf[IDX2 ] = des_tv[i].plaintext[1 ];
drivers/ieee1394/ohci1394.c renamed from drivers/ieee1394/ohci1394.c~stanford-memcy-size-fixes +1 -1
@@ -3165,7 +3165,7 @@ static void ohci_init_config_rom(structstruct config_rom_ptr cr;memset (&cr,0 ,sizeof (cr)); -memset (ohci->csr_config_rom_cpu,0 ,sizeof (ohci->csr_config_rom_cpu)); +memset (ohci->csr_config_rom_cpu,0 ,sizeof (*ohci->csr_config_rom_cpu)); cr.data = ohci->csr_config_rom_cpu;
drivers/isdn/hardware/eicon/maintidi.c renamed from drivers/isdn/hardware/eicon/maintidi.c~stanford-memcy-size-fixes +1 -1
@@ -116,7 +116,7 @@ diva_strace_library_interface_t* DivaSTr } pmem +=sizeof (*pLib); -memset (pLib,0x00 ,sizeof (pLib)); +memset (pLib,0x00 ,sizeof (*pLib)); pLib->Adapter = Adapter;
drivers/net/wan/sdla_chdlc.c renamed from drivers/net/wan/sdla_chdlc.c~stanford-memcy-size-fixes +1 -1
@@ -1069,7 +1069,7 @@ static void disable_comm (sdla_t *card) card->tty=NULL ; tty_card_map[card->tty_minor]=NULL ; state = &rs_table[card->tty_minor]; -memset (state,0 ,sizeof (state)); +memset (state,0 ,sizeof (*state)); }return ; }
drivers/net/wireless/airo.c renamed from drivers/net/wireless/airo.c~stanford-memcy-size-fixes +1 -1
@@ -4845,7 +4845,7 @@ static int airo_get_range(struct net_devreadCapabilityRid (local, &cap_rid); dwrq->length =sizeof (struct iw_range ); -memset (range,0 ,sizeof (range)); +memset (range,0 ,sizeof (*range)); range->min_nwid =0x0000 ; range->max_nwid =0x0000 ; range->num_channels =14 ;
drivers/scsi/megaraid.c renamed from drivers/scsi/megaraid.c~stanford-memcy-size-fixes +4 -4
@@ -4664,7 +4664,7 @@ mega_is_bios_enabled(adapter_t *adapter) mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (mbox)); +memset (mbox,0 ,sizeof (*mbox));memset ((void *)adapter->mega_buffer,0 ,MEGA_BUFFER_SIZE );
@@ -4697,7 +4697,7 @@ mega_enum_raid_scsi(adapter_t *adapter) mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (mbox)); +memset (mbox,0 ,sizeof (*mbox));/* * issue command to find out what channels are raid/scsi
@@ -4818,7 +4818,7 @@ mega_support_random_del(adapter_t *adapt mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (mbox)); +memset (mbox,0 ,sizeof (*mbox));/* * issue command
@@ -4847,7 +4847,7 @@ mega_support_ext_cdb(adapter_t *adapter) mbox = (mbox_t *)raw_mbox; -memset (mbox,0 ,sizeof (mbox)); +memset (mbox,0 ,sizeof (*mbox));/* * issue command to find out if controller supports extended CDBs. */
fs/cifs/md5.c renamed from fs/cifs/md5.c~stanford-memcy-size-fixes +1 -1
@@ -148,7 +148,7 @@ MD5Final(unsigned char digest[16], strucMD5Transform (ctx->buf, (__u32 *) ctx->in);byteReverse ((unsigned char *) ctx->buf,4 );memmove (digest, ctx->buf,16 ); -memset (ctx,0 ,sizeof (ctx));/* In case it's sensitive */ +memset (ctx,0 ,sizeof (*ctx));/* In case it's sensitive */ }/* The four core functions - F1 is optimized somewhat */
net/netrom/nr_route.c renamed from net/netrom/nr_route.c~stanford-memcy-size-fixes +3 -2
@@ -110,7 +110,8 @@ static int nr_add_node(ax25_address *nr,kfree (nr_neigh);return -ENOMEM ; } -memcpy (nr_neigh->digipeat, ax25_digi,sizeof (ax25_digi)); +memcpy (nr_neigh->digipeat, ax25_digi, +sizeof (*ax25_digi)); }spin_lock_bh (&nr_neigh_lock);
@@ -387,7 +388,7 @@ static int nr_add_neigh(ax25_address *cakfree (nr_neigh);return -ENOMEM ; } -memcpy (nr_neigh->digipeat, ax25_digi,sizeof (ax25_digi)); +memcpy (nr_neigh->digipeat, ax25_digi,sizeof (*ax25_digi)); }spin_lock_bh (&nr_neigh_lock);
sound/pci/emu10k1/emufx.c renamed from sound/pci/emu10k1/emufx.c~stanford-memcy-size-fixes +1 -1
@@ -2206,7 +2206,7 @@ static int snd_emu10k1_fx8010_info(emu10unsigned short fxbus_mask, extin_mask, extout_mask;int res; -memset (info,0 ,sizeof (info)); +memset (info,0 ,sizeof (*info)); info->card = emu->card_type; info->internal_tram_size = emu->fx8010.itram_size; info->external_tram_size = emu->fx8010.etram_size;
_
Quoted 10 lines · Andrew Morton
Quoted 4 lines · Ken Ashcraft
I'm with the Stanford Metacompilation research group and I wrote a checker that looks for places where people use 'sizeof(ptr)' instead of '
sizeof(*ptr)' as the length argument to memcpy/memset.Well they all look like genuine bugs. It could be that some code is just performing overly-paranoid memsets.
I shall submit the below lot unless squeaked at.
No squeaks from me.
Ken, would you please try and Cc: maintainers for future reports?
- James
Signature · 2 lines
James Morris <[email protected]>