console-server: Enable handler iteration with -fsanitize=address

Currently when running obmc-console-server built with -fsanitize=address
we receive the following abort:

```
$ dbus-run-session ./build/obmc-console-server -i test $(realpath pts)
iniparser: cannot open etc/obmc-console.conf
3 handler types
obmc-console-server: Can't open log buffer file /var/local/log/obmc-console.log: No such file or directory
  console 'test': handler log [inactive]
=================================================================
==724703==ERROR: AddressSanitizer: global-buffer-overflow on address 0x559163200b08 at pc 0x5591631e6d08 bp 0x7ffdb2e64350 sp 0x7ffdb2e64348
READ of size 8 at 0x559163200b08 thread T0
    #0 0x5591631e6d07 in handlers_init ../console-server.c:560
    #1 0x5591631e6d07 in main ../console-server.c:1025
    #2 0x7f8e3f446249 in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #3 0x7f8e3f446304 in __libc_start_main_impl ../csu/libc-start.c:360
    #4 0x5591631e7390 in _start (/home/andrew/src/openbmc.org/openbmc/obmc-console/build/obmc-console-server+0x26390)

0x559163200b08 is located 24 bytes to the left of global variable 'socket_handler' defined in '../socket-handler.c:515:34' (0x559163200b20) of size 32
0x559163200b08 is located 8 bytes to the right of global variable 'log_handler' defined in '../log-handler.c:222:34' (0x559163200ae0) of size 32
SUMMARY: AddressSanitizer: global-buffer-overflow ../console-server.c:560 in handlers_init
Shadow bytes around the buggy address:
  0x0ab2ac638110: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ab2ac638120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ab2ac638130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ab2ac638140: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00
  0x0ab2ac638150: 00 00 00 00 00 00 00 00 f9 f9 f9 f9 00 00 00 00
=>0x0ab2ac638160: f9[f9]f9 f9 00 00 00 00 f9 f9 f9 f9 00 00 00 00
  0x0ab2ac638170: f9 f9 f9 f9 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ab2ac638180: 00 00 00 00 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9
  0x0ab2ac638190: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0ab2ac6381a0: 00 00 00 00 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0ab2ac6381b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==724703==ABORTING
```

Rework the start and stop symbol declarations to indicate we're
accessing an array, which keeps the sanitizer happy.

Change-Id: Ib17506a018702e64bbc419f0056da571847e2787
Signed-off-by: Andrew Jeffery <andrew@codeconstruct.com.au>
1 file changed
tree: dbcc14ed765cd9ce20ca55430d48575b2a16465d
  1. conf/
  2. subprojects/
  3. test/
  4. .clang-format
  5. .clang-tidy
  6. .gitignore
  7. .travis.yml
  8. CHANGELOG.md
  9. config-internal.h
  10. config.c
  11. config.h
  12. console-client.c
  13. console-dbus.c
  14. console-server.c
  15. console-server.h
  16. console-socket.c
  17. LICENSE
  18. log-handler.c
  19. meson.build
  20. meson.options
  21. OWNERS
  22. README.md
  23. ringbuffer.c
  24. socket-handler.c
  25. tty-handler.c
  26. util.c
README.md

To Build

To build this project, run the following shell commands:

meson setup build
meson compile -C build

To test:

meson test -C build

To Run Server

Running the server requires a serial port (e.g. /dev/ttyS0):

touch obmc-console.conf
./obmc-console-server --config obmc-console.conf ttyS0

To Connect Client

To connect to the server, simply run the client:

./obmc-console-client

To disconnect the client, use the standard ~. combination.

Underlying design

This shows how the host UART connection is abstracted within the BMC as a Unix domain socket.

               +---------------------------------------------------------------------------------------------+
               |                                                                                             |
               |       obmc-console-client       unix domain socket         obmc-console-server              |
               |                                                                                             |
               |     +----------------------+                           +------------------------+           |
               |     |   client.2200.conf   |  +---------------------+  | server.ttyVUART0.conf  |           |
           +---+--+  +----------------------+  |                     |  +------------------------+  +--------+-------+
Network    | 2200 +-->                      +->+ @obmc-console.host0 +<-+                        <--+ /dev/ttyVUART0 |   UARTs
           +---+--+  | console-id = "host0" |  |                     |  |  console-id = "host0"  |  +--------+-------+
               |     |                      |  +---------------------+  |                        |           |
               |     +----------------------+                           +------------------------+           |
               |                                                                                             |
               |                                                                                             |
               |                                                                                             |
               +---------------------------------------------------------------------------------------------+

This supports multiple independent consoles. The console-id is a unique portion for the unix domain socket created by the obmc-console-server instance. The server needs to know this because it needs to know what to name the pipe; the client needs to know it as it needs to form the abstract socket name to which to connect.