From 8911cef81db03c6d3b3f6b7361a56538f8b2dd5c Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 1 Jul 2010 19:56:19 +0200 Subject: [PATCH] [SGSN] Fix segfault when passing re-assembled SN-PDU to GMM sgsn_rx_sndcp_ud_ind() can no longer make the assumption that msgb_bcid() is valid, as this is only true for an un-fragmented SN-PDU. So instead, we now store the RAID in the SNDCP Entity and pass it as an explicit argument to sgsn_rx_sndcp_ud_ind(). --- openbsc/include/openbsc/sgsn.h | 4 ++-- openbsc/src/gprs/gprs_sndcp.c | 8 +++++--- openbsc/src/gprs/gprs_sndcp.h | 2 ++ openbsc/src/gprs/sgsn_libgtp.c | 8 +++----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/openbsc/include/openbsc/sgsn.h b/openbsc/include/openbsc/sgsn.h index eccfdeaa6..84db87e91 100644 --- a/openbsc/include/openbsc/sgsn.h +++ b/openbsc/include/openbsc/sgsn.h @@ -57,8 +57,8 @@ int sndcp_sm_activate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); /* Entry point for the SNSM-DEACTIVATE.indication */ int sndcp_sm_deactivate_ind(struct gprs_llc_lle *lle, uint8_t nsapi); /* Called by SNDCP when it has received/re-assembled a N-PDU */ -int sgsn_rx_sndcp_ud_ind(uint32_t tlli, uint8_t nsapi, struct msgb *msg, - uint32_t npdu_len, uint8_t *npdu); +int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, + struct msgb *msg, uint32_t npdu_len, uint8_t *npdu); int sndcp_unitdata_req(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t nsapi, void *mmcontext); diff --git a/openbsc/src/gprs/gprs_sndcp.c b/openbsc/src/gprs/gprs_sndcp.c index b352aeb9b..6e2d31421 100644 --- a/openbsc/src/gprs/gprs_sndcp.c +++ b/openbsc/src/gprs/gprs_sndcp.c @@ -170,8 +170,8 @@ static int defrag_segments(struct gprs_sndcp_entity *sne) /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(sne->lle->llme->tlli, sne->nsapi, msg, - sne->defrag.tot_len, npdu); + return sgsn_rx_sndcp_ud_ind(&sne->ra_id, sne->lle->llme->tlli, + sne->nsapi, msg, sne->defrag.tot_len, npdu); } static int defrag_input(struct gprs_sndcp_entity *sne, struct msgb *msg, uint8_t *hdr) @@ -517,6 +517,8 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t *hd lle->llme->tlli, lle->sapi, sch->nsapi); return -EIO; } + /* FIXME: move this RA_ID up to the LLME or even higher */ + bssgp_parse_cell_id(&sne->ra_id, msgb_bcid(msg)); if (!sch->first || sch->more) { #if 0 @@ -542,7 +544,7 @@ int sndcp_llunitdata_ind(struct msgb *msg, struct gprs_llc_lle *lle, uint8_t *hd } /* actually send the N-PDU to the SGSN core code, which then * hands it off to the correct GTP tunnel + GGSN via gtp_data_req() */ - return sgsn_rx_sndcp_ud_ind(lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); + return sgsn_rx_sndcp_ud_ind(&sne->ra_id, lle->llme->tlli, sne->nsapi, msg, npdu_len, npdu); } /* Section 5.1.2.1 LL-RESET.ind */ diff --git a/openbsc/src/gprs/gprs_sndcp.h b/openbsc/src/gprs/gprs_sndcp.h index 6c7c83465..e9a50be1c 100644 --- a/openbsc/src/gprs/gprs_sndcp.h +++ b/openbsc/src/gprs/gprs_sndcp.h @@ -33,6 +33,8 @@ enum sndcp_rx_state { struct gprs_sndcp_entity { struct llist_head list; + /* FIXME: move this RA_ID up to the LLME or even higher */ + struct gprs_ra_id ra_id; /* reference to the LLC Entity below this SNDCP entity */ struct gprs_llc_lle *lle; /* The NSAPI we shall use on top of LLC */ diff --git a/openbsc/src/gprs/sgsn_libgtp.c b/openbsc/src/gprs/sgsn_libgtp.c index ed15bbec4..09bdcc49a 100644 --- a/openbsc/src/gprs/sgsn_libgtp.c +++ b/openbsc/src/gprs/sgsn_libgtp.c @@ -419,16 +419,14 @@ static int cb_data_ind(struct pdp_t *lib, void *packet, unsigned int len) } /* Called by SNDCP when it has received/re-assembled a N-PDU */ -int sgsn_rx_sndcp_ud_ind(uint32_t tlli, uint8_t nsapi, struct msgb *msg, - uint32_t npdu_len, uint8_t *npdu) +int sgsn_rx_sndcp_ud_ind(struct gprs_ra_id *ra_id, int32_t tlli, uint8_t nsapi, + struct msgb *msg, uint32_t npdu_len, uint8_t *npdu) { struct sgsn_mm_ctx *mmctx; struct sgsn_pdp_ctx *pdp; - struct gprs_ra_id ra_id; /* look-up the MM context for this message */ - bssgp_parse_cell_id(&ra_id, msgb_bcid(msg)); - mmctx = sgsn_mm_ctx_by_tlli(tlli, &ra_id); + mmctx = sgsn_mm_ctx_by_tlli(tlli, ra_id); if (!mmctx) { LOGP(DGPRS, LOGL_ERROR, "Cannot find MM CTX for TLLI %08x\n", tlli);