summaryrefslogtreecommitdiff
path: root/src/backend/utils
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils')
-rw-r--r--src/backend/utils/resowner/resowner.c61
1 files changed, 61 insertions, 0 deletions
diff --git a/src/backend/utils/resowner/resowner.c b/src/backend/utils/resowner/resowner.c
index a171df573ce..e24f00f0601 100644
--- a/src/backend/utils/resowner/resowner.c
+++ b/src/backend/utils/resowner/resowner.c
@@ -22,6 +22,7 @@
#include "common/cryptohash.h"
#include "common/hashfn.h"
+#include "common/hmac.h"
#include "jit/jit.h"
#include "storage/bufmgr.h"
#include "storage/ipc.h"
@@ -130,6 +131,7 @@ typedef struct ResourceOwnerData
ResourceArray dsmarr; /* dynamic shmem segments */
ResourceArray jitarr; /* JIT contexts */
ResourceArray cryptohasharr; /* cryptohash contexts */
+ ResourceArray hmacarr; /* HMAC contexts */
/* We can remember up to MAX_RESOWNER_LOCKS references to local locks. */
int nlocks; /* number of owned locks */
@@ -178,6 +180,7 @@ static void PrintSnapshotLeakWarning(Snapshot snapshot);
static void PrintFileLeakWarning(File file);
static void PrintDSMLeakWarning(dsm_segment *seg);
static void PrintCryptoHashLeakWarning(Datum handle);
+static void PrintHMACLeakWarning(Datum handle);
/*****************************************************************************
@@ -448,6 +451,7 @@ ResourceOwnerCreate(ResourceOwner parent, const char *name)
ResourceArrayInit(&(owner->dsmarr), PointerGetDatum(NULL));
ResourceArrayInit(&(owner->jitarr), PointerGetDatum(NULL));
ResourceArrayInit(&(owner->cryptohasharr), PointerGetDatum(NULL));
+ ResourceArrayInit(&(owner->hmacarr), PointerGetDatum(NULL));
return owner;
}
@@ -568,6 +572,16 @@ ResourceOwnerReleaseInternal(ResourceOwner owner,
PrintCryptoHashLeakWarning(foundres);
pg_cryptohash_free(context);
}
+
+ /* Ditto for HMAC contexts */
+ while (ResourceArrayGetAny(&(owner->hmacarr), &foundres))
+ {
+ pg_hmac_ctx *context = (pg_hmac_ctx *) PointerGetDatum(foundres);
+
+ if (isCommit)
+ PrintHMACLeakWarning(foundres);
+ pg_hmac_free(context);
+ }
}
else if (phase == RESOURCE_RELEASE_LOCKS)
{
@@ -737,6 +751,7 @@ ResourceOwnerDelete(ResourceOwner owner)
Assert(owner->dsmarr.nitems == 0);
Assert(owner->jitarr.nitems == 0);
Assert(owner->cryptohasharr.nitems == 0);
+ Assert(owner->hmacarr.nitems == 0);
Assert(owner->nlocks == 0 || owner->nlocks == MAX_RESOWNER_LOCKS + 1);
/*
@@ -765,6 +780,7 @@ ResourceOwnerDelete(ResourceOwner owner)
ResourceArrayFree(&(owner->dsmarr));
ResourceArrayFree(&(owner->jitarr));
ResourceArrayFree(&(owner->cryptohasharr));
+ ResourceArrayFree(&(owner->hmacarr));
pfree(owner);
}
@@ -1428,3 +1444,48 @@ PrintCryptoHashLeakWarning(Datum handle)
elog(WARNING, "cryptohash context reference leak: context %p still referenced",
DatumGetPointer(handle));
}
+
+/*
+ * Make sure there is room for at least one more entry in a ResourceOwner's
+ * hmac context reference array.
+ *
+ * This is separate from actually inserting an entry because if we run out of
+ * memory, it's critical to do so *before* acquiring the resource.
+ */
+void
+ResourceOwnerEnlargeHMAC(ResourceOwner owner)
+{
+ ResourceArrayEnlarge(&(owner->hmacarr));
+}
+
+/*
+ * Remember that a HMAC context is owned by a ResourceOwner
+ *
+ * Caller must have previously done ResourceOwnerEnlargeHMAC()
+ */
+void
+ResourceOwnerRememberHMAC(ResourceOwner owner, Datum handle)
+{
+ ResourceArrayAdd(&(owner->hmacarr), handle);
+}
+
+/*
+ * Forget that a HMAC context is owned by a ResourceOwner
+ */
+void
+ResourceOwnerForgetHMAC(ResourceOwner owner, Datum handle)
+{
+ if (!ResourceArrayRemove(&(owner->hmacarr), handle))
+ elog(ERROR, "HMAC context %p is not owned by resource owner %s",
+ DatumGetPointer(handle), owner->name);
+}
+
+/*
+ * Debugging subroutine
+ */
+static void
+PrintHMACLeakWarning(Datum handle)
+{
+ elog(WARNING, "HMAC context reference leak: context %p still referenced",
+ DatumGetPointer(handle));
+}