summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2018-08-09 21:32:50 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2018-08-09 21:32:50 +0200
commit61ad1ba7ac9d90ed156f34c625933d64e9e75bf9 (patch)
tree6cace82ce0a611dc74a4668d5b6a87e69fbc7525
parentcb17fcff69460f466ca133d229d7bf9ea317cbce (diff)
parente3a75df62393a799ee17bfc5e058c89acda7e477 (diff)
Merge tag 'upstream/0.5.1'
Upstream version 0.5.1
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am4
-rw-r--r--src/e1_input.c47
-rw-r--r--src/input/ipaccess.c29
-rw-r--r--src/trau/osmo_ortp.c5
5 files changed, 63 insertions, 28 deletions
diff --git a/configure.ac b/configure.ac
index 0aca550..54d79f8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -59,9 +59,9 @@ AC_SUBST(SYMBOL_VISIBILITY)
dnl Generate the output
AM_CONFIG_HEADER(config.h)
-PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.11.0)
-PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.11.0)
-PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.11.0)
+PKG_CHECK_MODULES(LIBOSMOCORE, libosmocore >= 0.12.0)
+PKG_CHECK_MODULES(LIBOSMOVTY, libosmovty >= 0.12.0)
+PKG_CHECK_MODULES(LIBOSMOGSM, libosmogsm >= 0.12.0)
PKG_CHECK_MODULES(ORTP, ortp >= 0.22.0)
AC_CHECK_HEADERS(dahdi/user.h,,AC_MSG_WARN(DAHDI input driver will not be built))
diff --git a/src/Makefile.am b/src/Makefile.am
index ab42d38..eb2b572 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,8 +1,8 @@
# This is _NOT_ the library release version, it's an API version.
# Please read chapter "Library interface versions" of the libtool documentation
# before making any modifications: https://www.gnu.org/software/libtool/manual/html_node/Versioning.html
-ABIS_LIBVERSION=6:0:0
-TRAU_LIBVERSION=3:0:1
+ABIS_LIBVERSION=6:1:0
+TRAU_LIBVERSION=3:1:1
AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(top_builddir)
AM_CFLAGS= -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) $(LIBOSMOVTY_CFLAGS) $(COVERAGE_CFLAGS)
diff --git a/src/e1_input.c b/src/e1_input.c
index 29ba440..4717830 100644
--- a/src/e1_input.c
+++ b/src/e1_input.c
@@ -58,13 +58,13 @@ static void *tall_sigl_ctx;
static const struct rate_ctr_desc e1inp_ctr_d[] = {
[E1I_CTR_HDLC_ABORT] = {
- "hdlc.abort", "HDLC abort"
+ "hdlc:abort", "HDLC abort"
},
[E1I_CTR_HDLC_BADFCS] = {
- "hdlc.bad_fcs", "HLDC Bad FCS"
+ "hdlc:bad_fcs", "HLDC Bad FCS"
},
[E1I_CTR_HDLC_OVERR] = {
- "hdlc.overrun", "HDLC Overrun"
+ "hdlc:overrun", "HDLC Overrun"
},
[E1I_CTR_ALARM] = {
"alarm", "Alarm"
@@ -394,6 +394,25 @@ e1inp_line_clone(void *ctx, struct e1inp_line *line)
return NULL;
memcpy(clone, line, sizeof(struct e1inp_line));
+
+ if (line->name) {
+ clone->name = talloc_strdup(clone, line->name);
+ OSMO_ASSERT(clone->name);
+ }
+ if (line->sock_path) {
+ clone->sock_path = talloc_strdup(clone, line->sock_path);
+ OSMO_ASSERT(clone->sock_path);
+ }
+
+ /*
+ * Rate counters and driver data are shared between clones. These are pointers
+ * to dynamic memory so we use reference counting to avoid a double-free (see OS#3137).
+ */
+ OSMO_ASSERT(line->rate_ctr);
+ clone->rate_ctr = talloc_reference(clone, line->rate_ctr);
+ if (line->driver_data)
+ clone->driver_data = talloc_reference(clone, line->driver_data);
+
clone->refcnt = 1;
return clone;
}
@@ -406,8 +425,28 @@ void e1inp_line_get(struct e1inp_line *line)
void e1inp_line_put(struct e1inp_line *line)
{
line->refcnt--;
- if (line->refcnt == 0)
+ if (line->refcnt == 0) {
+ /* Remove our counter group from libosmocore's global counter
+ * list if we are freeing the last remaining talloc context.
+ * Otherwise we get a use-after-free when libosmocore's timer
+ * ticks again and attempts to update these counters (OS#3011).
+ *
+ * Note that talloc internally counts "secondary" references
+ * _in addition to_ the initial allocation context, so yes,
+ * we must check for *zero* remaining secondary contexts here. */
+ if (talloc_reference_count(line->rate_ctr) == 0) {
+ rate_ctr_group_free(line->rate_ctr);
+ } else {
+ /* We are not freeing the last talloc context.
+ * Instead of calling talloc_free(), unlink this 'line' pointer
+ * which serves as one of several talloc contexts for the rate
+ * counters and driver private state. */
+ talloc_unlink(line, line->rate_ctr);
+ if (line->driver_data)
+ talloc_unlink(line, line->driver_data);
+ }
talloc_free(line);
+ }
}
void
diff --git a/src/input/ipaccess.c b/src/input/ipaccess.c
index 9a80d8e..23eeda6 100644
--- a/src/input/ipaccess.c
+++ b/src/input/ipaccess.c
@@ -84,6 +84,8 @@ static int ipaccess_drop(struct osmo_fd *bfd, struct e1inp_line *line)
return ret;
}
+/* Returns -1 on error, and 0 or 1 on success. If -1 or 1 is returned, line has
+ * been released and should not be used anymore by the caller. */
static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
struct osmo_fd *bfd)
{
@@ -123,13 +125,11 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
if (ret < 0) {
LOGP(DLINP, LOGL_ERROR, "IPA response message "
"with malformed TLVs\n");
- ret = -EINVAL;
goto err;
}
if (!TLVP_PRESENT(&tlvp, IPAC_IDTAG_UNIT)) {
LOGP(DLINP, LOGL_ERROR, "IPA response message "
"without unit ID\n");
- ret = -EINVAL;
goto err;
}
@@ -137,7 +137,6 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
if (len < 1) {
LOGP(DLINP, LOGL_ERROR, "IPA response message "
"with too small unit ID\n");
- ret = -EINVAL;
goto err;
}
unitid = (char *) TLVP_VAL(&tlvp, IPAC_IDTAG_UNIT);
@@ -147,7 +146,6 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
if (!line->ops->sign_link_up) {
LOGP(DLINP, LOGL_ERROR,
"Unable to set signal link, closing socket.\n");
- ret = -EINVAL;
goto err;
}
/* the BSC creates the new sign links at this stage. */
@@ -159,7 +157,6 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
LOGP(DLINP, LOGL_ERROR,
"Unable to set signal link, "
"closing socket.\n");
- ret = -EINVAL;
goto err;
}
} else if (bfd->priv_nr == E1INP_SIGN_RSL) {
@@ -174,7 +171,6 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
LOGP(DLINP, LOGL_ERROR,
"Unable to set signal link, "
"closing socket.\n");
- ret = -EINVAL;
goto err;
}
/* this is a bugtrap, the BSC should be using the
@@ -194,7 +190,6 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
newbfd = &ts->driver.ipaccess.fd;
/* get rid of our old temporary bfd */
- memcpy(&newbfd->list, &bfd->list, sizeof(newbfd->list));
newbfd->fd = bfd->fd;
newbfd->when |= bfd->when; /* preserve 'newbfd->when' flags potentially set by sign_link_up() */
newbfd->cb = bfd->cb;
@@ -210,11 +205,11 @@ static int ipaccess_rcvmsg(struct e1inp_line *line, struct msgb *msg,
}
/* now we can release the dummy RSL line. */
e1inp_line_put(line);
+ return 1;
}
break;
default:
LOGP(DLINP, LOGL_ERROR, "Unknown IPA message type\n");
- ret = -EINVAL;
goto err;
}
return 0;
@@ -223,9 +218,10 @@ err:
close(bfd->fd);
bfd->fd = -1;
e1inp_line_put(line);
- return ret;
+ return -1;
}
+/* Returns -EBADF if bfd cannot be used by the caller anymore after return. */
static int handle_ts1_read(struct osmo_fd *bfd)
{
struct e1inp_line *line = bfd->data;
@@ -251,23 +247,21 @@ static int handle_ts1_read(struct osmo_fd *bfd)
hh = (struct ipaccess_head *) msg->data;
if (hh->proto == IPAC_PROTO_IPACCESS) {
- ipaccess_rcvmsg(line, msg, bfd);
+ ret = ipaccess_rcvmsg(line, msg, bfd);
+ /* BIG FAT WARNING: bfd might no longer exist here (ret != 0),
+ * since ipaccess_rcvmsg() might have free'd it !!! */
msgb_free(msg);
- return 0;
+ return ret != 0 ? -EBADF : 0;
} else if (e1i_ts->type == E1INP_TS_TYPE_NONE) {
/* this sign link is not know yet.. complain. */
LOGP(DLINP, LOGL_ERROR, "Timeslot is not configured.\n");
- ret = -EINVAL;
goto err_msg;
}
- /* BIG FAT WARNING: bfd might no longer exist here, since ipaccess_rcvmsg()
- * might have free'd it !!! */
link = e1inp_lookup_sign_link(e1i_ts, hh->proto, 0);
if (!link) {
LOGP(DLINP, LOGL_ERROR, "no matching signalling link for "
"hh->proto=0x%02x\n", hh->proto);
- ret = -EINVAL;
goto err_msg;
}
msg->dst = link;
@@ -276,7 +270,6 @@ static int handle_ts1_read(struct osmo_fd *bfd)
if (!e1i_ts->line->ops->sign_link) {
LOGP(DLINP, LOGL_ERROR, "Fix your application, "
"no action set for signalling messages.\n");
- ret = -EINVAL;
goto err_msg;
}
rc = e1i_ts->line->ops->sign_link(msg);
@@ -294,7 +287,7 @@ err_msg:
msgb_free(msg);
err:
ipaccess_drop(bfd, line);
- return ret;
+ return -EBADF;
}
static int ts_want_write(struct e1inp_ts *e1i_ts)
@@ -395,7 +388,7 @@ int ipaccess_fd_cb(struct osmo_fd *bfd, unsigned int what)
if (what & BSC_FD_READ)
rc = handle_ts1_read(bfd);
- if (what & BSC_FD_WRITE)
+ if (rc != -EBADF && (what & BSC_FD_WRITE))
rc = handle_ts1_write(bfd);
return rc;
diff --git a/src/trau/osmo_ortp.c b/src/trau/osmo_ortp.c
index 8ea05e4..d8f4abf 100644
--- a/src/trau/osmo_ortp.c
+++ b/src/trau/osmo_ortp.c
@@ -114,7 +114,8 @@ static void ortp_sig_cb_ssrc(RtpSession *rs, void *data)
uint32_t ssrc = rtp_session_get_recv_ssrc(rs);
LOGP(DLMIB, LOGL_INFO,
- "osmo-ortp(%d): ssrc_changed to 0x%08x\n", port, ssrc);
+ "osmo-ortp(%d): ssrc_changed to 0x%08x, resetting\n", port, ssrc);
+ rtp_session_reset(rs);
}
static void ortp_sig_cb_pt(RtpSession *rs, void *data)
@@ -370,6 +371,8 @@ struct osmo_rtp_socket *osmo_rtp_socket_create(void *talloc_ctx, unsigned int fl
rtp_session_set_seq_number(rs->sess, random());
rs->tx_timestamp = random();
+ /* Make sure ssrc changes are detected immediately */
+ rtp_session_set_ssrc_changed_threshold(rs->sess, 0);
return rs;
}