diff --git a/libpurple/glibcompat.h b/libpurple/glibcompat.h
--- a/libpurple/glibcompat.h
+++ b/libpurple/glibcompat.h
@@ -54,4 +54,22 @@
 gchar *purple_compat_date_time_format_iso8601(GDateTime *datetime);
 #endif /* GLIB_CHECK_VERSION(2, 62, 0) */
 
+/* Backport the static inline version of g_memdup2 if we don't have g_memdup2.
+ * see https://mail.gnome.org/archives/desktop-devel-list/2021-February/msg00000.html
+ * for more information.
+ */
+#if !GLIB_CHECK_VERSION(2, 67, 3)
+static inline gpointer
+g_memdup2(gconstpointer mem, gsize byte_size) {
+	gpointer new_mem = NULL;
+
+	if(mem && byte_size != 0) {
+		new_mem = g_malloc (byte_size);
+		memcpy (new_mem, mem, byte_size);
+	}
+
+	return new_mem;
+}
+#endif /* !GLIB_CHECK_VERSION(2, 67, 3) */
+
 #endif /* PURPLE_GLIBCOMPAT_H */
diff --git a/libpurple/image.h b/libpurple/image.h
--- a/libpurple/image.h
+++ b/libpurple/image.h
@@ -102,7 +102,7 @@
  * Creates a new #PurpleImage object with contents of @data buffer.
  *
  * The @data buffer is owned by #PurpleImage object, so you might want
- * to #g_memdup it first.
+ * to g_memdup2() it first.
  *
  * Returns: the new #PurpleImage.
  */
@@ -116,7 +116,7 @@
  * Creates a new #PurpleImage object with contents of @data buffer.
  *
  * The @data buffer is owned by #PurpleImage object, so you might want
- * to #g_memdup it first.
+ * to g_memdup2() it first.
  *
  * Returns: the new #PurpleImage.
  */
diff --git a/libpurple/mediamanager.c b/libpurple/mediamanager.c
--- a/libpurple/mediamanager.c
+++ b/libpurple/mediamanager.c
@@ -25,6 +25,7 @@
 
 #include "account.h"
 #include "debug.h"
+#include "glibcompat.h"
 #include "media.h"
 #include "mediamanager.h"
 
