]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Fix xdr_bytes() strict-aliasing violations 1012/head
authorGreg Hudson <ghudson@mit.edu>
Tue, 10 Dec 2019 17:06:05 +0000 (12:06 -0500)
committerGreg Hudson <ghudson@mit.edu>
Sun, 5 Jan 2020 06:16:55 +0000 (01:16 -0500)
When xdr_bytes() is used for a gss_buffer_desc object, a temporary
character pointer must be used for the data value to avoid a strict
aliasing violation.

When xdr_bytes() is used for a krb5_keyblock object, a temporary
character pointer must also be used, even though the data pointer is
of type unsigned char *, to avoid a clang warning on macOS due to the
"#pragma pack" declaration in krb5.h.

src/lib/kadm5/kadm_rpc_xdr.c
src/lib/rpc/auth_gssapi_misc.c
src/lib/rpc/authgss_prot.c

index f22ea7f1f8cdb8e3d713b8e9bff1287bbb340357..8383e4e23013294bb10f25c9f296438e913698f7 100644 (file)
@@ -1125,14 +1125,16 @@ xdr_krb5_salttype(XDR *xdrs, krb5_int32 *objp)
 bool_t
 xdr_krb5_keyblock(XDR *xdrs, krb5_keyblock *objp)
 {
+   char *cp;
+
    /* XXX This only works because free_keyblock assumes ->contents
       is allocated by malloc() */
-
    if(!xdr_krb5_enctype(xdrs, &objp->enctype))
       return FALSE;
-   if(!xdr_bytes(xdrs, (char **) &objp->contents, (unsigned int *)
-                &objp->length, ~0))
+   cp = (char *)objp->contents;
+   if(!xdr_bytes(xdrs, &cp, &objp->length, ~0))
       return FALSE;
+   objp->contents = (uint8_t *)cp;
    return TRUE;
 }
 
index a05ea19eb7c45c8acf2d8d3b1a4e72e2938789e6..a60eb7f7cb61b56d9c2d2260bb1897b8c140bc46 100644 (file)
@@ -45,9 +45,11 @@ bool_t xdr_gss_buf(
      bool_t result;
      /* Fix type mismatches between APIs.  */
      unsigned int length = buf->length;
-     result = xdr_bytes(xdrs, (char **) &buf->value, &length,
+     char *cp = buf->value;
+     result = xdr_bytes(xdrs, &cp, &length,
                        (xdrs->x_op == XDR_DECODE && buf->value == NULL)
                        ? (unsigned int) -1 : (unsigned int) buf->length);
+     buf->value = cp;
      buf->length = length;
      return result;
 }
@@ -204,6 +206,7 @@ bool_t auth_gssapi_wrap_data(
      XDR temp_xdrs;
      int conf_state;
      unsigned int length;
+     char *cp;
 
      PRINTF(("gssapi_wrap_data: starting\n"));
 
@@ -243,13 +246,13 @@ bool_t auth_gssapi_wrap_data(
 
      /* write the token */
      length = out_buf.length;
-     if (! xdr_bytes(out_xdrs, (char **) &out_buf.value,
-                    (unsigned int *) &length,
-                    out_buf.length)) {
+     cp = out_buf.value;
+     if (! xdr_bytes(out_xdrs, &cp, &length, out_buf.length)) {
          PRINTF(("gssapi_wrap_data: serializing encrypted data failed\n"));
          XDR_DESTROY(&temp_xdrs);
          return FALSE;
      }
+     out_buf.value = cp;
 
      *major = gss_release_buffer(minor, &out_buf);
 
@@ -272,6 +275,7 @@ bool_t auth_gssapi_unwrap_data(
      uint32_t verf_seq_num;
      int conf, qop;
      unsigned int length;
+     char *cp;
 
      PRINTF(("gssapi_unwrap_data: starting\n"));
 
@@ -280,14 +284,15 @@ bool_t auth_gssapi_unwrap_data(
 
      in_buf.value = NULL;
      out_buf.value = NULL;
-     if (! xdr_bytes(in_xdrs, (char **) &in_buf.value,
-                    &length, (unsigned int) -1)) {
+     cp = in_buf.value;
+     if (! xdr_bytes(in_xdrs, &cp, &length, (unsigned int) -1)) {
         PRINTF(("gssapi_unwrap_data: deserializing encrypted data failed\n"));
         temp_xdrs.x_op = XDR_FREE;
-        (void)xdr_bytes(&temp_xdrs, (char **) &in_buf.value, &length,
-                        (unsigned int) -1);
+        (void)xdr_bytes(&temp_xdrs, &cp, &length, (unsigned int) -1);
+        in_buf.value = NULL;
         return FALSE;
      }
+     in_buf.value = cp;
      in_buf.length = length;
 
      *major = gss_unseal(minor, context, &in_buf, &out_buf, &conf,
index a5a587f90553279a18df7bad3bd2e9b8c98f1e41..9a48277b34a83701ad9362031236e9609a754196 100644 (file)
@@ -50,6 +50,7 @@ xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
 {
        bool_t xdr_stat;
        u_int tmplen;
+       char *cp;
 
        if (xdrs->x_op != XDR_DECODE) {
                if (buf->length > UINT_MAX)
@@ -57,7 +58,9 @@ xdr_rpc_gss_buf(XDR *xdrs, gss_buffer_t buf, u_int maxsize)
                else
                        tmplen = buf->length;
        }
-       xdr_stat = xdr_bytes(xdrs, (char **)&buf->value, &tmplen, maxsize);
+       cp = buf->value;
+       xdr_stat = xdr_bytes(xdrs, &cp, &tmplen, maxsize);
+       buf->value = cp;
 
        if (xdr_stat && xdrs->x_op == XDR_DECODE)
                buf->length = tmplen;