The run-time behaviour as seen in gdb ===================================== My comments are formatted as: "------------------------------------------ REETESH: ------------------------------------------" address@hidden any-fix]$ gdb bug GNU gdb 5.0 Copyright 2000 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) b DDecContentContent Breakpoint 1 at 0x80487b6: file any.c, line 66. (gdb) r Starting program: /home/reeteshr/learn/asn/snacc/any-fix/bug saved ptr: 0x804d348, *buf: 0x804d334, diff: 20, length: 20 Breakpoint 1, DDecContentContent (b=0x804cf38, tagId0=0, elmtLen0=0, v=0xbffff770, bytesDecoded=0xbffff780, env=0xbffff6d0) at any.c:66 66 int seqDone = FALSE; (gdb) s 67 AsnLen totalElmtsLen1 = 0; (gdb) n 70 int mandatoryElmtCount1 = 0; (gdb) 73 tagId1 = DDecTag (b, &totalElmtsLen1, env); (gdb) p *b $1 = 0x804d334 "\006\a|\002\005E\001" (gdb) n 75 if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, OID_TAG_CODE)))) (gdb) 77 elmtLen1 = DDecLen (b, &totalElmtsLen1, env); (gdb) p *b $2 = 0x804d335 "\a|\002\005E\001" (gdb) n 78 DDecAsnOidContent (b, tagId1, elmtLen1, (&v->type), &totalElmtsLen1, env); (gdb) p *b $3 = 0x804d336 "|\002\005E\001" (gdb) n 79 } ------------------------------------------------------------------- REETESH: So, by this time we have successfully decoded Content.type ------------------------------------------------------------------- (gdb) p *b $4 = 0x804d33d "\002\001[\002\001P\002\003Sô1" ------------------------------------------------------------------- REETESH: This is the encoding of Content.value ------------------------------------------------------------------- (gdb) p v->type $5 = {octetLen = 7, octs = 0x804c8e8 "|\002\005E\001"} (gdb) n 85 SetAnyTypeByOid ((&v->content), (&v->type)); (gdb) p v->content $6 = {ai = 0x804c7b4, value = 0x80483c4} (gdb) p v->type $7 = {octetLen = 7, octs = 0x804c8e8 "|\002\005E\001"} (gdb) n 86 DDecAsnAnyDefinedBy (b, (&v->content), &totalElmtsLen1, env); (gdb) p *(v->content->ai) $8 = {anyId = 0, oid = {octetLen = 7, octs = 0x804adc8 "|\002\005E\001"}, intId = 0, size = 12, Encode = 0x8048a0c , Decode = 0x8048ae0 , Free = 0x8048e18 , Print = 0x8048c98 } ------------------------------------------------------------------- REETESH: As you can see, the AnyInfo is correctly fetched for the DDecAsnAnyDefinedBy function to use in decoding the remaining string to PhoneNumber type. Now, let us step in the AsnAny decode function ------------------------------------------------------------------- (gdb) s BDecAsnAny (b=0x804cf38, result=0xbffff778, bytesDecoded=0xbffff690, env=0xbffff6d0) at mbuf/asn-any.c:219 219 if ((result->ai != NULL) && (result->ai->Decode != NULL)) (gdb) n 218 { (gdb) 219 if ((result->ai != NULL) && (result->ai->Decode != NULL)) (gdb) 221 result->value = (void*) Asn1Alloc (result->ai->size); (gdb) 222 result->ai->Decode (b, result->value, bytesDecoded, env); (gdb) p result->ai->Decode $9 = 0x8048ae0 (gdb) p b $10 = (char **) 0x804cf38 (gdb) p *b $11 = 0x804d33d "\002\001[\002\001P\002\003Sô1" (gdb) p result->value $12 = (void *) 0x804c8f0 (gdb) p bytesDecoded $13 = (AsnLen *) 0xbffff690 (gdb) p env $14 = (struct __jmp_buf_tag *) 0xbffff6d0 ----------------------------------------------------------------- REETESH : I have printed the values above for comparing them with the values of arguments taken by the actual decode function DDecPhoneNumberContent ----------------------------------------------------------------- (gdb) s DDecPhoneNumberContent (b=0x804cf38, tagId0=134531312, elmtLen0=3221223056, v=0xbffff6d0, bytesDecoded=0xc, env=0xd1b99df9) at any.c:184 184 int seqDone = FALSE; ----------------------------------------------------------------- REETESH: As you can see, 'b' has correctly been passed But, 'env' has been incorrectly passed as 'v' the values for 'bytesDecoded' and 'env' are coming probably from the stack of DDecPhoneNumberContent and they are dangerous to use ----------------------------------------------------------------- (gdb) p (0x804c8f0 == 134531312) $15 = 1 ----------------------------------------------------------------- REETESH: And, address 'result->value' has gone as number 'tagId0' ----------------------------------------------------------------- (gdb) p (0xbffff690 == 3221223056) $16 = 1 ----------------------------------------------------------------- REETESH: And, address 'bytesDecoded' has gone as number 'elmtLen0' ----------------------------------------------------------------- (gdb) n 185 AsnLen totalElmtsLen1 = 0; (gdb) 188 int mandatoryElmtCount1 = 0; (gdb) 191 tagId1 = DDecTag (b, &totalElmtsLen1, env); (gdb) 193 if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) (gdb) 195 elmtLen1 = DDecLen (b, &totalElmtsLen1, env); (gdb) 196 DDecAsnIntContent (b, tagId1, elmtLen1, (&v->country), &totalElmtsLen1, env); (gdb) 197 tagId1 = DDecTag (b, &totalElmtsLen1, env); (gdb) p v->country $17 = 91 ----------------------------------------------------------------- REETESH: Since, the decode succeeds and there is no read/write operation done with 'env' inside DDecTag, DDecAsnIntContent we have not got any problem so far... Had there been any access to 'env' it will lead to problems as it has an invalid address value (Look into main.c.1 for the values we have given to the Phone Number struct variable members to verify that decoding has been successful) ----------------------------------------------------------------- (gdb) n 198 } (gdb) 203 if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) (gdb) 205 elmtLen1 = DDecLen (b, &totalElmtsLen1, env); (gdb) 206 DDecAsnIntContent (b, tagId1, elmtLen1, (&v->area), &totalElmtsLen1, env); (gdb) 207 tagId1 = DDecTag (b, &totalElmtsLen1, env); (gdb) p v->area $18 = 80 ----------------------------------------------------------------- REETESH: Here also it has escaped the danger ----------------------------------------------------------------- (gdb) n 208 } (gdb) 213 if (((tagId1 == MAKE_TAG_ID (UNIV, PRIM, INTEGER_TAG_CODE)))) (gdb) 215 elmtLen1 = DDecLen (b, &totalElmtsLen1, env); (gdb) 216 DDecAsnIntContent (b, tagId1, elmtLen1, (&v->number), &totalElmtsLen1, env); (gdb) 217 seqDone = TRUE; (gdb) p v->number $19 = 5502001 ----------------------------------------------------------------- REETESH: and here too... ----------------------------------------------------------------- (gdb) n 218 if (elmtLen0 == INDEFINITE_LEN) (gdb) 220 else if (totalElmtsLen1 != elmtLen0) (gdb) 221 longjmp (env, -105); (gdb) Program received signal SIGSEGV, Segmentation fault. __libc_siglongjmp (env=0xd1b99df9, val=-105) at ../sysdeps/generic/longjmp.c:35 35 ../sysdeps/generic/longjmp.c: No such file or directory. ----------------------------------------------------------------- REETESH: But not here, ultimately It happened because 'elmtLen0' is not carrying a valid value and both checks fail, leading to longjmp call which uses 'env' which is carrying an invalid value, too. ----------------------------------------------------------------- (gdb)