aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bsc/pcu_sock.c
diff options
context:
space:
mode:
authorPhilipp Maier <pmaier@sysmocom.de>2022-09-15 12:03:43 +0200
committerPhilipp Maier <pmaier@sysmocom.de>2022-09-26 12:53:11 +0200
commit797378af74e899eec6fd87102ca104bc7da3a722 (patch)
tree8ff3b15e718f020ac877935dfddb6ebb38493727 /src/osmo-bsc/pcu_sock.c
parent9573ccbe2b04b37cd857841d26c578b037eb77cb (diff)
pcu_sock: check size of primitive
The pcu_sock interface in osmo-bts does check the size of the primitives it receives. Lets do the same in osmo-bsc as well. Change-Id: I247c6f4b5a7a22d17a060a558c4ceb9221ca7351 Related: OS#5198
Diffstat (limited to 'src/osmo-bsc/pcu_sock.c')
-rw-r--r--src/osmo-bsc/pcu_sock.c21
1 files changed, 19 insertions, 2 deletions
diff --git a/src/osmo-bsc/pcu_sock.c b/src/osmo-bsc/pcu_sock.c
index 2cf1ab5d2..1af9a9db6 100644
--- a/src/osmo-bsc/pcu_sock.c
+++ b/src/osmo-bsc/pcu_sock.c
@@ -448,8 +448,17 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type,
return rc;
}
+#define CHECK_IF_MSG_SIZE(prim_len, prim_msg) \
+ do { \
+ size_t _len = PCUIF_HDR_SIZE + sizeof(prim_msg); \
+ if (prim_len < _len) { \
+ LOGP(DPCU, LOGL_ERROR, "Received %zu bytes on PCU Socket, but primitive %s " \
+ "size is %zu, discarding\n", prim_len, #prim_msg, _len); \
+ return -EINVAL; \
+ } \
+ } while (0)
static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
- struct gsm_pcu_if *pcu_prim)
+ struct gsm_pcu_if *pcu_prim, size_t prim_len)
{
int rc = 0;
struct gsm_bts *bts;
@@ -460,6 +469,7 @@ static int pcu_rx(struct gsm_network *net, uint8_t msg_type,
switch (msg_type) {
case PCU_IF_MSG_DATA_REQ:
case PCU_IF_MSG_PAG_REQ:
+ CHECK_IF_MSG_SIZE(prim_len, pcu_prim->u.data_req);
rc = pcu_rx_data_req(bts, msg_type, &pcu_prim->u.data_req);
break;
default:
@@ -574,7 +584,14 @@ static int pcu_sock_read(struct osmo_fd *bfd)
goto close;
}
- rc = pcu_rx(state->net, pcu_prim->msg_type, pcu_prim);
+ if (rc < PCUIF_HDR_SIZE) {
+ LOGP(DPCU, LOGL_ERROR, "Received %d bytes on PCU Socket, but primitive hdr size "
+ "is %zu, discarding\n", rc, PCUIF_HDR_SIZE);
+ msgb_free(msg);
+ return 0;
+ }
+
+ rc = pcu_rx(state->net, pcu_prim->msg_type, pcu_prim, rc);
/* as we always synchronously process the message in pcu_rx() and
* its callbacks, we can free the message here. */