Tcl Source Code

Check-in [bd7d7a2061]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Insure that PURIFY builds cannot exploit the Tcl stack to hide mem defects.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: bd7d7a206120b919f00a02a0bab49cb67a9beee3
User & Date: mig 2013-01-04 05:26:40
Context
2013-01-04
11:14
Improve code generation for many simple core ensemble subcommands. check-in: 5a0e18f766 user: dkf tags: trunk
06:54
merges check-in: 01331c9a5a user: mig tags: mig-strip-brutal
05:35
empty merge with trunc: sync, last patch does not apply to this branch. Temp work committed, not deb... check-in: 467a159cd0 user: mig tags: mig-alloc-reform
05:26
Insure that PURIFY builds cannot exploit the Tcl stack to hide mem defects. check-in: bd7d7a2061 user: mig tags: trunk
2013-01-03
14:35
"Mine eyes deceive, but others catch me when I fall." -- Someone or other check-in: 606dc91401 user: dkf tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to ChangeLog.






1
2
3
4
5
6
7





2013-01-03  Donal K. Fellows  <[email protected]>

	* doc/fconfigure.n, doc/CrtChannel.3: Updated to reflect the fact that
	the minimum buffer size is one byte, not ten. Identified by Schelte
	Bron on the Tcler's Chat.

	* generic/tclExecute.c (TEBCresume:INST_INVOKE_REPLACE):
>
>
>
>
>







1
2
3
4
5
6
7
8
9
10
11
12
2013-01-04  Miguel Sofer  <[email protected]>

	* generic/tclInt.h:      Insure that PURIFY builds cannot exploit the
	* generic/tclExecute.c:  Tcl stack to hide mem defects.

2013-01-03  Donal K. Fellows  <[email protected]>

	* doc/fconfigure.n, doc/CrtChannel.3: Updated to reflect the fact that
	the minimum buffer size is one byte, not ten. Identified by Schelte
	Bron on the Tcler's Chat.

	* generic/tclExecute.c (TEBCresume:INST_INVOKE_REPLACE):

Changes to generic/tclExecute.c.

1044
1045
1046
1047
1048
1049
1050

1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066

1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079

1080
1081
1082
1083
1084
1085
1086
	if (!markerPtr) {
	    Tcl_Panic("STACK: Reallocating with no previous alloc");
	}
	if (needed <= 0) {
	    return MEMSTART(markerPtr);
	}
    } else {

	Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
	int offset = OFFSET(tmpMarkerPtr);

	if (needed + offset < 0) {
	    /*
	     * Put a marker pointing to the previous marker in this stack, and
	     * store it in esPtr as the current marker. Return a pointer to
	     * the start of aligned memory.
	     */

	    esPtr->markerPtr = tmpMarkerPtr;
	    memStart = tmpMarkerPtr + offset;
	    esPtr->tosPtr = memStart - 1;
	    *esPtr->markerPtr = (Tcl_Obj *) markerPtr;
	    return memStart;
	}

    }

    /*
     * Reset move to hold the number of words to be moved to new stack (if
     * any) and growth to hold the complete stack requirements: add one for
     * the marker, (WALLOCALIGN-1) for the maximal possible offset.
     */

    if (move) {
	moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1;
    }
    needed = growth + moveWords + WALLOCALIGN;


    /*
     * Check if there is enough room in the next stack (if there is one, it
     * should be both empty and the last one!)
     */

    if (esPtr->nextPtr) {
	oldPtr = esPtr;







>
















>











|

>







1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
	if (!markerPtr) {
	    Tcl_Panic("STACK: Reallocating with no previous alloc");
	}
	if (needed <= 0) {
	    return MEMSTART(markerPtr);
	}
    } else {
#ifndef PURIFY
	Tcl_Obj **tmpMarkerPtr = esPtr->tosPtr + 1;
	int offset = OFFSET(tmpMarkerPtr);

	if (needed + offset < 0) {
	    /*
	     * Put a marker pointing to the previous marker in this stack, and
	     * store it in esPtr as the current marker. Return a pointer to
	     * the start of aligned memory.
	     */

	    esPtr->markerPtr = tmpMarkerPtr;
	    memStart = tmpMarkerPtr + offset;
	    esPtr->tosPtr = memStart - 1;
	    *esPtr->markerPtr = (Tcl_Obj *) markerPtr;
	    return memStart;
	}
#endif
    }

    /*
     * Reset move to hold the number of words to be moved to new stack (if
     * any) and growth to hold the complete stack requirements: add one for
     * the marker, (WALLOCALIGN-1) for the maximal possible offset.
     */

    if (move) {
	moveWords = esPtr->tosPtr - MEMSTART(markerPtr) + 1;
    }
    needed = growth + moveWords + WALLOCALIGN - 1;

    
    /*
     * Check if there is enough room in the next stack (if there is one, it
     * should be both empty and the last one!)
     */

    if (esPtr->nextPtr) {
	oldPtr = esPtr;
1102
1103
1104
1105
1106
1107
1108

1109
1110
1111
1112




1113
1114
1115
1116
1117
1118
1119
    }

    /*
     * We need to allocate a new stack! It needs to store 'growth' words,
     * including the elements to be copied over and the new marker.
     */


    newElems = 2*currElems;
    while (needed > newElems) {
	newElems *= 2;
    }




    newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);

    oldPtr = esPtr;
    esPtr = ckalloc(newBytes);

    oldPtr->nextPtr = esPtr;
    esPtr->prevPtr = oldPtr;







