krb5: crypto.c avoid realloc to trim memory allocation

decrypt_internal_derived(), decrypt_internal_enc_then_cksum(),
decrypt_internal(), and decrypt_internal_special() execute the
following pattern where 'p' is an allocation of size 'len'

  l = len - n
  memmove(p, p + n, l);
  result->data = realloc(p, l);
  if (result->data == NULL && l != 0) {
      free(p);
      return krb5_enomem(context);
  }
  result->length = l;

which when compiled by gcc 13.0.1-0.12.fc38 or gcc-13.0.1-0.13.fc39
generates the following warning

  warning: pointer 'p' may be used after 'realloc' [-Wuse-after-free]

The C language specification indicates that it is only safe to free()
the pointer passed to realloc() if errno is set to ENOMEM.  Yet the
warning is generated by the following pattern

  l = len - n
  memmove(p, p + n, l);
  errno = 0;
  result->data = realloc(p, l);
  if (result->data == NULL && l != 0) {
      if (errno == ENOMEM)
          free(p);
      return krb5_enomem(context);
  }
  result->length = l;

The value of performing the realloc() is questionable.  realloc()
in many cases will need to perform a second allocation of the
smaller size and then perform a memcpy() which will slow down
the operation without saving much memory.  The allocation is already
very small.

This change avoids the warning by removing the realloc() entirely.
This commit is contained in:
Jeffrey Altman
2023-04-19 08:33:25 -04:00
parent d280a83ebe
commit 1b1ff8fdd5

View File

@@ -1275,11 +1275,6 @@ decrypt_internal_derived(krb5_context context,
}
l = len - et->confoundersize;
memmove(p, p + et->confoundersize, l);
result->data = realloc(p, l);
if(result->data == NULL && l != 0) {
free(p);
return krb5_enomem(context);
}
result->length = l;
return 0;
}
@@ -1360,11 +1355,6 @@ decrypt_internal_enc_then_cksum(krb5_context context,
l = len - et->confoundersize;
memmove(p, p + et->blocksize + et->confoundersize, l);
result->data = realloc(p, l);
if(result->data == NULL && l != 0) {
free(p);
return krb5_enomem(context);
}
result->length = l;
return 0;
}
@@ -1426,11 +1416,6 @@ decrypt_internal(krb5_context context,
}
l = len - et->confoundersize - checksum_sz;
memmove(p, p + et->confoundersize + checksum_sz, l);
result->data = realloc(p, l);
if(result->data == NULL && l != 0) {
free(p);
return krb5_enomem(context);
}
result->length = l;
return 0;
}
@@ -1473,11 +1458,6 @@ decrypt_internal_special(krb5_context context,
}
memmove (p, p + cksum_sz + et->confoundersize, sz);
result->data = realloc(p, sz);
if(result->data == NULL && sz != 0) {
free(p);
return krb5_enomem(context);
}
result->length = sz;
return 0;
}