Re: Data corruption - [EMAIL PROTECTED] on VMS.

2005-07-30 Thread Nicholas Clark
On Sat, Jul 30, 2005 at 12:27:43AM -0400, John E. Malmberg wrote:

 The address 10439704 was already a part of the structure that 
 Perl_hv_iternext_flags() had pointed a variable named iter at.
 
 DBG exam *iter
 *HV\Perl_hv_iternext_flags\iter
 xhv_name:   1162633044
 xhv_eiter:  4998486
 xhv_riter:  -256
 DBG eval/addr iter-xhv_riter
 10439704
 
 It appears to me that one of these structures was not allocated large 
 enough for the data that is being put in it.  As the xpvhv_aux structure 
 is a fixed size structure, my suspicion is that the problem is the above 
 code somewhere since this is where the HEK struct is allocated just 
 before *iter got corrupted.

However the xpvhv_aux structure is allocated by extending the HV's array
of linked list heads, and using space after it. So there is the possibility
that there is a code path where the extending realloc() didn't take place,
and the memory is being used out-of-bounds.

What is the value of sv_flags in the hash?
(struct hv, defined in sv.h, typdef'd to HV)

Specifically is bit 0x0020 set? It should be, where xpvhv_aux is in use
(See the comment near SVf_OOK in sv.h)


I'm about to set off to the US for OSCON, so I'm unlikely to be in a position
to read mail, let alone respond to it, for over 24 hours. (travel + sleep)

Nicholas Clark


Re: Data corruption - [EMAIL PROTECTED] on VMS.

2005-07-30 Thread John E. Malmberg

Nicholas Clark wrote:

On Sat, Jul 30, 2005 at 12:27:43AM -0400, John E. Malmberg wrote:


The address 10439704 was already a part of the structure that 
Perl_hv_iternext_flags() had pointed a variable named iter at.


DBG exam *iter
*HV\Perl_hv_iternext_flags\iter
   xhv_name:   1162633044
   xhv_eiter:  4998486
   xhv_riter:  -256
DBG eval/addr iter-xhv_riter
10439704

It appears to me that one of these structures was not allocated large 
enough for the data that is being put in it.  As the xpvhv_aux structure 
is a fixed size structure, my suspicion is that the problem is the above 
code somewhere since this is where the HEK struct is allocated just 
before *iter got corrupted.


However the xpvhv_aux structure is allocated by extending the HV's array
of linked list heads, and using space after it. So there is the possibility
that there is a code path where the extending realloc() didn't take place,
and the memory is being used out-of-bounds.

What is the value of sv_flags in the hash?
(struct hv, defined in sv.h, typdef'd to HV)


DBG exam/hex *hv
*HV\Perl_hv_iternext_flags\hv
sv_any: 0097721C
sv_refcnt:  0001
sv_flags:   2020C00C
sv_u
[Displaying union member number 1]
svu_iv: 009D33D8
DBG


Specifically is bit 0x0020 set? It should be, where xpvhv_aux is in use
(See the comment near SVf_OOK in sv.h)


The bit is set.  Of course I am looking after a state where I know that 
data corruption has taken place, so I will need start over and look again.



I'm about to set off to the US for OSCON, so I'm unlikely to be in a position
to read mail, let alone respond to it, for over 24 hours. (travel + sleep)


Ok,

So what I need to look at in the mean time is how and where the 
xpvhv_aux structure gets allocated.  Looking for that bit being set is 
probably my best clue.


From what I can see, if the name for the environment variable being 
stored in the hash had been 1 byte less in length, this data corruption 
may be invisible.


Right now my reproducer is test 16 of script t/run/switches.t which 
spawns the VMS command:


$ MCR EAGLE$DQA0:[PROJECT_ROOT.perl-blead.][00]DBGPERL.EXE;1 -
 -I../lib -V

Other spawned Perl commands succeed, so I do not know what is different 
here.


-John
[EMAIL PROTECTED]
Personal Opinion Only


Data corruption - [EMAIL PROTECTED] on VMS.

2005-07-29 Thread John E. Malmberg
In the code path below, the execution of the HEK_FLAGS(hek) causes the 
memory for a different allocated structure to be modified, which then 
causes an access violation when the corrupted value is used as an index.


This is in the module HV, routine S_share_hek_flags().

len has a value if 19 in this case.

Newx(k, STRUCT_OFFSET(struct shared_he,
 shared_he_hek.hek_key[0]) + len + 2, char);
new_entry = (struct shared_he *)k;
entry = (new_entry-shared_he_he);
hek = (new_entry-shared_he_hek);

Copy(str, HEK_KEY(hek), len, char);
HEK_KEY(hek)[len] = 0;
HEK_LEN(hek) = len;
HEK_HASH(hek) = hash;
HEK_FLAGS(hek) = (unsigned char)flags_masked;

HEK_FLAGS(hek) expands to:
   (*((unsigned char *)(hek)-hek_key)+(hek)-hek_len+1))

DBG eval/addr hek-hek_key
10439684
DBG eval 10439684+20
10439704

The address 10439704 was already a part of the structure that 
Perl_hv_iternext_flags() had pointed a variable named iter at.


DBG exam *iter
*HV\Perl_hv_iternext_flags\iter
xhv_name:   1162633044
xhv_eiter:  4998486
xhv_riter:  -256
DBG eval/addr iter-xhv_riter
10439704

It appears to me that one of these structures was not allocated large 
enough for the data that is being put in it.  As the xpvhv_aux structure 
is a fixed size structure, my suspicion is that the problem is the above 
code somewhere since this is where the HEK struct is allocated just 
before *iter got corrupted.


Prior to the corruption, iter-xhv_riter had -1.

The value that was being processed at this time is:

DBG exam/az *str
*HV\S_share_hek_flags\str:  PERL_DESTRUCT_LEVEL = 2

-John
[EMAIL PROTECTED]
Personal Opinion Only