Browse Source

security: hardening flags + control_server fixes (F-001, F-002)

- Add --hardened flag to build.sh with FORTIFY, stack protector, PIE, RELRO
- Add --enable-hardening to configure.ac
- F-001: fix %s -> %.32s to prevent stack leak from non-null-terminated network string
- F-002: add pre-check recv_len >= MAX before buf_space computation to prevent size_t underflow
chatgui
Evgeny 3 months ago
parent
commit
f5c93266dc
  1. 18
      build.sh
  2. 14
      configure.ac
  3. 3
      doc/_plan.txt
  4. 8
      src/control_server.c
  5. 32
      tools/chatgui/build_linux.sh

18
build.sh

@ -6,6 +6,7 @@
# --clean Clean before build # --clean Clean before build
# --full Full rebuild (autoreconf + configure + make) # --full Full rebuild (autoreconf + configure + make)
# --asan Build with AddressSanitizer (debug) # --asan Build with AddressSanitizer (debug)
# --hardened Build with compiler security hardening flags
# -j[N] Build with N parallel jobs (default: 4) # -j[N] Build with N parallel jobs (default: 4)
set -e # Exit on error set -e # Exit on error
@ -23,8 +24,10 @@ fi
CLEAN=0 CLEAN=0
FULL_REBUILD=0 FULL_REBUILD=0
USE_ASAN=0 USE_ASAN=0
USE_HARDENED=0
JOBS="-j4" JOBS="-j4"
MAKE_ARGS="" MAKE_ARGS=""
HARDEN_FLAGS=""
while [[ $# -gt 0 ]]; do while [[ $# -gt 0 ]]; do
case $1 in case $1 in
@ -35,6 +38,7 @@ while [[ $# -gt 0 ]]; do
echo " --clean Clean before build" echo " --clean Clean before build"
echo " --full Full rebuild (autoreconf + configure + make)" echo " --full Full rebuild (autoreconf + configure + make)"
echo " --asan Build with AddressSanitizer" echo " --asan Build with AddressSanitizer"
echo " --hardened Build with compiler security hardening flags"
echo " -j[N] Build with N parallel jobs (default: 4)" echo " -j[N] Build with N parallel jobs (default: 4)"
exit 0 exit 0
;; ;;
@ -50,6 +54,10 @@ while [[ $# -gt 0 ]]; do
USE_ASAN=1 USE_ASAN=1
shift shift
;; ;;
--hardened)
USE_HARDENED=1
shift
;;
-j*) -j*)
JOBS="$1" JOBS="$1"
shift shift
@ -135,6 +143,8 @@ if [ ! -f Makefile ]; then
echo "Running ./configure..." echo "Running ./configure..."
if [ "$USE_ASAN" -eq 1 ]; then if [ "$USE_ASAN" -eq 1 ]; then
./configure CFLAGS="-g -Og -fsanitize=address -fno-omit-frame-pointer -fno-pie" LDFLAGS="-no-pie" ./configure CFLAGS="-g -Og -fsanitize=address -fno-omit-frame-pointer -fno-pie" LDFLAGS="-no-pie"
elif [ "$USE_HARDENED" -eq 1 ]; then
./configure --enable-hardening
else else
./configure ./configure
fi fi
@ -151,6 +161,14 @@ if [ "$USE_ASAN" -eq 1 ]; then
(cd lib && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "lib build failed"; exit 1; } (cd lib && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "lib build failed"; exit 1; }
(cd src && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "src build failed"; exit 1; } (cd src && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$AF" "LDFLAGS+=$AL" $JOBS $MAKE_ARGS 2>&1) || { echo "src build failed"; exit 1; }
BUILD_SUCCESS=1 BUILD_SUCCESS=1
elif [ "$USE_HARDENED" -eq 1 ]; then
echo "(Hardening flags enabled)"
HF="-D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wformat=2 -Wformat-overflow=2 -fPIE"
HL="-Wl,-z,relro -Wl,-z,now -pie"
(cd lib && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "lib build failed"; exit 1; }
(cd src && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "src build failed"; exit 1; }
(cd tests && make clean $JOBS $MAKE_ARGS 2>&1 && make "CFLAGS+=$HF" "LDFLAGS+=$HL" $JOBS $MAKE_ARGS 2>&1) || { echo "tests build failed"; exit 1; }
BUILD_SUCCESS=1
else else
make $JOBS $MAKE_ARGS 2>&1 | tee build.log make $JOBS $MAKE_ARGS 2>&1 | tee build.log
if [ ${PIPESTATUS[0]} -eq 0 ]; then if [ ${PIPESTATUS[0]} -eq 0 ]; then

14
configure.ac

@ -55,6 +55,20 @@ fi
AM_CONDITIONAL([USE_OPENSSL], [test "x$with_openssl" = "xyes"]) AM_CONDITIONAL([USE_OPENSSL], [test "x$with_openssl" = "xyes"])
# ==================== HARDENING ====================
AC_ARG_ENABLE([hardening],
AS_HELP_STRING([--enable-hardening], [Enable compiler security hardening (FORTIFY, stack protector, PIE, RELRO)]),
[enable_hardening=$enableval],
[enable_hardening=no])
if test "x$enable_hardening" = "xyes"; then
HARDEN_CFLAGS="-D_FORTIFY_SOURCE=2 -fstack-protector-strong -fstack-clash-protection -Wformat=2 -Wformat-overflow=2 -fPIE"
HARDEN_LDFLAGS="-Wl,-z,relro -Wl,-z,now -pie"
CFLAGS="$CFLAGS $HARDEN_CFLAGS"
LDFLAGS="$LDFLAGS $HARDEN_LDFLAGS"
AC_MSG_NOTICE([Hardening flags enabled: $HARDEN_CFLAGS])
fi
# ==================== НАДЁЖНЫЙ ДЕТЕКТ WINDOWS ==================== # ==================== НАДЁЖНЫЙ ДЕТЕКТ WINDOWS ====================
AC_MSG_CHECKING([for Windows]) AC_MSG_CHECKING([for Windows])
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[

3
doc/_plan.txt

@ -0,0 +1,3 @@
План доработок
[ ] продумать архитектуру репликации таблицы узлов группы
[ ] добавить узлы хелперы (для проксирования трафика)

8
src/control_server.c

@ -479,6 +479,12 @@ static void client_read_callback(socket_t fd, void* arg) {
struct control_client* client = (struct control_client*)arg; struct control_client* client = (struct control_client*)arg;
struct control_server* server = client->server; struct control_server* server = client->server;
if (client->recv_len >= ETCPMON_MAX_MSG_SIZE) {
DEBUG_ERROR(DEBUG_CATEGORY_CONTROL, "Control recv buffer overflow (pre-check)");
close_client(server, client);
return;
}
/* Read available data */ /* Read available data */
uint8_t* buf = client->recv_buffer + client->recv_len; uint8_t* buf = client->recv_buffer + client->recv_len;
size_t buf_space = ETCPMON_MAX_MSG_SIZE - client->recv_len; size_t buf_space = ETCPMON_MAX_MSG_SIZE - client->recv_len;
@ -801,7 +807,7 @@ static void handle_client_data(struct control_server* server, struct control_cli
u_free(text); u_free(text);
} }
} else { } else {
DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Unknown action received: '%s'", cmd->action); DEBUG_WARN(DEBUG_CATEGORY_CONTROL, "Unknown action received: '%.32s'", cmd->action);
} }
} }
break; break;

32
tools/chatgui/build_linux.sh

@ -0,0 +1,32 @@
#!/bin/bash
set -eo pipefail
# --- dependencies ---
PKGS="cmake librlottie-dev zlib1g-dev qtbase5-dev libssl-dev"
MISSING=""
for p in $PKGS; do
dpkg -s "$p" &>/dev/null || MISSING="$MISSING $p"
done
if [ -n "$MISSING" ]; then
echo "Installing missing packages:$MISSING"
sudo apt update && sudo apt install -y $MISSING
else
echo "All dependencies OK"
fi
# --- build ---
SRCDIR="$(cd "$(dirname "$0")" && pwd)"
BUILDDIR="$SRCDIR/build"
JOBS="${JOBS:-$(nproc)}"
echo "Source: $SRCDIR"
echo "Build: $BUILDDIR"
echo "Jobs: $JOBS"
echo ""
[ -f "$BUILDDIR/Makefile" ] || cmake -S "$SRCDIR" -B "$BUILDDIR"
cmake --build "$BUILDDIR" -j"$JOBS"
echo ""
echo "OK. Run: $BUILDDIR/chatgui"
Loading…
Cancel
Save