summaryrefslogtreecommitdiffstats
path: root/src/host
diff options
context:
space:
mode:
authorVadim Yanitskiy <axilirator@gmail.com>2018-10-03 07:14:16 +0700
committerVadim Yanitskiy <axilirator@gmail.com>2018-10-03 19:46:25 +0700
commit1a892eeb2a7e7de0c9946cc73b01f569043af4e7 (patch)
treea9eca99cadc848e1b9be59105e7aa8e1cb8f9c2d /src/host
parent7bf8aea33a6ea3300452a5c67f91ba320602e8c2 (diff)
layer23/l1ctl.c: clean up & fix message length checking
Almost all handlers for received L1CTL messages are also affected by the bug fixed in I7fe2e00bb45ba07c9bb7438445eededfa09c96f3. In short, they do verify the length of 'msg->l2h' or 'msg->l3h', but not the 'msg->l1h'. Let's fix this, and also add missing checks. Change-Id: I866bb5d97a1cc1b6cb887877bb444b9e3dca977a
Diffstat (limited to 'src/host')
-rw-r--r--src/host/layer23/src/common/l1ctl.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/src/host/layer23/src/common/l1ctl.c b/src/host/layer23/src/common/l1ctl.c
index 642cde85..6f4a6d8e 100644
--- a/src/host/layer23/src/common/l1ctl.c
+++ b/src/host/layer23/src/common/l1ctl.c
@@ -83,9 +83,9 @@ static int rx_l1_fbsb_conf(struct osmocom_ms *ms, struct msgb *msg)
struct gsm_time tm;
struct osmobb_fbsb_res fr;
- if (msgb_l3len(msg) < sizeof(*dl) + sizeof(*sb)) {
- LOGP(DL1C, LOGL_ERROR, "FBSB RESP: MSG too short %u\n",
- msgb_l3len(msg));
+ if (msgb_l1len(msg) < (sizeof(*dl) + sizeof(*sb))) {
+ LOGP(DL1C, LOGL_ERROR, "FBSB RESP: MSG too short (len=%u), "
+ "missing UL info header and/or payload\n", msgb_l1len(msg));
return -1;
}
@@ -121,9 +121,9 @@ static int rx_l1_rach_conf(struct osmocom_ms *ms, struct msgb *msg)
struct osmo_phsap_prim pp;
struct l1ctl_info_dl *dl;
- if (msgb_l2len(msg) < sizeof(*dl)) {
- LOGP(DL1C, LOGL_ERROR, "RACH CONF: MSG too short %u\n",
- msgb_l3len(msg));
+ if (msgb_l1len(msg) < sizeof(*dl)) {
+ LOGP(DL1C, LOGL_ERROR, "RACH CONF MSG too short "
+ "(len=%u), missing DL info header\n", msgb_l1len(msg));
msgb_free(msg);
return -1;
}
@@ -150,9 +150,9 @@ static int rx_ph_data_ind(struct osmocom_ms *ms, struct msgb *msg)
uint8_t gsmtap_chan_type;
struct gsm_time tm;
- if (msgb_l3len(msg) < sizeof(*ccch)) {
- LOGP(DL1C, LOGL_ERROR, "MSG too short Data Ind: %u\n",
- msgb_l3len(msg));
+ if (msgb_l1len(msg) < sizeof(*dl)) {
+ LOGP(DL1C, LOGL_ERROR, "DATA IND MSG too short (len=%u), "
+ "missing UL info header\n", msgb_l1len(msg));
msgb_free(msg);
return -1;
}
@@ -260,6 +260,13 @@ static int rx_ph_data_conf(struct osmocom_ms *ms, struct msgb *msg)
struct l1ctl_info_dl *dl = (struct l1ctl_info_dl *) msg->l1h;
struct lapdm_entity *le;
+ if (msgb_l1len(msg) < sizeof(*dl)) {
+ LOGP(DL1C, LOGL_ERROR, "DATA CONF MSG too short (len=%u), "
+ "missing UL info header\n", msgb_l1len(msg));
+ msgb_free(msg);
+ return -1;
+ }
+
osmo_prim_init(&pp.oph, SAP_GSM_PH, PRIM_PH_RTS,
PRIM_OP_INDICATION, msg);
@@ -284,14 +291,12 @@ int l1ctl_tx_data_req(struct osmocom_ms *ms, struct msgb *msg,
DEBUGP(DL1C, "(%s)\n", osmo_hexdump(msg->l2h, msgb_l2len(msg)));
- if (msgb_l2len(msg) > 23) {
- LOGP(DL1C, LOGL_ERROR, "L1 cannot handle message length "
- "> 23 (%u)\n", msgb_l2len(msg));
+ if (msgb_l2len(msg) != 23) {
+ LOGP(DL1C, LOGL_ERROR, "Wrong message length (len=%u), "
+ "DATA REQ ignored, please fix!\n", msgb_l2len(msg));
msgb_free(msg);
return -EINVAL;
- } else if (msgb_l2len(msg) < 23)
- LOGP(DL1C, LOGL_ERROR, "L1 message length < 23 (%u) "
- "doesn't seem right!\n", msgb_l2len(msg));
+ }
/* send copy via GSMTAP */
rsl_dec_chan_nr(chan_nr, &chan_type, &chan_ss, &chan_ts);
@@ -702,6 +707,12 @@ static int rx_l1_pm_conf(struct osmocom_ms *ms, struct msgb *msg)
{
struct l1ctl_pm_conf *pmr;
+ if (msgb_l1len(msg) < sizeof(*pmr)) {
+ LOGP(DL1C, LOGL_ERROR, "PM CONF MSG too short (len=%u), "
+ "missing measurement results\n", msgb_l1len(msg));
+ return -1;
+ }
+
for (pmr = (struct l1ctl_pm_conf *) msg->l1h;
(uint8_t *) pmr < msg->tail; pmr++) {
struct osmobb_meas_res mr;
@@ -721,9 +732,9 @@ static int rx_l1_ccch_mode_conf(struct osmocom_ms *ms, struct msgb *msg)
struct osmobb_ccch_mode_conf mc;
struct l1ctl_ccch_mode_conf *conf;
- if (msgb_l3len(msg) < sizeof(*conf)) {
- LOGP(DL1C, LOGL_ERROR, "CCCH MODE CONF: MSG too short %u\n",
- msgb_l3len(msg));
+ if (msgb_l1len(msg) < sizeof(*conf)) {
+ LOGP(DL1C, LOGL_ERROR, "CCCH MODE CONF: MSG too short "
+ "(len=%u), missing CCCH mode info\n", msgb_l1len(msg));
return -1;
}
@@ -744,9 +755,9 @@ static int rx_l1_tch_mode_conf(struct osmocom_ms *ms, struct msgb *msg)
struct osmobb_tch_mode_conf mc;
struct l1ctl_tch_mode_conf *conf;
- if (msgb_l3len(msg) < sizeof(*conf)) {
- LOGP(DL1C, LOGL_ERROR, "TCH MODE CONF: MSG too short %u\n",
- msgb_l3len(msg));
+ if (msgb_l1len(msg) < sizeof(*conf)) {
+ LOGP(DL1C, LOGL_ERROR, "TCH MODE CONF: MSG too short "
+ "(len=%u), missing TCH mode info\n", msgb_l1len(msg));
return -1;
}
@@ -768,6 +779,12 @@ static int rx_l1_traffic_ind(struct osmocom_ms *ms, struct msgb *msg)
struct l1ctl_info_dl *dl;
struct l1ctl_traffic_ind *ti;
+ if (msgb_l1len(msg) < sizeof(*dl)) {
+ LOGP(DL1C, LOGL_ERROR, "TRAFFIC IND MSG too short "
+ "(len=%u), missing DL info header\n", msgb_l1len(msg));
+ return -1;
+ }
+
/* Header handling */
dl = (struct l1ctl_info_dl *) msg->l1h;
msg->l2h = dl->payload;
@@ -854,6 +871,12 @@ static int rx_l1_neigh_pm_ind(struct osmocom_ms *ms, struct msgb *msg)
{
struct l1ctl_neigh_pm_ind *pm_ind;
+ if (msgb_l1len(msg) < sizeof(*pm_ind)) {
+ LOGP(DL1C, LOGL_ERROR, "NEIGH PH IND MSG too short "
+ "(len=%u), missing measurement results\n", msgb_l1len(msg));
+ return -1;
+ }
+
for (pm_ind = (struct l1ctl_neigh_pm_ind *) msg->l1h;
(uint8_t *) pm_ind < msg->tail; pm_ind++) {
struct osmobb_neigh_pm_ind mi;