gbproxy/sgsn: Enforce termination when creating a P-TMSI/TLLI

Currently the number of iterations when creating a P-TMSI/TLLI is not
limited. It is nevertheless very unlikely that the loop will not
terminate. On the other hand, the number of iterations of every loop
should have an upper bound (loop variant) which wouldn't be the case
here if an arbitrary random generator was used.

This patch limits the number of iterations to 23 and logs an error if
the creation of the indentifier was aborted due to this limit.

Sponsored-by: On-Waves ehf
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index daa9ba0..8b5a672 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -226,6 +226,7 @@
 				uint32_t sgsn_ptmsi)
 {
 	uint32_t bss_ptmsi;
+	int max_retries = 23;
 	if (!peer->cfg->patch_ptmsi) {
 		bss_ptmsi = sgsn_ptmsi;
 	} else {
@@ -235,9 +236,12 @@
 
 			if (gbproxy_find_tlli_by_ptmsi(peer, bss_ptmsi))
 				bss_ptmsi = GSM_RESERVED_TMSI;
-		} while (bss_ptmsi == GSM_RESERVED_TMSI);
+		} while (bss_ptmsi == GSM_RESERVED_TMSI && max_retries--);
 	}
 
+	if (bss_ptmsi == GSM_RESERVED_TMSI)
+		LOGP(DGPRS, LOGL_ERROR, "Failed to allocate a BSS P-TMSI\n");
+
 	return bss_ptmsi;
 }
 
@@ -246,6 +250,7 @@
 				uint32_t bss_tlli)
 {
 	uint32_t sgsn_tlli;
+	int max_retries = 23;
 	if (!peer->cfg->patch_ptmsi) {
 		sgsn_tlli = bss_tlli;
 	} else if (tlli_info->sgsn_tlli.ptmsi != GSM_RESERVED_TMSI) {
@@ -259,8 +264,12 @@
 
 			if (gbproxy_find_tlli_by_any_sgsn_tlli(peer, sgsn_tlli))
 				sgsn_tlli = 0;
-		} while (!sgsn_tlli);
+		} while (!sgsn_tlli && max_retries--);
 	}
+
+	if (!sgsn_tlli)
+		LOGP(DGPRS, LOGL_ERROR, "Failed to allocate an SGSN TLLI\n");
+
 	return sgsn_tlli;
 }