Comment 5 for bug 683546

Revision history for this message
Loïc Minier (lool) wrote : Re: gitk crashes on start

Problem is this struct in generic/tclCmdMZ.c:
typedef struct {
    int flags; /* Operations for which Tcl command is
                                 * to be invoked. */
    size_t length; /* Number of non-NULL chars. in command. */
    char command[4]; /* Space for Tcl command to invoke. Actual
                                 * size will be as large as necessary to
                                 * hold command. This field must be the
                                 * last in the structure, so that it can
                                 * be larger than 4 bytes. */
} TraceVarInfo;

it defines command with length 4, but in reality more bytes are allocated:
typedef struct {
    VarTrace trace;
    TraceVarInfo tvar;
} CompoundVarTrace;
[...]
                CompoundVarTrace *compTracePtr;
[...]
                compTracePtr = (CompoundVarTrace *) ckalloc((unsigned)
                        (sizeof(CompoundVarTrace) - sizeof(tvarPtr->command)
                                + length + 1));

but the strcpy() call doesn't know about that:
                tvarPtr = &(compTracePtr->tvar);
[...]
                strcpy(tvarPtr->command, command);

so strcpy_chk thinks that the destination buffers is 4 bytes long, but it's called with larger source strings at runtime, e.g. "::tk::EventMotifBindings".

One way to avoid this would be to declare command[] with the maximum size a variable name can have, but I couldn't find this limit in the tcl source code.

For now, I'm going to patch the build to pass -U_FORTIFY_SOURCE.

This doesn't happen in tcl8.5, and it's a false positive, not sure how useful it is to chase this down.