Commit Graph

4779 Commits

Author SHA1 Message Date
Dominik fbee810f52 fix: correct uint64 underflow in performance timing macros
When ts1.tv_nsec < ts0.tv_nsec (nanosecond counter wraps across a second
boundary), the unsigned subtraction produced a huge positive value instead
of a small negative one. Compute the full difference in signed int64_t
nanoseconds first, then convert to unsigned microseconds.

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-21 21:41:30 +01:00
Dominik a50ebb47d4 Add debug.performance
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-21 21:36:54 +01:00
Dominik 0140c57525 Merge pull request #2814 from pi-hole/fix/rate-limiting-count
Fix client count inflation for rate-limited queries
2026-03-21 11:55:39 +01:00
Dominik bb82c09a74 Merge pull request #2813 from pi-hole/fix/print_totp_cli
config: show totp_secret presence in CLI output
2026-03-21 10:32:19 +01:00
Dominik 11c2aa954b Merge pull request #2811 from pi-hole/new/backtraces
Add universal crash backtrace via _Unwind_Backtrace
2026-03-20 20:20:08 +01:00
Dominik 2d4dcc982c Improve wording as suggested by @rdwebdesign
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-20 20:18:55 +01:00
Dominik bc85e2678c dnsmasq_interface: fix client count inflation for rate-limited queries
findClientID() increments client->count for every incoming query,
including those that are immediately refused by the rate-limiter.
Because rate-limited queries never create a query record, GC (gc.c)
has nothing to decrement and the count inflates permanently.

Undo the increment before the early return so the "Top Clients
(total)" counter stays consistent with what Pi-hole actually
processed.

Fixes #2810

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-20 20:15:40 +01:00
RD WebDesign b5e9f1ade4 Add autocompletion for the new commands
Signed-off-by: RD WebDesign <github@rdwebdesign.com.br>
2026-03-20 14:46:59 -03:00
Dominik 2ac91560e7 database: Guard query-count counters against uint64_t underflow
memdb_queries_count and diskdb_queries_count are declared as uint64_t.
In delete_old_queries_from_db(), both counters are decremented by
`deleted` (int64_t from sqlite3_changes64). If the counter is already
at 0 — which can happen when import_queries_from_disk() fails and
resets the counter to 0 mid-import — subtracting any positive `deleted`
value wraps the counter to UINT64_MAX (≈1.84×10¹⁹).

db_counts() returns these counters as sqlite3_int64 (signed), so
UINT64_MAX becomes -1. The /api/queries endpoint then casts -1 to
unsigned long for recordsTotal, producing the observed
1.8446744073709552E+19 value and making the query log appear to have
millions of pages.

Fix: clamp the subtraction to 0 instead of allowing underflow, using
a guarded conditional assignment.

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-20 15:56:30 +01:00
Dominik b55cb419dc config: show totp_secret presence in CLI output
`pihole-FTL --config webserver.api` previously silently omitted
`webserver.api.totp_secret` because it carries FLAG_WRITE_ONLY,
making it impossible to tell from the CLI whether 2FA was enabled.

Write-only config items are now included in CLI output but rendered
as "********" when the secret is set (consistent with how
`webserver.api.password` is displayed), or left blank when unset.
The actual secret value is never exposed.

Fixes #2435

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-20 14:49:15 +01:00
Dominik 227b69573d Add universal crash backtrace via _Unwind_Backtrace
Replace the glibc-only execinfo.h backtrace with _Unwind_Backtrace
from GCC's libgcc, which works on glibc and musl, static-pie and
dynamic, across all supported architectures.

Key design decisions:
- __ehdr_start (GNU ld linker symbol) gives the PIE load base
  reliably on all targets, replacing dl_iterate_phdr which does not
  enumerate the main executable consistently on musl static builds
- SOURCE_ROOT compile definition strips the build machine prefix so
  backtraces show project-relative paths (src/signals.c:42)
- dladdr() resolves dynamic symbol names from .dynsym for stripped
  shared-library frames; /proc/self/maps provides the library name
  as fallback when no symbol is exported
