MITKRB5-SA-2003-003: xdrmem int overflows
authorTom Yu <tlyu@mit.edu>
Mon, 24 Mar 2003 22:55:51 +0000 (22:55 +0000)
committerTom Yu <tlyu@mit.edu>
Mon, 24 Mar 2003 22:55:51 +0000 (22:55 +0000)
* xdr_mem.c (xdrmem_create): Perform some additional size checks.
(xdrmem_getlong, xdrmem_putlong, xdrmem_getbytes): Check x_handy
prior to decrementing it.

ticket: new
status: open
tags: pullup
target_version: 1.3

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@15300 dc483132-0cff-0310-8789-dd5450dbe970

src/lib/rpc/ChangeLog
src/lib/rpc/xdr_mem.c

index 6534240549acd6c8a9c45e7a54c8f46ea9f0c943..725db86bcff5e99629753766ace192d8305cebeb 100644 (file)
@@ -1,3 +1,9 @@
+2003-03-24  Tom Yu  <tlyu@mit.edu>
+
+       * xdr_mem.c (xdrmem_create): Perform some additional size checks.
+       (xdrmem_getlong, xdrmem_putlong, xdrmem_getbytes): Check x_handy
+       prior to decrementing it.
+
 2003-01-12  Ezra Peisach  <epeisach@bu.edu>
 
        * svc_auth_gssapi.c (_svcauth_gssapi_unset_names): If invoked more
index 18265da817817ab1ea66bc43008fb6bbc0d9be08..58e2d82a377097f59330eda2a657e14295cc449e 100644 (file)
@@ -48,6 +48,7 @@ static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro";
 #include <netinet/in.h>
 #include <stdio.h>
 #include <string.h>
+#include <limits.h>
 
 static bool_t  xdrmem_getlong(XDR *, long *);
 static bool_t  xdrmem_putlong(XDR *, long *);
@@ -84,7 +85,7 @@ xdrmem_create(xdrs, addr, size, op)
        xdrs->x_op = op;
        xdrs->x_ops = &xdrmem_ops;
        xdrs->x_private = xdrs->x_base = addr;
-       xdrs->x_handy = size;
+       xdrs->x_handy = (size > INT_MAX) ? INT_MAX : size; /* XXX */
 }
 
 static void
@@ -99,8 +100,10 @@ xdrmem_getlong(xdrs, lp)
        long *lp;
 {
 
-       if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+       if (xdrs->x_handy < sizeof(rpc_int32))
                return (FALSE);
+       else
+               xdrs->x_handy -= sizeof(rpc_int32);
        *lp = (long)ntohl(*((rpc_u_int32 *)(xdrs->x_private)));
        xdrs->x_private = (char *)xdrs->x_private + sizeof(rpc_int32);
        return (TRUE);
@@ -112,8 +115,10 @@ xdrmem_putlong(xdrs, lp)
        long *lp;
 {
 
-       if ((xdrs->x_handy -= sizeof(rpc_int32)) < 0)
+       if (xdrs->x_handy < sizeof(rpc_int32))
                return (FALSE);
+       else
+               xdrs->x_handy -= sizeof(rpc_int32);
        *(rpc_int32 *)xdrs->x_private = (rpc_int32)htonl((rpc_u_int32)(*lp));
        xdrs->x_private = (char *)xdrs->x_private + sizeof(rpc_int32);
        return (TRUE);
@@ -126,8 +131,10 @@ xdrmem_getbytes(xdrs, addr, len)
        register unsigned int len;
 {
 
-       if ((xdrs->x_handy -= len) < 0)
+       if (xdrs->x_handy < len)
                return (FALSE);
+       else
+               xdrs->x_handy -= len;
        memmove(addr, xdrs->x_private, len);
        xdrs->x_private = (char *)xdrs->x_private + len;
        return (TRUE);
@@ -140,8 +147,10 @@ xdrmem_putbytes(xdrs, addr, len)
        register unsigned int len;
 {
 
-       if ((xdrs->x_handy -= len) < 0)
+       if (xdrs->x_handy < len)
                return (FALSE);
+       else
+               xdrs->x_handy -= len;
        memmove(xdrs->x_private, addr, len);
        xdrs->x_private = (char *)xdrs->x_private + len;
        return (TRUE);
@@ -180,7 +189,7 @@ xdrmem_inline(xdrs, len)
 {
        rpc_int32 *buf = 0;
 
-       if (xdrs->x_handy >= len) {
+       if (len >= 0 && xdrs->x_handy >= len) {
                xdrs->x_handy -= len;
                buf = (rpc_int32 *) xdrs->x_private;
                xdrs->x_private = (char *)xdrs->x_private + len;