[2961] in Kerberos-V5-bugs
krb5-libs/626: shsUpdate, shsFinalize can trash core or produce bad results.
daemon@ATHENA.MIT.EDU (Marcus D Watts)
Tue Sep 1 19:05:15 1998
Resent-From: gnats@rt-11.MIT.EDU (GNATS Management)
Resent-To: krb5-unassigned@RT-11.MIT.EDU
Resent-Reply-To: krb5-bugs@MIT.EDU, mdw@quince.ifs.umich.edu
Date: Tue, 1 Sep 1998 18:57:54 -0400
From: Marcus D Watts <mdw@quince.ifs.umich.edu>
Reply-To: mdw@quince.ifs.umich.edu
To: krb5-bugs@MIT.EDU
>Number: 626
>Category: krb5-libs
>Synopsis: shsUpdate, shsFinalize can trash core or produce bad results.
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: krb5-unassigned
>State: open
>Class: sw-bug
>Submitter-Id: unknown
>Arrival-Date: Tue Sep 01 18:59:01 EDT 1998
>Last-Modified:
>Originator: Marcus D Watts
>Organization:
University of Michigan
>Release: krb5-current-19980804
>Environment:
System: SunOS pepper-pot 5.6 Generic_105181-03 sun4u sparc SUNW,Ultra-5_10
Architecture: sun4
>Description:
If the first call to shsUpdate has left some data, and the 2nd call
to shsUpdate passes too little data to make up a complete block,
shsTransform may still be called in certain circumstances.
If the sum of counts to previous calls to shsUpdate is not a
multiple of 4, the first 1-3 bytes of data supplied is or'd into
the wrong part of a word.
If shsUpdate is given a very small count (1-6 bytes), it can under
certain conditions fetch and mis-use an extra word of data.
If the byte count of the total amount of data supplied is 60-63 mod
64, shsFinalize will zero an extra word of storage immediately past
the end of the SHS_INFO structure passed to it.
See
http://web.mit.edu/afs/umich.edu/user/m/d/mdw/src/shs/
for more information including test programs.
>How-To-Repeat:
The file /afs/umich.edu/user/m/d/mdw/src/shs/t_shs3.c contains
a program will exercise the bugs.
>Fix:
--- shs_old.c Tue Sep 1 18:13:26 1998
+++ shs_n.c Tue Sep 1 18:13:25 1998
@@ -272,25 +272,21 @@
/* Handle any leading odd-sized chunks */
if (dataCount) {
lp = shsInfo->data + dataCount / 4;
- canfill = (count >= dataCount);
dataCount = SHS_DATASIZE - dataCount;
+ canfill = (count >= dataCount);
if (dataCount % 4) {
/* Fill out a full 32 bit word first if needed -- this
is not very efficient (computed shift amount),
but it shouldn't happen often. */
while (dataCount % 4 && count > 0) {
- *lp |= (LONG) *buffer++ << ((3 - dataCount++ % 4) * 8);
+ *lp |= (LONG) *buffer++ << ((--dataCount % 4) * 8);
count--;
}
lp++;
}
while (lp < shsInfo->data + 16) {
- *lp = (LONG) *buffer++ << 24;
- *lp |= (LONG) *buffer++ << 16;
- *lp |= (LONG) *buffer++ << 8;
- *lp++ |= (LONG) *buffer++;
- if ((count -= 4) < 4 && lp < shsInfo->data + 16) {
+ if (count < 4) {
*lp = 0;
switch (count % 4) {
case 3:
@@ -300,9 +296,14 @@
case 1:
*lp |= (LONG) buffer[0] << 24;
}
- break;
count = 0;
+ break;
}
+ *lp = (LONG) *buffer++ << 24;
+ *lp |= (LONG) *buffer++ << 16;
+ *lp |= (LONG) *buffer++ << 8;
+ *lp++ |= (LONG) *buffer++;
+ count -= 4;
}
if (canfill) {
SHSTransform(shsInfo->digest, shsInfo->data);
@@ -378,7 +379,8 @@
if (lp > shsInfo->data + 14) {
/* Pad out to 64 bytes if not enough room for length words */
- *lp = 0;
+ if (count < 60)
+ *lp = 0;
SHSTransform(shsInfo->digest, shsInfo->data);
lp = shsInfo->data;
}
>Audit-Trail:
>Unformatted: