mirror of
				https://gitea.osmocom.org/cellular-infrastructure/osmo-mgw.git
				synced 2025-11-03 21:43:32 +00:00 
			
		
		
		
	GPRS: Fix buffer overflow in case of very long MS RA CAP IE
The MS Radio Access Capability IE can be _very_ long in some recent high-end mobile phones, way beyond the old 14-byte limit. We increase our array to 52 bytes, and make sure not to overflow that buffer.
This commit is contained in:
		@@ -78,7 +78,7 @@ struct sgsn_mm_ctx {
 | 
				
			|||||||
	/* CKSN */
 | 
						/* CKSN */
 | 
				
			||||||
	enum gprs_ciph_algo	ciph_algo;
 | 
						enum gprs_ciph_algo	ciph_algo;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
		uint8_t	buf[14];	/* 10.5.5.12a */
 | 
							uint8_t	buf[52];	/* 10.5.5.12a */
 | 
				
			||||||
		uint8_t	len;
 | 
							uint8_t	len;
 | 
				
			||||||
	} ms_radio_access_capa;
 | 
						} ms_radio_access_capa;
 | 
				
			||||||
	struct {
 | 
						struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -675,8 +675,9 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
 | 
				
			|||||||
	/* MS Radio Access Capability 10.5.5.12a */
 | 
						/* MS Radio Access Capability 10.5.5.12a */
 | 
				
			||||||
	ms_ra_acc_cap_len = *cur++;
 | 
						ms_ra_acc_cap_len = *cur++;
 | 
				
			||||||
	ms_ra_acc_cap = cur;
 | 
						ms_ra_acc_cap = cur;
 | 
				
			||||||
	if (ms_ra_acc_cap_len > 51)
 | 
						if (ms_ra_acc_cap_len > 52)
 | 
				
			||||||
		goto err_inval;
 | 
							goto err_inval;
 | 
				
			||||||
 | 
						cur += ms_ra_acc_cap_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
 | 
						/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -735,8 +736,10 @@ static int gsm48_rx_gmm_att_req(struct sgsn_mm_ctx *ctx, struct msgb *msg,
 | 
				
			|||||||
	ctx->cell_id = cid;
 | 
						ctx->cell_id = cid;
 | 
				
			||||||
	/* Update MM Context with other data */
 | 
						/* Update MM Context with other data */
 | 
				
			||||||
	ctx->drx_parms = drx_par;
 | 
						ctx->drx_parms = drx_par;
 | 
				
			||||||
	ctx->ms_radio_access_capa.len = ms_ra_acc_cap_len;
 | 
						ctx->ms_radio_access_capa.len = OSMO_MIN(ms_ra_acc_cap_len,
 | 
				
			||||||
	memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap, ms_ra_acc_cap_len);
 | 
										 sizeof((ctx->ms_radio_access_capa.buf)));
 | 
				
			||||||
 | 
						memcpy(ctx->ms_radio_access_capa.buf, ms_ra_acc_cap,
 | 
				
			||||||
 | 
							ctx->ms_radio_access_capa.len);
 | 
				
			||||||
	ctx->ms_network_capa.len = msnc_len;
 | 
						ctx->ms_network_capa.len = msnc_len;
 | 
				
			||||||
	memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
 | 
						memcpy(ctx->ms_network_capa.buf, msnc, msnc_len);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -910,6 +913,9 @@ static int gsm48_rx_gmm_ra_upd_req(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
 | 
				
			|||||||
	/* MS Radio Access Capability 10.5.5.12a */
 | 
						/* MS Radio Access Capability 10.5.5.12a */
 | 
				
			||||||
	ms_ra_acc_cap_len = *cur++;
 | 
						ms_ra_acc_cap_len = *cur++;
 | 
				
			||||||
	ms_ra_acc_cap = cur;
 | 
						ms_ra_acc_cap = cur;
 | 
				
			||||||
 | 
						if (ms_ra_acc_cap_len > 52)
 | 
				
			||||||
 | 
							return gsm48_tx_gmm_ra_upd_rej(msg, GMM_CAUSE_PROTO_ERR_UNSPEC);
 | 
				
			||||||
 | 
						cur += ms_ra_acc_cap_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
 | 
						/* Optional: Old P-TMSI Signature, Requested READY timer, TMSI Status,
 | 
				
			||||||
	 * DRX parameter, MS network capability */
 | 
						 * DRX parameter, MS network capability */
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user