<feed xmlns='http://www.w3.org/2005/Atom'>
<title>accel-ppp.git/.github, branch 1.15.0</title>
<subtitle>High performance PPTP/L2TP/SSTP/PPPoE/IPoE server for Linux (mirror of https://github.com/accel-ppp/accel-ppp.git)
</subtitle>
<id>https://git.amelek.net/accel-ppp/accel-ppp.git/atom?h=1.15.0</id>
<link rel='self' href='https://git.amelek.net/accel-ppp/accel-ppp.git/atom?h=1.15.0'/>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/'/>
<updated>2026-10-28T18:50:54+00:00</updated>
<entry>
<title>tests: fix DHCPv6 fixtures after DNS refactoring and add CI coverage</title>
<updated>2026-10-28T18:50:54+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-10-28T18:47:22+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=69cfe9cc7c03f663bcbc430291bc3a9460e433ba'/>
<id>urn:sha1:69cfe9cc7c03f663bcbc430291bc3a9460e433ba</id>
<content type='text'>
Use the shared DNS storage and production allocator in the DHCPv6 fixture. Check bounded large DNS replies, preserve the repeated-ORO overflow regression, and check domain-list allocation failure in both reply builders. Link ipv6_dns.c and stub the truncation warning. Run the standalone suites and CTest in sanitizer CI, and replace the stale documented failure with current instructions.

Validation: all six standalone suites pass with ASan/UBSan (LCP uses UBSan); both CTest checks pass.
Signed-off-by: Denys Fedoryshchenko &lt;denys.f@collabora.com&gt;
</content>
</entry>
<entry>
<title>ipv6: remove obsolete three-server DNS limit</title>
<updated>2026-10-05T23:19:48+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-27T06:16:31+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=2823a07df0c88e9d98472b9248f2e9c3179f6920'/>
<id>urn:sha1:2823a07df0c88e9d98472b9248f2e9c3179f6920</id>
<content type='text'>
The legacy limit matches RFC 6106's recommendation that hosts treat three learned RDNSS addresses as sufficient. That was host-side repository guidance, not a limit in the RADIUS, DHCPv6, or RDNSS encodings.

RFC 8106 obsoletes RFC 6106 and explicitly removes the recommendation to limit learned RDNSS addresses to three, leaving the number to local policy. It instead recommends the ability to store at least three addresses when DNS information comes from multiple sources.

Store both configured and per-session servers in reusable contiguous arrays. Start with a four-address, 64-byte allocation, grow geometrically, retain capacity across reload or reauthorization, and free session storage only at teardown. Bound advertised lists by actual DHCPv6 and router-advertisement packet space.

Warn when servers have to be dropped for lack of room, as the fixed limit used to, skip the DNS search list rather than write it past the end of a full advertisement, and drop the stale three-server wording from the [ipv6-dns] documentation.

Link: https://github.com/accel-ppp/accel-ppp/commit/4f562467dbdf819395e138617c2a057e02595b9e#r197212083
Link: https://www.rfc-editor.org/rfc/rfc6106.html#section-5.3.1
Link: https://www.rfc-editor.org/rfc/rfc8106.html#section-5.3.1
Link: https://www.rfc-editor.org/rfc/rfc8106.html#appendix-A
</content>
</entry>
<entry>
<title>Merge pull request #358 from nuclearcat/fix/kernel-module-install</title>
<updated>2026-10-05T23:17:37+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-10-05T23:17:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=d33028de8b8b520dfde12d9d9d01f4cd576f23b3'/>
<id>urn:sha1:d33028de8b8b520dfde12d9d9d01f4cd576f23b3</id>
<content type='text'>
cmake: fix kernel module installation</content>
</entry>
<entry>
<title>ci: remove qemu build from BE (s390x) workflow using qemu from ubuntu 26.04</title>
<updated>2026-09-11T18:37:47+00:00</updated>
<author>
<name>Sergey V. Lobanov</name>
<email>sergey@lobanov.in</email>
</author>
<published>2026-09-11T18:17:45+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=fa7d316967a1cb0c4fa583a236757c62efd56d6a'/>
<id>urn:sha1:fa7d316967a1cb0c4fa583a236757c62efd56d6a</id>
<content type='text'>
</content>
</entry>
<entry>
<title>ci: remove debian11 as EoL, add ubuntu 26:04</title>
<updated>2026-09-11T17:58:01+00:00</updated>
<author>
<name>Sergey V. Lobanov</name>
<email>sergey@lobanov.in</email>
</author>
<published>2026-09-10T22:41:57+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=b8af4865bd4c0bd33b895e9f5fe66bbe8ea33980'/>
<id>urn:sha1:b8af4865bd4c0bd33b895e9f5fe66bbe8ea33980</id>
<content type='text'>
</content>
</entry>
<entry>
<title>Merge pull request #346 from nuclearcat/ipoe-stale-session-flush</title>
<updated>2026-08-31T15:30:54+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-31T15:30:54+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=40575b78b7bb043c7a0ff4dd29a048be056dee9f'/>
<id>urn:sha1:40575b78b7bb043c7a0ff4dd29a048be056dee9f</id>
<content type='text'>
Ipoe stale session flush fixes</content>
</entry>
<entry>
<title>cmake: fix kernel module installation</title>
<updated>2026-08-30T00:10:39+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-30T00:10:39+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=dbc9d0fb6863026b16f4805709acc7e4977d7e66'/>
<id>urn:sha1:dbc9d0fb6863026b16f4805709acc7e4977d7e66</id>
<content type='text'>
Install each module from its real build directory, propagate staged install roots, and fail when kbuild modules_install fails. Add a rootless CTest and CI regression for successful and failed installs.

Best practices followed:

Use the standard CMake DESTDIR and kbuild INSTALL_MOD_PATH staging interfaces:
https://cmake.org/cmake/help/latest/envvar/DESTDIR.html
https://docs.kernel.org/kbuild/modules.html#install-mod-path

Check child command status with execute_process RESULT_VARIABLE:
https://cmake.org/cmake/help/latest/command/execute_process.html

Register repeatable tests with CTest add_test:
https://cmake.org/cmake/help/latest/command/add_test.html
</content>
</entry>
<entry>
<title>ipv6: assign DNS servers per session from RADIUS</title>
<updated>2026-08-12T07:42:35+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-04T15:39:51+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=58ef850d1705d88f006d761d32c55bde5205a27d'/>
<id>urn:sha1:58ef850d1705d88f006d761d32c55bde5205a27d</id>
<content type='text'>
The ipv6_nd and ipv6_dhcp modules could only advertise the DNS servers
configured in [ipv6-dns], the same set for every subscriber. RFC 6911
defines DNS-Server-IPv6-Address (attribute 169) for exactly this, and
the attribute was already in the shipped dictionary and in attr_defs.h;
nothing read it.

Give struct ap_session an ipv6_dns list, filled by the radius module
from that attribute, and have both modules advertise it when the session
has one: in the RDNSS option of the router advertisements, and in the
DNS_SERVERS option of DHCPv6 replies. Sessions without a list of their
own keep getting the configured servers, so nothing changes for anyone
not sending the attribute.

The selection is a single ipv6_dns_get() shared by both modules rather
than a copy in each: they already duplicate the whole [ipv6-dns] parser,
and two copies of a precedence rule are two chances to drift. It caps
what it returns, so neither the RDNSS option length (one byte, in units
of 8) nor the router advertisement buffer can be pushed around by what a
RADIUS server sends. The radius module caps at the same 3 servers as
[ipv6-dns] accepts and warns once when a reply carries more.

An Access-Accept which carries the attribute replaces the whole
previously assigned list rather than appending to it, so a re-authorized
session ends up with the servers of the latest reply and not with a
concatenation. One which does not carry it leaves the current list
alone, which is how the IPv4 MS-Primary-DNS-Server attribute already
behaves.

ipv6_dns_test.c covers the selection: assigned wins over configured,
empty list means "nothing assigned" rather than "no DNS", the cap holds
for both sources, and a caller with no room gets nothing rather than a
stomped buffer. Wired into the ASAN/UBSAN workflow.

Inspired by the per-session IPv6 DNS support in accel-ppp-ng (commit
2df6eb99), reimplemented against mainline's ap_session and ipdb types.
</content>
</entry>
<entry>
<title>l2tp: validate the deciphered length of hidden AVPs</title>
<updated>2026-08-12T07:42:35+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-04T14:40:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=9554ce05e13fdb8c55a54e259b4154c9aeaca58d'/>
<id>urn:sha1:9554ce05e13fdb8c55a54e259b4154c9aeaca58d</id>
<content type='text'>
decode_avp() only checked the 2 bytes length prefix of the Hidden AVP
Subformat when the ciphered attribute spanned more than one MD5 block.
For an attribute of at most 16 bytes it deciphered the single block and
returned straight away, leaving l2tp_recv() to take the prefix at face
value:

	orig_avp_len = ntohs(*(uint16_t *)avp-&gt;val) + sizeof(*avp);
	...
	attr-&gt;length = orig_avp_len - sizeof(*avp);

That prefix is an output of the cipher, so a peer which does not know
the secret (i.e. anyone able to reach the L2TP socket, no handshake
needed beyond a preceding Random-Vector AVP) turns it into 16 random
bits. Worse than an over-read: orig_avp_len is a uint16_t, so a prefix
of 0xffff wraps to 5, attr-&gt;length becomes -1, and the ATTR_TYPE_STRING
and ATTR_TYPE_OCTETS cases then run

	attr-&gt;val.string = _malloc(attr-&gt;length + 1);	/* _malloc(0) */
	memcpy(attr-&gt;val.string, orig_avp_val, attr-&gt;length);	/* SIZE_MAX */

that is an unbounded memcpy() into a zero sized allocation. Remotely
triggerable heap corruption on any tunnel with a secret configured. The
accel-ppp encoder always pads hidden AVPs by at least 16 bytes, so it
never produces an attribute short enough to reach this path; only a
crafted packet does.

Fix it at the source rather than at the call site: decode_avp() now
returns the deciphered length through an output parameter, and the
length is bounded against the room actually available in the received
AVP on every path out of the function, single block included. Callers
can no longer re-derive it from the AVP body and get it wrong, and the
existing multi-block check keeps guarding the deciphering loop itself.

Add packet_test.c, a standalone test which drives the real parser
through a real UDP socket: hand-crafted packets cover the length prefix
checks (including the boundaries of what fits and the single block path
the encoder cannot produce), and l2tp_packet_send()/l2tp_recv() round
trips cover the multi-block cipher and the unaligned AVP accessors. It
reproduces the corruption above under ASan on unpatched code. Wire it,
and the so far unused bitpool_test.c, into the ASAN/UBSAN workflow.

Inspired by the equivalent hardening in accel-ppp-ng (commit a8ca0f3f),
which bounds the length at the call site; the fix here is placed inside
decode_avp() and covered by a regression test.
</content>
</entry>
<entry>
<title>ci: survive the negative branch counters gcov reports</title>
<updated>2026-08-08T16:19:13+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-08T16:19:13+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=60702f40ac55d474ce26bd8e1d904feb9e5f160f'/>
<id>urn:sha1:60702f40ac55d474ce26bd8e1d904feb9e5f160f</id>
<content type='text'>
The coverage job fails while gcovr reads the data for triton.c:

    Unrecognized GCOV output ... branch  2 taken -1
    NegativeHits: Got negative hit value in gcov line 'branch  2 taken -1'

gcov emits those now and then, it is gcc bug 68080 and not something the
source can avoid. gcovr 6 and later treat it as a fatal parse error
unless --gcov-ignore-parse-errors names the case to tolerate.

Passing that option unconditionally is not enough, since the job runs on
both ubuntu-24.04 and ubuntu-22.04 and the gcovr in the latter predates
it and takes no value. Ask gcovr whether it knows the option before
adding it, and print what was decided so the log says which one ran.
</content>
</entry>
</feed>
