osmo-bsc/src/osmo-bsc/osmo_bsc_filter.c

151 lines
4.1 KiB
C
Raw Normal View History

/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
* (C) 2009-2011 by On-Waves
* All Rights Reserved
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
#include <osmocom/gsm/gsm48.h>
#include <osmocom/bsc/osmo_bsc.h>
#include <osmocom/bsc/bsc_msc_data.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/bsc_subscriber.h>
#include <osmocom/bsc/debug.h>
#include <osmocom/bsc/paging.h>
#include <osmocom/bsc/gsm_04_08_rr.h>
#include <osmocom/bsc/bts.h>
#include <stdlib.h>
static int bsc_patch_mm_info(struct gsm_subscriber_connection *conn,
uint8_t *data, unsigned int length)
{
struct tlv_parsed tp;
int parse_res;
int tzunits;
uint8_t tzbsd = 0;
uint8_t dst = 0;
/* Is TZ patching enabled? */
struct gsm_tz *tz = &conn->network->tz;
if (!tz->override)
return 0;
parse_res = tlv_parse(&tp, &gsm48_mm_att_tlvdef, data, length, 0, 0);
if (parse_res <= 0 && parse_res != -3)
2016-02-29 08:35:54 +00:00
/* FIXME: -3 means unknown IE error, so this accepts messages
* with unknown IEs. But parsing has aborted with the unknown
* IE and the message is broken or parsed incompletely. */
return 0;
/* Convert tz.hr and tz.mn to units */
if (tz->hr < 0) {
tzunits = -tz->hr*4;
tzbsd |= 0x08;
} else
tzunits = tz->hr*4;
tzunits = tzunits + (tz->mn/15);
tzbsd |= (tzunits % 10)*0x10 + (tzunits / 10);
/* Convert DST value */
if (tz->dst >= 0 && tz->dst <= 2)
dst = tz->dst;
if (TLVP_PRESENT(&tp, GSM48_IE_UTC)) {
LOGP(DMSC, LOGL_DEBUG,
"Changing 'Local time zone' from 0x%02x to 0x%02x.\n",
TLVP_VAL(&tp, GSM48_IE_UTC)[6], tzbsd);
((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_UTC)))[0] = tzbsd;
}
if (TLVP_PRESENT(&tp, GSM48_IE_NET_TIME_TZ)) {
LOGP(DMSC, LOGL_DEBUG,
"Changing 'Universal time and local time zone' TZ from "
"0x%02x to 0x%02x.\n",
TLVP_VAL(&tp, GSM48_IE_NET_TIME_TZ)[6], tzbsd);
((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_NET_TIME_TZ)))[6] = tzbsd;
}
#ifdef GSM48_IE_NET_DST
if (TLVP_PRESENT(&tp, GSM48_IE_NET_DST)) {
LOGP(DMSC, LOGL_DEBUG,
"Changing 'Network daylight saving time' from "
"0x%02x to 0x%02x.\n",
TLVP_VAL(&tp, GSM48_IE_NET_DST)[0], dst);
((uint8_t *)(TLVP_VAL(&tp, GSM48_IE_NET_DST)))[0] = dst;
}
#endif
return 0;
}
static int has_core_identity(struct bsc_msc_data *msc)
{
if (msc->core_plmn.mnc != GSM_MCC_MNC_INVALID)
return 1;
if (msc->core_plmn.mcc != GSM_MCC_MNC_INVALID)
return 1;
if (msc->core_lac != -1)
return 1;
if (msc->core_ci != -1)
return 1;
return 0;
}
/**
* Messages coming back from the MSC.
*/
int bsc_scan_msc_msg(struct gsm_subscriber_connection *conn, struct msgb *msg)
{
struct bsc_msc_data *msc;
struct gsm48_loc_area_id *lai;
struct gsm48_hdr *gh;
uint8_t pdisc;
uint8_t mtype;
int length = msgb_l3len(msg);
if (length < sizeof(*gh)) {
LOGP(DMSC, LOGL_ERROR, "GSM48 header does not fit.\n");
return -1;
}
gh = (struct gsm48_hdr *) msgb_l3(msg);
length -= (const char *)&gh->data[0] - (const char *)gh;
pdisc = gsm48_hdr_pdisc(gh);
if (pdisc != GSM48_PDISC_MM)
return 0;
mtype = gsm48_hdr_msg_type(gh);
msc = conn->sccp.msc;
if (mtype == GSM48_MT_MM_LOC_UPD_ACCEPT) {
fix crashes due to OSMO_ASSERT(conn->lchan) Starting from ttcn3-bsc-test-sccplite build #777, it was noticed that osmo-bsc crashes with the following message: Assert failed conn->lchan include/osmocom/bsc/gsm_data.h:1376 The cause of this is a recently merged patch that calls conn_get_bts() during assignment_fsm rate counter dispatch: "Count assignment rates per BTS as well" commit b5ccf09fc4042c7fb1fdaaa6263961c40b32564e Change-Id I0009e51d4caf68e762138d98e2e23d49acc3cc1a The root cause being that the assignment_fsm attempts to count an Assignment event for a BTS after the lchan has already been released and disassociated from the conn. The assertion is found in conn_get_bts(), which is used in various places. In fact, each caller is a potential DoS risk -- though most are in code paths that are guaranteed to have an lchan and bts present, having an OSMO_ASSERT() on the relatively volatile presence of an lchan is not a good idea for osmo-bsc's stability and error resilience. - Change conn_get_bts() to return NULL in the lack of an lchan. - Adjust all callers of conn_get_bts() to gracefully handle a NULL return val. - Same for cgi_for_msc() and callers, closely related. Here is a backtrace: Program received signal SIGABRT pwndbg> bt 0x0000555555be6e52 in conn_get_bts (conn=0x622000057160) at include/osmocom/bsc/gsm_data.h:1376 0x0000555555c1edc8 in assignment_fsm_timer_cb (fi=0x612000060220) at assignment_fsm.c:758 0x00007ffff72b1104 in fsm_tmr_cb (data=0x612000060220) at libosmocore/src/fsm.c:325 0x00007ffff72ab062 in osmo_timers_update () at libosmocore/src/timer.c:257 0x00007ffff72ab5d2 in _osmo_select_main (polling=0) at libosmocore/src/select.c:260 0x00007ffff72abd2f in osmo_select_main_ctx (polling=<optimized out>) at libosmocore/src/select.c:291 0x0000555555e1b81b in main (argc=3, argv=0x7fffffffe1b8) at osmo_bsc_main.c:953 0x00007ffff6752002 in __libc_start_main () from /usr/lib/libc.so.6 0x0000555555b61bbe in _start () In the case of the assignment_fsm counter, we now miss a chance to increase a BTS counter for a failed Assignment, but this is a separate problem. The main point of this patch is that osmo-bsc must not crash. Related: OS#4620, OS#4619 Patch-by: fixeria Tweaked-by: neels Fixes: I0009e51d4caf68e762138d98e2e23d49acc3cc1a Change-Id: Id681dfb0ad654bdb4b71805d1ad4f39a8bf6bbd1
2020-06-18 15:29:56 +00:00
struct gsm_bts *bts = conn_get_bts(conn);
if (bts && has_core_identity(msc)) {
if (msgb_l3len(msg) >= sizeof(*gh) + sizeof(*lai)) {
2016-02-29 08:40:22 +00:00
/* overwrite LAI in the message */
lai = (struct gsm48_loc_area_id *) &gh->data[0];
fix crashes due to OSMO_ASSERT(conn->lchan) Starting from ttcn3-bsc-test-sccplite build #777, it was noticed that osmo-bsc crashes with the following message: Assert failed conn->lchan include/osmocom/bsc/gsm_data.h:1376 The cause of this is a recently merged patch that calls conn_get_bts() during assignment_fsm rate counter dispatch: "Count assignment rates per BTS as well" commit b5ccf09fc4042c7fb1fdaaa6263961c40b32564e Change-Id I0009e51d4caf68e762138d98e2e23d49acc3cc1a The root cause being that the assignment_fsm attempts to count an Assignment event for a BTS after the lchan has already been released and disassociated from the conn. The assertion is found in conn_get_bts(), which is used in various places. In fact, each caller is a potential DoS risk -- though most are in code paths that are guaranteed to have an lchan and bts present, having an OSMO_ASSERT() on the relatively volatile presence of an lchan is not a good idea for osmo-bsc's stability and error resilience. - Change conn_get_bts() to return NULL in the lack of an lchan. - Adjust all callers of conn_get_bts() to gracefully handle a NULL return val. - Same for cgi_for_msc() and callers, closely related. Here is a backtrace: Program received signal SIGABRT pwndbg> bt 0x0000555555be6e52 in conn_get_bts (conn=0x622000057160) at include/osmocom/bsc/gsm_data.h:1376 0x0000555555c1edc8 in assignment_fsm_timer_cb (fi=0x612000060220) at assignment_fsm.c:758 0x00007ffff72b1104 in fsm_tmr_cb (data=0x612000060220) at libosmocore/src/fsm.c:325 0x00007ffff72ab062 in osmo_timers_update () at libosmocore/src/timer.c:257 0x00007ffff72ab5d2 in _osmo_select_main (polling=0) at libosmocore/src/select.c:260 0x00007ffff72abd2f in osmo_select_main_ctx (polling=<optimized out>) at libosmocore/src/select.c:291 0x0000555555e1b81b in main (argc=3, argv=0x7fffffffe1b8) at osmo_bsc_main.c:953 0x00007ffff6752002 in __libc_start_main () from /usr/lib/libc.so.6 0x0000555555b61bbe in _start () In the case of the assignment_fsm counter, we now miss a chance to increase a BTS counter for a failed Assignment, but this is a separate problem. The main point of this patch is that osmo-bsc must not crash. Related: OS#4620, OS#4619 Patch-by: fixeria Tweaked-by: neels Fixes: I0009e51d4caf68e762138d98e2e23d49acc3cc1a Change-Id: Id681dfb0ad654bdb4b71805d1ad4f39a8bf6bbd1
2020-06-18 15:29:56 +00:00
gsm48_generate_lai2(lai, bts_lai(bts));
}
}
return 0;
} else if (mtype == GSM48_MT_MM_INFO) {
bsc_patch_mm_info(conn, &gh->data[0], length);
}
return 0;
}