ead-client trusts several length and index fields taken straight from
the network when handling server responses, before authentication has
completed. Since the client sends its requests as UDP broadcasts and
never validates the origin of the replies, any host on the same L2
segment can spoof the whole handshake and hit these paths.
handle_prime() copies sb->len bytes into saltbuf[MAXSALTLEN] (32 bytes)
without checking the length, and passes sb->prime to t_getpreparam()
without a range check. Both come from the wire, so a salt length up to
255 overflows saltbuf and a prime index up to 255 reads (and writes)
out of bounds in the precompiled parameter table. This is
GHSA-mq4v-mf82-24rr.
handle_b() computes the copy length as msg->len - sizeof(number) and
memcpy()s it into bbuf[MAXPARAMLEN] with no bounds check. msg->len is
attacker controlled and only capped by the 1500 byte receive buffer, so
up to 1479 bytes land in the 256 byte bbuf. A msg->len of 0 makes the
signed length -1, which memcpy() treats as SIZE_MAX. This is
GHSA-8f8g-5c8x-8mhh.
handle_pong() writes the NUL terminator at pong->name[len] using an
unchecked length, allowing a one byte write past msgbuf, and the receive
loop's length check could wrap for a large msg->len.
Bound every length against its destination buffer and range check the
prime index, mirroring the checks already present on the daemon side in
ead.c (handle_send_a(), commit 63c0767f3d). ead-client is not
installed into images by the ead package, only the daemon is, so this
only affects administrators who build and run the client by hand.
Link: https://github.com/openwrt/openwrt/security/advisories/GHSA-mq4v-mf82-24rr
Link: https://github.com/openwrt/openwrt/security/advisories/GHSA-8f8g-5c8x-8mhh
Fixes: 2d86ea2a1d ("add the 'ead' package (emergency access daemon), which can provide remote access to your device, even if the ip and firewall settings are broken")
Assisted-by: Claude:claude-opus-4-8
Link: https://github.com/openwrt/openwrt/pull/25492
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Indicate that there are some changes. This should make sure that the
package gets updated.
Fixes: 63c0767f3d ("ead: fix integer underflow in handle_send_a()")
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
GCC 15 defaults to C23, where an empty parameter list "()" means
"(void)" instead of an unspecified argument list. This broke two spots
in the bundled tinysrp sources:
- The interrupt() signal handler in t_truerand.c was declared with
"()", so its type became "void (*)(void)" and no longer matched the
"void (*)(int)" expected by signal():
t_truerand.c:100:32: error: passing argument 2 of 'signal' from
incompatible pointer type [-Wincompatible-pointer-types]
Give it the proper signal handler signature instead.
- The pre-ANSI fallback in t_defines.h declared strchr(), strrchr()
and strtok() with "()". ead.c is compiled without -DHAVE_CONFIG_H,
so STDC_HEADERS is undefined and that legacy branch is taken, where
the zero-argument prototypes now conflict with the declarations in
the standard headers:
tinysrp/t_defines.h:90:30: error: conflicting types for 'strtok';
have 'char *(void)'
Drop the dead K&R branch and include <stdlib.h> and <string.h>
unconditionally; the library's own objects already take this path
via config.h.
Assisted-by: Claude:claude-opus-4-8
Link: https://github.com/openwrt/openwrt/pull/23955
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
handle_send_a() computed the SRP "A" parameter length as
len = ntohl(msg->len) - sizeof(struct ead_msg_number);
sizeof(struct ead_msg_number) is 1, and the subtraction is evaluated in
unsigned arithmetic. A packet with msg->len == 0 therefore wraps the
result to a huge value which, assigned to the signed int len, becomes -1.
The following bounds check is signed:
if (len > MAXPARAMLEN + 1)
return false;
so -1 passes, and memcpy(A.data, number->data, len) runs with len cast to
size_t (~SIZE_MAX) against the 257-byte abuf, crashing the daemon.
Neither parse_message() nor handle_packet() validate msg->len (only the
captured packet length), so an unauthenticated attacker on the local
segment can reach this path and crash ead with a single crafted packet.
Validate the claimed length in unsigned arithmetic before the subtraction
and bound it on both sides. Doing the upper-bound check unsigned as well
also closes a 32-bit-only variant where sizeof(ead_packet) + msg->len
overflows in handle_packet(), letting a large msg->len reach the same
negative-len path.
Link: https://github.com/openwrt/openwrt/security/advisories/GHSA-9558-77jp-g3fw
Reported-by: @Vasco0x4
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
The RETSIGTYPE macro was historically used for signal handler return types,
defaulting to int on some legacy systems. This is no longer needed,
so we now use void as the return type.
Fixes a compiler error:
error: assignment to 'void (*)(int)' from incompatible pointer type 'int (*)()' [-Wincompatible-pointer-types]
Link: https://github.com/openwrt/openwrt/pull/19681
Signed-off-by: Nick Hainke <vincent@systemli.org>
Trying to compile EAD with now default GCC14 will fail due to now erroring
out on implicit int type as well as implicit function declarations.
Due to this, the packaged configure script will fail on the simple compiler
test as the generated test uses main loop with an implicit int type.
So, instead of patching multiple test cases in the shipped configure script
for tinysrp lets run autoreconf on it so its regenerated.
We also need to pass -Wno-error=implicit-function-declaration as there are
multiple instances of tinysrp code relying on implicit function declarations.
Link: https://github.com/openwrt/openwrt/pull/18645
Signed-off-by: Robert Marko <robimarko@gmail.com>
Add call to fclose for file pointer fp in function t_openpw.
The resource leak could happen during an error handling.
Signed-off-by: Andrea Dalla Costa <andrea@dallacosta.me>
Note, that licensing stuff is a nightmare: many packages does not clearly
state their licenses, and often multiple source files are simply copied
together - each with different licensing information in the file headers.
I tried hard to ensure, that the license information extracted into the OpenWRT's
makefiles fit the "spirit" of the packages, e.g. such small packages which
come without a dedicated source archive "inherites" the OpenWRT's own license
in my opinion.
However, I can not garantee that I always picked the correct information
and/or did not miss license information.
Signed-off-by: Michael Heimpold <mhei@heimpold.de>
SVN-Revision: 43155