@@ -1696,7 +1697,7 @@
 		media, session_id, participant);
 
 	if (info && info->appsrc && info->connected) {
-		GstBuffer *gstbuffer = gst_buffer_new_wrapped (g_memdup (buffer, size),
+		GstBuffer *gstbuffer = gst_buffer_new_wrapped (g_memdup2(buffer, size),
 			size);
 		GstAppSrc *appsrc = gst_object_ref (info->appsrc);
 
diff --git a/libpurple/protocols/bonjour/buddy.c b/libpurple/protocols/bonjour/buddy.c
--- a/libpurple/protocols/bonjour/buddy.c
+++ b/libpurple/protocols/bonjour/buddy.c
@@ -21,6 +21,7 @@
 
 #include "buddy.h"
 #include "bonjour.h"
+#include "glibcompat.h"
 
 /**
  * Creates a new buddy.
@@ -229,7 +230,7 @@
 			  hash, buddy->phsh ? buddy->phsh : "(null)");
 
 	purple_buddy_icons_set_for_user(buddy->account, buddy->name,
-		g_memdup(data, len), len, hash);
+		g_memdup2(data, len), len, hash);
 
 	g_free(hash);
 }
diff --git a/libpurple/protocols/facebook/api.c b/libpurple/protocols/facebook/api.c
--- a/libpurple/protocols/facebook/api.c
+++ b/libpurple/protocols/facebook/api.c
@@ -26,6 +26,7 @@
 #include <stdarg.h>
 #include <string.h>
 
+#include "libpurple/glibcompat.h"
 
 #include "api.h"
 #include "http.h"
@@ -3243,7 +3244,7 @@
 		return g_new0(FbApiEvent, 1);
 	}
 
-	ret = g_memdup(event, sizeof *event);
+	ret = g_memdup2(event, sizeof *event);
 
 	if (deep) {
 		ret->text = g_strdup(event->text);
@@ -3282,7 +3283,7 @@
 		return g_new0(FbApiMessage, 1);
 	}
 
-	ret = g_memdup(msg, sizeof *msg);
+	ret = g_memdup2(msg, sizeof *msg);
 
 	if (deep) {
 		ret->text = g_strdup(msg->text);
@@ -3319,7 +3320,7 @@
 		return g_new0(FbApiPresence, 1);
 	}
 
-	return g_memdup(pres, sizeof *pres);
+	return g_memdup2(pres, sizeof *pres);
 }
 
 void
@@ -3348,7 +3349,7 @@
 		return g_new0(FbApiThread, 1);
 	}
 
-	ret = g_memdup(thrd, sizeof *thrd);
+	ret = g_memdup2(thrd, sizeof *thrd);
 
 	if (deep) {
 		ret->users = NULL;
@@ -3395,7 +3396,7 @@
 		return g_new0(FbApiTyping, 1);
 	}
 
-	return g_memdup(typg, sizeof *typg);
+	return g_memdup2(typg, sizeof *typg);
 }
 
 void
@@ -3422,7 +3423,7 @@
 		return g_new0(FbApiUser, 1);
 	}
 
-	ret = g_memdup(user, sizeof *user);
+	ret = g_memdup2(user, sizeof *user);
 
 	if (deep) {
 		ret->name = g_strdup(user->name);
diff --git a/libpurple/protocols/facebook/data.c b/libpurple/protocols/facebook/data.c
--- a/libpurple/protocols/facebook/data.c
+++ b/libpurple/protocols/facebook/data.c
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "api.h"
 #include "data.h"
@@ -397,7 +398,7 @@
 		return;
 	}
 
-	key = g_memdup(&id, sizeof id);
+	key = g_memdup2(&id, sizeof id);
 	g_hash_table_replace(priv->unread, key, GINT_TO_POINTER(unread));
 }
 
@@ -539,7 +540,7 @@
 		return NULL;
 	}
 
-	return g_memdup(priv->image, priv->size);
+	return g_memdup2(priv->image, priv->size);
 }
 
 const gchar *
diff --git a/libpurple/protocols/facebook/facebook.c b/libpurple/protocols/facebook/facebook.c
--- a/libpurple/protocols/facebook/facebook.c
+++ b/libpurple/protocols/facebook/facebook.c
@@ -22,6 +22,7 @@
 #include <glib/gi18n-lib.h>
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "api.h"
 #include "data.h"
@@ -925,7 +926,7 @@
 	for (l = buddies; l != NULL; l = l->next) {
 		name = purple_buddy_get_name(l->data);
 		uid = FB_ID_FROM_STR(name);
-		did = g_memdup(&uid, sizeof uid);
+		did = g_memdup2(&uid, sizeof uid);
 		uids = g_slist_prepend(uids, did);
 	}
 
diff --git a/libpurple/protocols/gg/account.c b/libpurple/protocols/gg/account.c
--- a/libpurple/protocols/gg/account.c
+++ b/libpurple/protocols/gg/account.c
@@ -106,7 +106,7 @@
 		token_info = h->data;
 		token->id = g_strdup(token_info->tokenid);
 		token->size = h->body_size;
-		token->data = g_memdup(h->body, token->size);
+		token->data = g_memdup2(h->body, token->size);
 		token->length = token_info->length;
 	} else {
 		purple_debug_error("gg", "ggp_account_token_handler: error\n");
diff --git a/libpurple/protocols/gg/avatar.c b/libpurple/protocols/gg/avatar.c
--- a/libpurple/protocols/gg/avatar.c
+++ b/libpurple/protocols/gg/avatar.c
@@ -29,6 +29,8 @@
 
 #include "avatar.h"
 
+#include "libpurple/glibcompat.h"
+
 #include "gg.h"
 #include "utils.h"
 #include "oauth/oauth-purple.h"
@@ -136,7 +138,7 @@
 	got_data = msg->response_body->data;
 	got_len = msg->response_body->length;
 	purple_buddy_icons_set_for_user(account, purple_buddy_get_name(buddy),
-	                                g_memdup(got_data, got_len), got_len,
+	                                g_memdup2(got_data, got_len), got_len,
 	                                timestamp_str);
 
 	purple_debug_info("gg",
diff --git a/libpurple/protocols/gg/resolver-purple.c b/libpurple/protocols/gg/resolver-purple.c
--- a/libpurple/protocols/gg/resolver-purple.c
+++ b/libpurple/protocols/gg/resolver-purple.c
@@ -28,6 +28,7 @@
  */
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include <libgadu.h>
 #include "resolver-purple.h"
@@ -99,7 +100,7 @@
 					"ipv4: %s\n", ip_address);
 
 				native_size = g_inet_address_get_native_size(inet_address);
-				in_addrs = g_list_append(in_addrs, g_memdup(g_inet_address_to_bytes(inet_address), native_size));
+				in_addrs = g_list_append(in_addrs, g_memdup2(g_inet_address_to_bytes(inet_address), native_size));
 
 				break;
 			case G_SOCKET_FAMILY_IPV6:
diff --git a/libpurple/protocols/irc/dcc_send.c b/libpurple/protocols/irc/dcc_send.c
--- a/libpurple/protocols/irc/dcc_send.c
+++ b/libpurple/protocols/irc/dcc_send.c
@@ -28,6 +28,7 @@
 #endif
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "irc.h"
 
@@ -189,7 +190,7 @@
 
 		xd->rxlen -= 4;
 		if (xd->rxlen) {
-			unsigned char *tmp = g_memdup(xd->rxqueue + 4, xd->rxlen);
+			unsigned char *tmp = g_memdup2(xd->rxqueue + 4, xd->rxlen);
 			g_free(xd->rxqueue);
 			xd->rxqueue = tmp;
 		} else {
diff --git a/libpurple/protocols/jabber/data.c b/libpurple/protocols/jabber/data.c
--- a/libpurple/protocols/jabber/data.c
+++ b/libpurple/protocols/jabber/data.c
@@ -28,6 +28,7 @@
 #include <string.h>
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "data.h"
 #include "iq.h"
@@ -54,7 +55,7 @@
 	data->type = g_strdup(type);
 	data->size = size;
 	data->ephemeral = ephemeral;
-	data->data = g_memdup(rawdata, size);
+	data->data = g_memdup2(rawdata, size);
 
 	g_free(checksum);
 	return data;
diff --git a/libpurple/protocols/jabber/useravatar.c b/libpurple/protocols/jabber/useravatar.c
--- a/libpurple/protocols/jabber/useravatar.c
+++ b/libpurple/protocols/jabber/useravatar.c
@@ -26,6 +26,7 @@
 #include <glib/gi18n-lib.h>
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include <libsoup/soup.h>
 
@@ -259,7 +260,7 @@
 		goto out;
 	}
 
-	icon_data = g_memdup(msg->response_body->data, msg->response_body->length);
+	icon_data = g_memdup2(msg->response_body->data, msg->response_body->length);
 	purple_buddy_icons_set_for_user(purple_connection_get_account(info->js->gc),
 	                                info->from, icon_data,
 	                                msg->response_body->length, info->id);
diff --git a/libpurple/protocols/silc/buddy.c b/libpurple/protocols/silc/buddy.c
--- a/libpurple/protocols/silc/buddy.c
+++ b/libpurple/protocols/silc/buddy.c
@@ -996,7 +996,7 @@
 				data = silc_mime_get_data(usericon, &data_len);
 				if (data) {
 					/* TODO: Check if SILC gives us something to use as the checksum instead */
-					purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len, NULL);
+					purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup2(data, data_len), data_len, NULL);
 				}
 			}
 			silc_mime_free(usericon);