>




>
>
>
>







1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
    }

    /*
     * We need to allocate a new stack! It needs to store 'growth' words,
     * including the elements to be copied over and the new marker.
     */

#ifndef PURIFY
    newElems = 2*currElems;
    while (needed > newElems) {
	newElems *= 2;
    }
#else
    newElems = needed;
#endif
    
    newBytes = sizeof(ExecStack) + (newElems-1) * sizeof(Tcl_Obj *);

    oldPtr = esPtr;
    esPtr = ckalloc(newBytes);

    oldPtr->nextPtr = esPtr;
    esPtr->prevPtr = oldPtr;
1254
1255
1256
1257
1258
1259
1260




1261
1262
1263
1264
1265
1266
1267
	    DeleteExecStack(tmpPtr);
	} else {
	    break;
	}
    }
    if (esPtr->prevPtr) {
	eePtr->execStackPtr = esPtr->prevPtr;




    } else {
	eePtr->execStackPtr = esPtr;
    }
}

void *
TclStackAlloc(







>
>
>
>







1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
	    DeleteExecStack(tmpPtr);
	} else {
	    break;
	}
    }
    if (esPtr->prevPtr) {
	eePtr->execStackPtr = esPtr->prevPtr;
#ifdef PURIFY
	eePtr->execStackPtr->nextPtr = NULL;
	DeleteExecStack(esPtr);
#endif
    } else {
	eePtr->execStackPtr = esPtr;
    }
}

void *
TclStackAlloc(

Changes to generic/tclInt.h.

4010
4011
4012
4013
4014
4015
4016

4017
4018
4019
4020
4021
4022
4023
#  define TclAllocObjStorageEx(interp, objPtr) \
	(objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))

#  define TclFreeObjStorageEx(interp, objPtr) \
	ckfree((char *) (objPtr))

#undef USE_THREAD_ALLOC

#elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)

/*
 * The TCL_THREADS mode is like the regular mode but allocates Tcl_Obj's from
 * per-thread caches.
 */








>







4010
4011
4012
4013
4014
4015
4016
4017
4018
4019
4020
4021
4022
4023
4024
#  define TclAllocObjStorageEx(interp, objPtr) \
	(objPtr) = (Tcl_Obj *) ckalloc(sizeof(Tcl_Obj))

#  define TclFreeObjStorageEx(interp, objPtr) \
	ckfree((char *) (objPtr))

#undef USE_THREAD_ALLOC
#undef USE_TCLALLOC
#elif defined(TCL_THREADS) && defined(USE_THREAD_ALLOC)

/*
 * The TCL_THREADS mode is like the regular mode but allocates Tcl_Obj's from
 * per-thread caches.
 */