diff options
author | Philipp Maier <pmaier@sysmocom.de> | 2022-09-15 12:03:43 +0200 |
---|---|---|
committer | Philipp Maier <pmaier@sysmocom.de> | 2022-09-26 12:53:11 +0200 |
commit | 797378af74e899eec6fd87102ca104bc7da3a722 (patch) | |
tree | 8ff3b15e718f020ac877935dfddb6ebb38493727 /src/osmo-bsc/pcu_sock.c | |
parent | 9573ccbe2b04b37cd857841d26c578b037eb77cb (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.c | 21 |
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. */ |