diff --git a/libpurple/protocols/silc/ops.c b/libpurple/protocols/silc/ops.c
--- a/libpurple/protocols/silc/ops.c
+++ b/libpurple/protocols/silc/ops.c
@@ -205,7 +205,7 @@
 		if (channel && !chat)
 			goto out;
 
-		img = purple_image_new_from_data(g_memdup(data, data_len), data_len);
+		img = purple_image_new_from_data(g_memdup2(data, data_len), data_len);
 		if (!img)
 			goto out;
 		img_id = purple_image_store_add_temporary(img);
diff --git a/libpurple/protocols/zephyr/Zinternal.c b/libpurple/protocols/zephyr/Zinternal.c
--- a/libpurple/protocols/zephyr/Zinternal.c
+++ b/libpurple/protocols/zephyr/Zinternal.c
@@ -10,6 +10,7 @@
  */
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "internal.h"
 #ifdef WIN32
@@ -332,7 +333,7 @@
 		 * a first fragment, grab the header from it. */
 		if (part == 0 && qptr->header == NULL) {
 			qptr->header_len = packet_len - notice.z_message_len;
-			qptr->header = g_memdup(packet, qptr->header_len);
+			qptr->header = g_memdup2(packet, qptr->header_len);
 		}
 		g_object_unref(from);
 		return Z_AddNoticeToEntry(qptr, &notice, part);
