[krbdev.mit.edu #1714] starttime marshalling bug on 64bit platforms in krb524d

Tom Yu via RT rt-comment at krbdev.mit.edu
Thu Aug 7 22:36:03 EDT 2003


>>>>> "Cesar" == Cesar Garcia via RT <rt-comment at krbdev.mit.edu> writes:

Cesar> Are we looking at the same thing?

Yes...

Cesar> ====> KRB4_PUT32BE is the relevent macro, from include/kerberosIV/prot.h:

Cesar>    #define KRB4_PUT32BE(p, val)                    \
Cesar>    do {                                            \
Cesar>        (p)[0] = ((KRB_UINT32)(val) >> 24) & 0xff;  \
Cesar>        (p)[1] = ((KRB_UINT32)(val) >> 16) & 0xff;  \
Cesar>        (p)[2] = ((KRB_UINT32)(val) >> 8)  & 0xff;  \
Cesar>        (p)[3] =  (KRB_UINT32)(val)        & 0xff;  \
Cesar>        (p) += 4;                                   \
Cesar>    } while (0)

Cesar> This is equivalent to casting an 8byte or 4byte quantities (val) to a 4
Cesar> byte quantity and memcpy'ing the 4 bytes.

It is not.  It is equivalent to truncating a 64-bit or 32-bit quantity
(or whatever) to 32 bits and unconditionally encoding as big-endian.
The cast operates on the value, not on its representation.  The
sequence of shifts always produces a big-endian encoding, hence the
name of the macro.

If there were a cast of a _pointer_ to a 64-bit integer to a pointer
to a 32-bit integer, you would have gotten all zeroes on a big-endian
machine when shifting out the value.

Cesar> If val is big endian, it writes the (casted) 4 bytes as would a
Cesar> memcpy of 4 bytes, resulting in network byte order (big endian).

Cesar> If val is little endian, this again, copies bytes as would a
Cesar> mempcy, resulting in little endian.

The endianness of val is irrelevant here, since we're not accessing it
with a char pointer, or doing any other sort of pointer casting.

Cesar> With 1.3.1 krb524d running on linux - with code borrowed from libkrb4
Cesar> as shown above, start time is:

Cesar> 1060266366 (decimal), or

Cesar> 7E61323F (hex, in host byte order, which on my linux box is little
Cesar> endian).

Ah.  Assuming you copied only the call to the KRB4_PUT32BE macro, and
not the other parts of the cr_tkt, you may have wound up with an
inconsistent packet.  There is a flag at the beginning of the packet
that indicates what byte order it has.  If you did not adjust the
setting of this flag to match the byte order used to encode the
timestamp, the receiving server would decide incorrectly whether to
byte-swap.

Cesar> Would be 3F32617E (hex, if converted to big endian)

Cesar> These corresponds to: Thu Aug  7 10:26:06 EDT 2003

Cesar> However, when 7E61323F is interpreted as big endian (212029907 in
Cesar> decimal), by AFS server, it corresponds to Tue Mar 10 06:57:51 EDT
Cesar> 2037.

No, it would have gotten 0x3F32617E in big-endian, but incorrectly
byte-swapped it because the setting of the endianness flag would
correspond to little-endian.

---Tom



More information about the krb5-bugs mailing list