- Each frame is logged as a single line:
    #N  func_name    src/file.c:line   (resolved)
    #N  0xADDRESS    (libc.so.6  sym+off)  (unresolved)

New subcommands:
- crash:     triggers a deterministic SIGSEGV via mmap(PROT_NONE)
             (not UB, not elided by the optimizer, not caught by
             sanitizers) to validate the crash handler end-to-end
- backtrace: prints a live backtrace without crashing, for manual
             inspection on a given build or platform

CI: add check_crash() to test/arch_test.sh, called unconditionally
for every architecture to verify the handler fires and a backtrace
is produced.

Bug fixes:
- removePID(): guard config.files.pid.v.s != NULL before fopen()
  to prevent a secondary SIGSEGV when config was never loaded
  (e.g. crash/backtrace subcommands)
- signal_handler(): fflush(stdout) immediately after generate_backtrace()
  so the output is preserved even if cleanup() faults on uninitialized
  state before exit() can flush stdio

Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-20 14:11:13 +01:00
Dominik 601880fea4 Update embedded SQLite3 to 3.51.3
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-14 17:57:29 +01:00
Dominik 80ddb8c2cd Revert "Update embedded SQLite3 to 3.52.0" 2026-03-14 17:52:34 +01:00
yubiuser 2fc50ec6ae Merge pull request #2806 from pi-hole/query_frequency/padd
Add query_frequency to /padd endpoint
2026-03-13 20:06:25 +01:00
yubiuser 5defa9679a Merge pull request #2804 from pi-hole/form-action
Add form-action 'self' to Content-Security-Policy
2026-03-13 20:06:10 +01:00
Dominik 86f690a3fe Merge pull request #2803 from pi-hole/fix/import_api_sessions_earlier
Ensure API sessions are restored before starting the HTTP server
2026-03-13 20:00:46 +01:00
yubiuser 4d774b5d8e Add query_frequency to /padd endpoint
Signed-off-by: yubiuser <github@yubiuser.dev>
2026-03-12 22:08:45 +01:00
yubiuser c1c9cd78c2 Add form-action 'self' to Content-Security-Policy
Signed-off-by: yubiuser <github@yubiuser.dev>
2026-03-12 19:49:33 +01:00
Dominik b0419a9651 Merge pull request #2791 from pi-hole/fix/groups_by_name
Fix obtaining client groups by name
2026-03-10 12:02:16 +01:00
Dominik caa02e8233 Merge pull request #2790 from pi-hole/fix/names_behind_router
Add new option for controling name resolution via MAC address
2026-03-09 22:06:38 +01:00
Dominik b541b36dfd Restore API sessions way ahead of starting the web server to ensure we are not falsely rejecting still valid sessions
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-09 22:02:57 +01:00
Dominik b4fe55d102 Merge pull request #2798 from pi-hole/update/sqlite3_52_0
Update embedded SQLite3 to 3.52.0
2026-03-07 12:29:57 +01:00
Dominik ba3c03b91f Merge pull request #2797 from aeolio/eventHorizon
Fix cross-compilation issues w/ custom toolchain
2026-03-06 20:38:34 +01:00
Dominik dcff36ede3 Update embedded SQLite3 to 3.52.0
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-06 20:33:08 +01:00
Andreas Ziegler 1fa09a842a Fix undeclared symbols in signal handler
Building with a custom toolchain (GCC 15, uClibc, kernel headers 5.10)
fails in netlink.c with errors like these:

pihole-ftl-6.5/src/signals.c:214:30: error: ‘BUS_MCEERR_AR’ undeclared (first use in this function)
  214 |                         case BUS_MCEERR_AR: log_info("     with code:  BUS_MCEERR_AR (Hardware memory error: action required)"); break;
      |                              ^~~~~~~~~~~~~
