From 14ff9255553f42bada7b042945e86d6b575b28b2 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 27 Mar 2014 09:19:24 +0100 Subject: agch/pcu: Fix crash for AGCH commands queued by the PCU The dequeue code assumed that msg->l3h is a valid pointer but in the case of the PCU socket it was a null pointer. This lead to memcpy copying a lot more than 23 bytes which ultimately lead to a crash. The issue was introduced in the git commits 37c332e5bfdb9591a1cd3cc6746afffdb1cd13b9 and the commit d290ee029a827c870f97372b98f0dbd7d057402a. use msg->l3h = msgb_put(msg, len) to make sure that there is a valid L3 pointer for the message. (gdb) bt #0 0x419d6384 in memcpy () from /tmp/ow/lib/libc.so.6 #1 0x0001894c in bts_ccch_copy_msg (bts=0x62248, out_buf=0x62248 "p\025\003", gt=0x1, is_ag_res=100684) at bts.c:572 #2 0x0000c958 in handle_ph_readytosend_ind (rts_ind=, fl1=0x62e78) at l1_if.c:515 #3 l1if_handle_ind (fl1=0x62e78, msg=0x8bb08) at l1_if.c:920 #4 0x000147e8 in read_dispatch_one (queue=, msg=0x8bb08, fl1h=) at l1_transp_hw.c:190 #5 l1if_fd_cb (ofd=0x62f04, what=) at l1_transp_hw.c:224 #6 0x41b9d028 in osmo_select_main (polling=) at select.c:158 #7 0x0000b204 in main (argc=, argv=) at main.c:384 (gdb) p *msg $12 = {list = {next = 0x100100, prev = 0x200200}, {dst = 0x0, trx = 0x0}, lchan = 0x0, l1h = 0x0, l2h = 0x0, l3h = 0x0, l4h = 0x0, cb = {0, 0, 0, 0, 0}, data_len = 23, len = 23, head = 0x8572c "-\006?\020\r\340*q\224#", tail = 0x85743 "", data = 0x8572c "-\006?\020\r\340*q\224#", _data = 0x8572c "-\006?\020\r\340*q\224#"} --- src/common/pcu_sock.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/common/pcu_sock.c') diff --git a/src/common/pcu_sock.c b/src/common/pcu_sock.c index bd89da2f..a978e469 100644 --- a/src/common/pcu_sock.c +++ b/src/common/pcu_sock.c @@ -494,7 +494,8 @@ static int pcu_rx_data_req(struct gsm_bts *bts, uint8_t msg_type, rc = -ENOMEM; break; } - memcpy(msgb_put(msg, data_req->len), data_req->data, data_req->len); + msg->l3h = msgb_put(msg, data_req->len); + memcpy(msg->l3h, data_req->data, data_req->len); if (bts_agch_enqueue(bts, msg) < 0) { msgb_free(msg); rc = -EIO; -- cgit v1.2.3