i had that patch done already. (see attachment)
what was the message id? I didn't see it.
Could you please answer this one?
hi holger,
sorry, i did not express myself well enough. i meant that i already
wrote the patch, but did not send it to the mailing list.
This lacks input validation. The code needs to check that the data
we read is within the bounds of the msgb and the data we write is within
the bounds too.
i added a check that limits the GSM frames to 33 octets (full speech).
(AMR requires only 31 octets + 1 octet length indicator.) an MNCC
message has much larger msgb allocation when received. see attachment.
best regards
andreas
>From 9175347f5a357317feba67e82b4ff3bc3aca5baf Mon Sep 17 00:00:00 2001
From: Andreas Eversberg <[email protected]>
Date: Thu, 8 Mar 2012 14:39:19 +0100
Subject: [PATCH] Add support for AMR frames to MNCC/RTP interface
AMR rate is currently fixed to 5.9k.
---
openbsc/src/libmsc/gsm_04_08.c | 1 +
openbsc/src/libtrau/rtp_proxy.c | 53 ++++++++++++++++++++++++++++++++++++-----
2 files changed, 48 insertions(+), 6 deletions(-)
diff --git a/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index df93433..a0650ab 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/src/libmsc/gsm_04_08.c
@@ -2953,6 +2953,7 @@ int mncc_tx_to_cc(struct gsm_network *net, int msg_type, void *arg)
case GSM_TCHF_FRAME:
case GSM_TCHF_FRAME_EFR:
case GSM_TCHH_FRAME:
+ case GSM_TCH_FRAME_AMR:
/* Find callref */
trans = trans_find_by_callref(net, data->callref);
if (!trans) {
diff --git a/openbsc/src/libtrau/rtp_proxy.c b/openbsc/src/libtrau/rtp_proxy.c
index 143bfa0..95729ef 100644
--- a/openbsc/src/libtrau/rtp_proxy.c
+++ b/openbsc/src/libtrau/rtp_proxy.c
@@ -192,21 +192,41 @@ static int rtp_decode(struct msgb *msg, uint32_t callref, struct msgb **data)
return -EINVAL;
}
break;
+ case RTP_PT_AMR:
+ break;
default:
DEBUGPC(DLMUX, "received RTP frame with unknown payload "
"type %d\n", rtph->payload_type);
return -EINVAL;
}
- new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + payload_len,
- "GSM-DATA");
+ if (payload_len > 33) {
+ DEBUGPC(DLMUX, "RTP payload too large (%d octets)\n",
+ payload_len);
+ return -EINVAL;
+ }
+
+ if (rtph->payload_type == RTP_PT_AMR) {
+ new_msg = msgb_alloc(sizeof(struct gsm_data_frame) + 1
+ + payload_len, "GSM-DATA (AMR)");
+ } else {
+ new_msg = msgb_alloc(sizeof(struct gsm_data_frame)
+ + payload_len, "GSM-DATA");
+ }
if (!new_msg)
return -ENOMEM;
frame = (struct gsm_data_frame *)(new_msg->data);
frame->msg_type = msg_type;
frame->callref = callref;
- memcpy(frame->data, payload, payload_len);
- msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len);
+ if (rtph->payload_type == RTP_PT_AMR) {
+ frame->data[0] = payload_len;
+ msgb_put(new_msg, sizeof(struct gsm_data_frame) + 1
+ + payload_len);
+ memcpy(frame->data + 1, payload, payload_len);
+ } else {
+ msgb_put(new_msg, sizeof(struct gsm_data_frame) + payload_len);
+ memcpy(frame->data, payload, payload_len);
+ }
*data = new_msg;
return 0;
@@ -264,6 +284,11 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
payload_len = RTP_LEN_GSM_HALF;
duration = RTP_GSM_DURATION;
break;
+ case GSM_TCH_FRAME_AMR:
+ payload_type = RTP_PT_AMR;
+ payload_len = frame->data[0];
+ duration = RTP_GSM_DURATION;
+ break;
default:
DEBUGPC(DLMUX, "unsupported message type %d\n",
frame->msg_type);
@@ -291,7 +316,18 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
}
}
- msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len, "RTP-GSM-FULL");
+ if (payload_len > 33) {
+ DEBUGPC(DLMUX, "RTP payload too large (%d octets)\n",
+ payload_len);
+ return -EINVAL;
+ }
+
+ if (frame->msg_type == GSM_TCH_FRAME_AMR)
+ msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len,
+ "RTP-GSM (AMR)");
+ else
+ msg = msgb_alloc(sizeof(struct rtp_hdr) + payload_len,
+ "RTP-GSM");
if (!msg)
return -ENOMEM;
rtph = (struct rtp_hdr *)msg->data;
@@ -305,7 +341,12 @@ int rtp_send_frame(struct rtp_socket *rs, struct gsm_data_frame *frame)
rtph->timestamp = htonl(rs->transmit.timestamp);
rs->transmit.timestamp += duration;
rtph->ssrc = htonl(rs->transmit.ssrc);
- memcpy(msg->data + sizeof(struct rtp_hdr), frame->data, payload_len);
+ if (frame->msg_type == GSM_TCH_FRAME_AMR)
+ memcpy(msg->data + sizeof(struct rtp_hdr), frame->data + 1,
+ payload_len);
+ else
+ memcpy(msg->data + sizeof(struct rtp_hdr), frame->data,
+ payload_len);
msgb_put(msg, sizeof(struct rtp_hdr) + payload_len);
msgb_enqueue(&rss->tx_queue, msg);
rss->bfd.when |= BSC_FD_WRITE;
--
1.8.1.5