pihole-ftl-6.5/src/signals.c:214:30: note: each undeclared identifier is reported only once for each function it appears in
pihole-ftl-6.5/src/signals.c:215:30: error: ‘BUS_MCEERR_AO’ undeclared (first use in this function)
  215 |                         case BUS_MCEERR_AO: log_info("     with code:  BUS_MCEERR_AO (Hardware memory error: action optional)"); break;
      |                              ^~~~~~~~~~~~~

Bracket undeclared symbols with precompiler directives.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:55:29 +01:00
Andreas Ziegler e3a3b6efcb Fix undeclared symbols in netlink protocol handler
Building with a custom toolchain (GCC 15, uClibc, kernel headers 5.10)
fails in netlink.c with errors like these:

pihole-ftl-6.5/src/tools/netlink_consts.h:40:11: error: ‘ARPHRD_MCTP’ undeclared here (not in a function); did you mean ‘ARPHRD_FCPP’?
   40 |         { ARPHRD_MCTP, "mctp" },
      |           ^~~~~~~~~~~
      |           ARPHRD_FCPP
pihole-ftl-6.5/src/tools/netlink_consts.h:148:11: error: ‘RTPROT_OPENR’ undeclared here (not in a function); did you mean ‘RTPROT_OSPF’?
  148 |         { RTPROT_OPENR, "openr" },
      |           ^~~~~~~~~~~~
      |           RTPROT_OSPF

Bracket undeclared symbols with precompiler directives.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:54:07 +01:00
Andreas Ziegler 3e3f635690 Fix build with missing execinfo.h
The __GLIBC__ logic to detect stack backtracing capability fails for
uClibc, because uClibc also defines these symbols, but backtrace
functionality is optional.

pihole-ftl-6.5/src/signals.c:13:10: fatal error: execinfo.h: No such file or directory
   13 | #include <execinfo.h>
      |          ^~~~~~~~~~~~

Instead of adding unreadable preprocessor exceptions, have CMake detect
execinfo.h and use a appropriate preprocessor symbol.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:50:05 +01:00
Andreas Ziegler 3408d23677 Introduce sys/random.h detection by CMake
The __GLIBC__ version check causes problems with uClibc, because
this library also defines these variables, but the numbering is not
consistent with GNU libc. This prevents the inclusion of sys/random.h
in a uClibc toolchain, even if the file is present

Instead let CMake detect sys/random.h and control header inclusion
with a preprocessor symbol.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:46:30 +01:00
Andreas Ziegler edfb685312 Fix getrandom fallback
If sys/random.h cannot be found, the build terminates with this error:

pihole-ftl-6.5/src/config/password.c: In function ‘get_secure_randomness’:
pihole-ftl-6.5/src/config/password.c:100:52: error: ‘GRND_NONBLOCK’ undeclared (first use in this function); did you mean ‘SOCK_NONBLOCK’?
  100 |                 result = getrandom(buffer, length, GRND_NONBLOCK);
      |                                                    ^~~~~~~~~~~~~
      |                                                    SOCK_NONBLOCK

Add the missing definition of GRND_NONBLOCK in daemon.h.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:42:01 +01:00
Andreas Ziegler 4afe481719 webserver/civetweb/CMakeLists.txt: Remove absolute include path
Most cross-compilation tools terminate the build, when they encounter
unsafe (e.g. absolute) paths in include directives, because that might
leak host components into the target. Buildroot fails with:

i586-buildroot-linux-uclibc-gcc: ERROR: unsafe header/library path used in cross-compilation: '-I/usr/local/include'

Remove offending path snippet to correspond with all other include
definitions in Pi-hole/FTL.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-06 05:35:01 +01:00
Dominik c5622e86b6 Return early in find_device_by_hwaddr() if resolver.macNames is false
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-03-05 19:30:42 +01:00
Dominik df0cd7c701 Merge pull request #2788 from pi-hole/fix/db_import_without_import
Fix overTime data when database.DBimport = false
2026-03-05 19:20:47 +01:00
Andreas Ziegler 871c44fe6a Fix build without mbedtls:
Commit 3b45213 (Implement automatic TLS/SSL certificate renewals) [1]
introduced functionality that requires mbedtls, but mbedtls is an
optional dependency. This leads to the following compilation error:

pihole-ftl-6.5/src/webserver/webserver.c:36:10: fatal error: mbedtls/ssl_ciphersuites.h: No such file or directory
   36 | #include <mbedtls/ssl_ciphersuites.h>
      |          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.

Use the HAVE_MBEDTLS preprocessor symbol to assert that certificate related
code is only included if mbedtls is present in the build.

[1] https://github.com/pi-hole/FTL/commit/3b45213

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-04 16:55:11 +01:00
Dominik 931bdf4748 Merge pull request #2795 from aeolio/cmake-options
Introduce CMake options for optional dependencies
2026-03-02 21:55:07 +01:00
Andreas Ziegler 85c8997592 Introduce CMake options for optional dependencies
Readline and Mbed TLS support are optional dependencies. CMake detects
them, and automatically includes them if they are found. If this is not
intended, currently the only way is to manually delete these liraries
from the build system. While the default behaviour is beneficial, a more
resilient method is looked for to exclude dependencies from the build.

Introduce CMake options for both dependencies, that allow controlling
build inclusion by setting a build variable.

Signed-off-by: Andreas Ziegler <15275159+aeolio@users.noreply.github.com>
2026-03-02 06:28:06 +01:00
Dominik d9b60aa2b3 Add -DCMAKE_EXPORT_COMPILE_COMMANDS=ON so compile_commands.json is actually created and VSCode knows about the defines used during compilation
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-28 20:23:07 +01:00
Dominik 1df6676536 Fix obtaining client groups by name
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-27 13:13:56 +01:00
Dominik e53bfc6fc1 Add config option resolver.macNames which can be used to control whether FTL tries to resolve host names via MAC addresses. This may not work in special network configurations where clients aren't all on the same link (Lay2 but not Layer 3 connection)
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-27 12:37:55 +01:00
Dominik 5dbeeb8e60 Always mark database import as done even when database.DBimport = false or on database errors. Otherwise, garbage collection will never run, causing the memory allocation to always grow and overtime information to be incorrect (handled in GC code as well)
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-26 07:22:53 +01:00
Dominik 9db76c85d1 Reimplement the resolver to avoid pointer magic possibly causing issues on armv5tel
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-20 17:54:39 +01:00
Dominik 77cd161134 Merge pull request #2772 from pi-hole/fix/dns_domain_local
home.arpa and internal TLDs may be non-local without revServer
2026-02-16 14:30:17 +01:00
Dominik b46907a796 Simplify if-condition
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-16 07:56:22 +01:00
Dominik 747d88de40 Fix logic and reformulate coment
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-15 19:52:57 +01:00
Dominik 0789ad27bd Merge branch 'development' into tweak/async_import
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-09 19:10:42 +01:00
Dominik 05ca076ff3 Merge pull request #2757 from pi-hole/tweak/track_sqlite_memory
Low-memory hardware optimizations
2026-02-08 21:13:53 +01:00
Dominik a8872e636a Cache earliest timestamp in both databases (mem and disk) as well
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-08 10:04:33 +01:00
Dominik aa6e4e8b49 Fix that dns.domain = "home.arpa" ("internal") and dns.domain.local == false should result in these domains being sent to regular upstreams in the absence of matching revServer settings
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-02-01 10:22:45 +01:00
Dominik ba2db9c10f Keep track of number of queries in the database ourselves. No need to fully count the number of queries in the disk after startup. Even though this is happening using a covering index, it turned out to be very slow on heavily I/O limited devices when the index tree does not fit into available cache memory (scanning can take upwards of one minute for a simple SELECT COUNT(*) FROM query_storage)
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-01-10 17:33:20 +01:00
Dominik 90313fdaf4 Update SQLite3 to 3.51.2
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-01-10 11:04:45 +01:00
Dominik b65de38a62 Use localtime_r() instead of localtime() for thread-safety reasons
Signed-off-by: Dominik <dl6er@dl6er.de>
2026-01-08 20:23:41 +01:00