From 7996134d2afb8098eb750433b20185bde21e0023 Mon Sep 17 00:00:00 2001 From: Holger Hans Peter Freyther Date: Thu, 22 May 2014 21:17:49 +0200 Subject: [PATCH] common: Ignore "si.valid" outside of _MAX_SYSINFO_TYPE Limit the range from 0 to (_MAX_SYSINFO_TYPE - 1) instead of 0 to 31. This way we will never access the lchan->si.buf[] out of bounds. This is only a theoretical issue though as the code filling the lchan->si.buf for the SACCH will not have valid >= _MAX_SYSINFO_TYPE. Add a small regression test to check we still schedule all SIs. Fixes: CID 1040765 --- .gitignore | 1 + configure.ac | 1 + src/common/sysinfo.c | 2 +- tests/Makefile.am | 2 +- tests/misc/Makefile.am | 8 ++++++ tests/misc/misc_test.c | 58 +++++++++++++++++++++++++++++++++++++++++ tests/misc/misc_test.ok | 1 + tests/testsuite.at | 6 +++++ 8 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 tests/misc/Makefile.am create mode 100644 tests/misc/misc_test.c create mode 100644 tests/misc/misc_test.ok diff --git a/.gitignore b/.gitignore index 3aa39cba9..835134937 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ tests/agch/agch_test tests/paging/paging_test tests/cipher/cipher_test tests/sysmobts/sysmobts_test +tests/misc/misc_test tests/testsuite tests/testsuite.log diff --git a/configure.ac b/configure.ac index cb601d2f5..2d08b87d9 100644 --- a/configure.ac +++ b/configure.ac @@ -75,4 +75,5 @@ AC_OUTPUT( tests/agch/Makefile tests/cipher/Makefile tests/sysmobts/Makefile + tests/misc/Makefile Makefile) diff --git a/src/common/sysinfo.c b/src/common/sysinfo.c index 6a50afd15..e08ffcaf3 100644 --- a/src/common/sysinfo.c +++ b/src/common/sysinfo.c @@ -135,7 +135,7 @@ uint8_t *lchan_sacch_get(struct gsm_lchan *lchan) { uint32_t tmp; - for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % 32) { + for (tmp = lchan->si.last + 1; tmp != lchan->si.last; tmp = (tmp + 1) % _MAX_SYSINFO_TYPE) { if (lchan->si.valid & (1 << tmp)) { lchan->si.last = tmp; return lchan->si.buf[tmp]; diff --git a/tests/Makefile.am b/tests/Makefile.am index b32241b99..633b6a4ad 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = paging cipher sysmobts agch +SUBDIRS = paging cipher sysmobts agch misc # The `:;' works around a Bash 3.2 bug when the output is not writeable. $(srcdir)/package.m4: $(top_srcdir)/configure.ac diff --git a/tests/misc/Makefile.am b/tests/misc/Makefile.am new file mode 100644 index 000000000..4091bc6ae --- /dev/null +++ b/tests/misc/Makefile.am @@ -0,0 +1,8 @@ +AM_CPPFLAGS = $(all_includes) -I$(top_srcdir)/include -I$(OPENBSC_INCDIR) +AM_CFLAGS = -Wall $(LIBOSMOCORE_CFLAGS) $(LIBOSMOGSM_CFLAGS) +LDADD = $(LIBOSMOCORE_LIBS) $(LIBOSMOGSM_LIBS) +noinst_PROGRAMS = misc_test +EXTRA_DIST = misc_test.ok + +misc_test_SOURCES = misc_test.c $(srcdir)/../stubs.c +misc_test_LDADD = $(top_builddir)/src/common/libbts.a $(LDADD) diff --git a/tests/misc/misc_test.c b/tests/misc/misc_test.c new file mode 100644 index 000000000..91fd73a1b --- /dev/null +++ b/tests/misc/misc_test.c @@ -0,0 +1,58 @@ +/* testing misc code */ + +/* (C) 2011 by Holger Hans Peter Freyther + * (C) 2014 by sysmocom s.f.m.c. GmbH + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + * + */ + +#include + +#include +#include + +static void test_sacch_get(void) +{ + struct gsm_lchan lchan; + int i, off; + + printf("Testing lchan_sacch_get\n"); + memset(&lchan, 0, sizeof(lchan)); + + /* initialize the input. */ + for (i = 1; i < _MAX_SYSINFO_TYPE; ++i) { + lchan.si.valid |= (1 << i); + memset(&lchan.si.buf[i], i, sizeof(lchan.si.buf[i])); + } + + /* It will start with '1' */ + for (i = 1, off = 0; i <= 32; ++i) { + uint8_t *data = lchan_sacch_get(&lchan); + off = (off + 1) % _MAX_SYSINFO_TYPE; + if (off == 0) + off += 1; + + //printf("i=%d (%%=%d) -> data[0]=%d\n", i, off, data[0]); + OSMO_ASSERT(data[0] == off); + } +} + +int main(int argc, char **argv) +{ + test_sacch_get(); + return EXIT_SUCCESS; +} diff --git a/tests/misc/misc_test.ok b/tests/misc/misc_test.ok new file mode 100644 index 000000000..c8187a10e --- /dev/null +++ b/tests/misc/misc_test.ok @@ -0,0 +1 @@ +Testing lchan_sacch_get diff --git a/tests/testsuite.at b/tests/testsuite.at index ec3021fd8..b528335f8 100644 --- a/tests/testsuite.at +++ b/tests/testsuite.at @@ -18,3 +18,9 @@ AT_KEYWORDS([cipher]) cat $abs_srcdir/cipher/cipher_test.ok > expout AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/cipher/cipher_test], [], [expout], [ignore]) AT_CLEANUP + +AT_SETUP([misc]) +AT_KEYWORDS([misc]) +cat $abs_srcdir/misc/misc_test.ok > expout +AT_CHECK([$OSMO_QEMU $abs_top_builddir/tests/misc/misc_test], [], [expout], [ignore]) +AT_CLEANUP