diff options
author | Max <msuraev@sysmocom.de> | 2017-09-06 15:28:31 +0200 |
---|---|---|
committer | Max <msuraev@sysmocom.de> | 2017-09-08 13:27:06 +0200 |
commit | cb9f608094ea31b851b376504c585432340af888 (patch) | |
tree | e44dfe9d943bf94e813a8154fc764b4267395b9a | |
parent | 9e36dca82aa139f10e25ca037cf4a7cc03eafea0 (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.c | 10 | ||||
-rw-r--r-- | src/osmo-bts-sysmo/l1_transp_hw.c | 10 |
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); |