aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax <msuraev@sysmocom.de>2017-09-06 15:28:31 +0200
committerMax <msuraev@sysmocom.de>2017-09-08 13:27:06 +0200
commitcb9f608094ea31b851b376504c585432340af888 (patch)
treee44dfe9d943bf94e813a8154fc764b4267395b9a
parent9e36dca82aa139f10e25ca037cf4a7cc03eafea0 (diff)
Check readv() return value to prevent crash
Previously result of readv() was used unconditionally so when it failed and returned negative value it was treated like very large positive which lead to memory corruption. Fix this and add proper error log. Change-Id: I956c8d551f45c9dd43b5e9de11dfe20dd8783647 Related: SYS#3865
-rw-r--r--src/osmo-bts-litecell15/l1_transp_hw.c10
-rw-r--r--src/osmo-bts-sysmo/l1_transp_hw.c10
2 files changed, 16 insertions, 4 deletions
diff --git a/src/osmo-bts-litecell15/l1_transp_hw.c b/src/osmo-bts-litecell15/l1_transp_hw.c
index 63818643..b526108a 100644
--- a/src/osmo-bts-litecell15/l1_transp_hw.c
+++ b/src/osmo-bts-litecell15/l1_transp_hw.c
@@ -204,9 +204,15 @@ static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what)
iov[i].iov_len = msgb_tailroom(msg[i]);
}
-
rc = readv(ofd->fd, iov, ARRAY_SIZE(iov));
- count = rc / prim_size;
+ if (rc < 0) {
+ LOGP(DL1C, LOGL_ERROR, "failed to read from fd: %s\n", strerror(errno));
+ /* N. B: we do not abort to let the cycle below cleanup allocated memory properly,
+ the return value is ignored by the caller anyway.
+ TODO: use libexplain's explain_readv() to provide detailed error description */
+ count = 0;
+ } else
+ count = rc / prim_size;
for (i = 0; i < count; ++i) {
msgb_put(msg[i], prim_size);
diff --git a/src/osmo-bts-sysmo/l1_transp_hw.c b/src/osmo-bts-sysmo/l1_transp_hw.c
index da8ac3f3..9c0a514a 100644
--- a/src/osmo-bts-sysmo/l1_transp_hw.c
+++ b/src/osmo-bts-sysmo/l1_transp_hw.c
@@ -215,9 +215,15 @@ static int l1if_fd_cb(struct osmo_fd *ofd, unsigned int what)
iov[i].iov_len = msgb_tailroom(msg[i]);
}
-
rc = readv(ofd->fd, iov, ARRAY_SIZE(iov));
- count = rc / prim_size;
+ if (rc < 0) {
+ LOGP(DL1C, LOGL_ERROR, "failed to read from fd: %s\n", strerror(errno));
+ /* N. B: we do not abort to let the cycle below cleanup allocated memory properly,
+ the return value is ignored by the caller anyway.
+ TODO: use libexplain's explain_readv() to provide detailed error description */
+ count = 0;
+ } else
+ count = rc / prim_size;
for (i = 0; i < count; ++i) {
msgb_put(msg[i], prim_size);