@@ -364,7 +365,7 @@
 	 * ID's will be predictable. */
 	if (part == 0) {
 		qptr->header_len = packet_len - notice.z_message_len;
-		qptr->header = g_memdup(packet, qptr->header_len);
+		qptr->header = g_memdup2(packet, qptr->header_len);
 	}
 
 	/* If this is not a fragmented notice, then don't bother with a hole
@@ -377,7 +378,7 @@
 		if (notice.z_message_len == 0) {
 			qptr->msg = NULL;
 		} else {
-			qptr->msg = g_memdup(notice.z_message, notice.z_message_len);
+			qptr->msg = g_memdup2(notice.z_message, notice.z_message_len);
 		}
 		qptr->msg_len = notice.z_message_len;
 		__Q_Size += notice.z_message_len;
diff --git a/libpurple/request.c b/libpurple/request.c
--- a/libpurple/request.c
+++ b/libpurple/request.c
@@ -23,6 +23,7 @@
 
 #include "internal.h"
 
+#include "glibcompat.h"
 #include "notify.h"
 #include "purplemarkup.h"
 #include "request.h"
@@ -1751,7 +1752,7 @@
 
 	field = purple_request_field_new(id, text, PURPLE_REQUEST_FIELD_IMAGE);
 
-	field->u.image.buffer  = g_memdup(buf, size);
+	field->u.image.buffer  = g_memdup2(buf, size);
 	field->u.image.size    = size;
 	field->u.image.scale_x = 1;
 	field->u.image.scale_y = 1;
diff --git a/libpurple/xfer.c b/libpurple/xfer.c
--- a/libpurple/xfer.c
+++ b/libpurple/xfer.c
@@ -29,6 +29,7 @@
 
 #include "debug.h"
 #include "enums.h"
+#include "glibcompat.h"
 #include "image-store.h"
 #include "network.h"
 #include "notify.h"
@@ -1953,7 +1954,7 @@
 	old_mimetype = priv->thumbnail_mimetype;
 
 	if (thumbnail && size > 0) {
-		priv->thumbnail_data = g_memdup(thumbnail, size);
+		priv->thumbnail_data = g_memdup2(thumbnail, size);
 		priv->thumbnail_size = size;
 		priv->thumbnail_mimetype = g_strdup(mimetype);
 	} else {
diff --git a/libpurple/xmlnode.c b/libpurple/xmlnode.c
--- a/libpurple/xmlnode.c
+++ b/libpurple/xmlnode.c
@@ -36,6 +36,7 @@
 #include "purplemarkup.h"
 #include "util.h"
 #include "xmlnode.h"
+#include "glibcompat.h"
 
 #ifdef _WIN32
 # define NEWLINE_S "\r\n"
@@ -108,7 +109,7 @@
 
 	child = new_node(NULL, PURPLE_XMLNODE_TYPE_DATA);
 
-	child->data = g_memdup(data, real_size);
+	child->data = g_memdup2(data, real_size);
 	child->data_sz = real_size;
 
 	purple_xmlnode_insert_child(node, child);
@@ -899,7 +900,7 @@
 	ret->xmlns = g_strdup(src->xmlns);
 	if (src->data) {
 		if (src->data_sz) {
-			ret->data = g_memdup(src->data, src->data_sz);
+			ret->data = g_memdup2(src->data, src->data_sz);
 			ret->data_sz = src->data_sz;
 		} else {
 			ret->data = g_strdup(src->data);
diff --git a/pidgin/gtkaccount.c b/pidgin/gtkaccount.c
--- a/pidgin/gtkaccount.c
+++ b/pidgin/gtkaccount.c
@@ -26,6 +26,7 @@
 #include <glib/gi18n-lib.h>
 
 #include <purple.h>
+#include "libpurple/glibcompat.h"
 
 #include "gtkaccount.h"
 #include "gtkblist.h"
@@ -731,7 +732,7 @@
 		if (img)
 		{
 			len = purple_image_get_data_size(img);
-			data = g_memdup(purple_image_get_data(img), len);
+			data = g_memdup2(purple_image_get_data(img), len);
 		}
 		set_dialog_icon(dialog, data, len,
 		                g_strdup(purple_account_get_buddy_icon_path(dialog->account)));
@@ -1376,7 +1377,7 @@
 			{
 				size_t len = purple_image_get_data_size(dialog->icon_img);
 				purple_buddy_icons_set_account_icon(account,
-					g_memdup(purple_image_get_data(dialog->icon_img), len), len);
+					g_memdup2(purple_image_get_data(dialog->icon_img), len), len);
 				purple_account_set_buddy_icon_path(account,
 					purple_image_get_path(dialog->icon_img));
 			}
diff --git a/pidgin/gtkblist-theme.c b/pidgin/gtkblist-theme.c
--- a/pidgin/gtkblist-theme.c
+++ b/pidgin/gtkblist-theme.c
@@ -22,6 +22,8 @@
 
 #include "gtkblist-theme.h"
 
+#include "libpurple/glibcompat.h"
+
 /******************************************************************************
  * Structs
  *****************************************************************************/
@@ -496,7 +498,7 @@
 {
 	g_return_val_if_fail(layout != NULL, NULL);
 
-	return g_memdup(layout, sizeof(PidginBlistLayout));
+	return g_memdup2(layout, sizeof(PidginBlistLayout));
 }
 
 GType
