<feed xmlns='http://www.w3.org/2005/Atom'>
<title>accel-ppp.git/accel-pppd/ctrl/l2tp, branch master</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=master</id>
<link rel='self' href='https://git.amelek.net/accel-ppp/accel-ppp.git/atom?h=master'/>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/'/>
<updated>2026-09-01T06:08:47+00:00</updated>
<entry>
<title>utils: centralize unaligned integer accessors</title>
<updated>2026-09-01T06:08:47+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-09-01T06:08:47+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=7d4f8524f57ba0ac77e47171bebfc0370df667b1'/>
<id>urn:sha1:7d4f8524f57ba0ac77e47171bebfc0370df667b1</id>
<content type='text'>
</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>l2tp: read and write AVP values through unaligned-safe accessors</title>
<updated>2026-08-12T07:42:12+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-08-04T14:38:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=36c440758fc9fd606fbdfe342a4b3fd842d05c4e'/>
<id>urn:sha1:36c440758fc9fd606fbdfe342a4b3fd842d05c4e</id>
<content type='text'>
AVPs are packed back to back in the receive buffer, so the offset of any
given AVP is the sum of the lengths of all the AVPs before it, i.e. a
value the peer picks. Casting avp-&gt;val to uint16_t/uint32_t/uint64_t
therefore dereferences a pointer with an arbitrary alignment, which is
undefined behaviour, is caught by -fsanitize=alignment, and is only
harmless on x86 by accident. The same applies to the send path, where
the AVPs being built are laid out the same way.

Introduce unaligned_{ntohs,ntohl,be64toh}() and their store
counterparts, all memcpy() based, and use them for every multi-byte
field read out of or written into an AVP body. Accesses to the members
of struct l2tp_avp_t itself are fine as it is declared packed.

memxor() had the same problem, in a worse form: it cast both of its
uint8_t pointers to uintmax_t and walked them word by word. Since it is
only ever called on MD5 sized chunks, replace it with a plain byte loop
which compilers vectorize just as well, and which no longer breaks
strict aliasing either.

No functional change intended, this is a portability and UB fix; it also
removes a source of noise for the s390x (big endian) CI job.
</content>
</entry>
<entry>
<title>openssl: suppress deprecated API warnings</title>
<updated>2026-06-10T18:28:29+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-06-10T14:15:34+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=c1689506bbc27f498612ca69648876599ded7d7c'/>
<id>urn:sha1:c1689506bbc27f498612ca69648876599ded7d7c</id>
<content type='text'>
</content>
</entry>
<entry>
<title>session: encapsulate statistics counters</title>
<updated>2026-05-04T00:09:49+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-04-29T12:21:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=d6383d69813cf2244f31d8116176733ffbbeaceb'/>
<id>urn:sha1:d6383d69813cf2244f31d8116176733ffbbeaceb</id>
<content type='text'>
Group the core session starting, active, and finishing statistics behind the private ap_session_stat storage in session.c instead of exposing writable counters through ap_session.h. This keeps ownership inside the session core while preserving the existing CLI and ACCEL-PPP-MIB counter semantics.

Route session counter updates through ap_session_stat_*() helpers. Session start, activation, termination, finish, and shutdown-idle paths no longer open-code individual counter increments/decrements; the update policy now lives beside the session-owned storage and uses relaxed atomic operations for the simple state counters.

Make the CLI show-stat path render from a local snapshot and convert the PPP SNMP starting/active/finishing scalars from watched raw pointers to scalar handlers. PPP controllers now read max-session limits through ap_session_stat_starting() and ap_session_stat_active(), removing external direct access to ap_session_stat.

Signed-off-by: Denys Fedoryshchenko &lt;denys.f@collabora.com&gt;
</content>
</entry>
<entry>
<title>l2tp: encapsulate statistics counters</title>
<updated>2026-05-04T00:09:49+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2026-04-29T10:50:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=55157b5411e374e651c7db78967d2908db9b30e8'/>
<id>urn:sha1:55157b5411e374e651c7db78967d2908db9b30e8</id>
<content type='text'>
Group the L2TP tunnel, control-session, and data-session statistics in struct l2tp_stat_t and keep the storage private to l2tp.c instead of spreading writable stat_* globals through the module.  This keeps the ownership boundary in the L2TP control code while preserving the existing CLI and ACCEL-PPP-MIB counter semantics.

Route counter updates through l2tp_stat_*() helpers.  Tunnel, control-session, and data-session state transitions no longer open-code individual counter increments/decrements; the update policy now lives beside the L2TP-owned storage and uses relaxed atomic operations for the simple state counters.

Make the CLI show-stat path render from a local snapshot and convert the L2TP SNMP starting/active scalars from watched raw pointers to scalar handlers.  SNMP now reads through l2tp_stat_starting() and l2tp_stat_active(), removing the old l2tp_get_stat() pointer escape hatch.

Signed-off-by: Denys Fedoryshchenko &lt;denys.f@collabora.com&gt;
</content>
</entry>
<entry>
<title>Refactor session free function pointer in l2tp.c</title>
<updated>2026-02-22T20:38:48+00:00</updated>
<author>
<name>marekm72</name>
<email>35698605+marekm72@users.noreply.github.com</email>
</author>
<published>2026-02-22T20:38:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=b52d38df680450b413869edeeaa3baaba73e2918'/>
<id>urn:sha1:b52d38df680450b413869edeeaa3baaba73e2918</id>
<content type='text'>
</content>
</entry>
<entry>
<title>crypto: Removed internal tomcat crypto.</title>
<updated>2025-12-10T17:16:42+00:00</updated>
<author>
<name>Andrii Melnychenko</name>
<email>a.melnychenko@vyos.io</email>
</author>
<published>2025-09-29T16:14:48+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=c912d09018828745e3bcba268cd02a611e324d54'/>
<id>urn:sha1:c912d09018828745e3bcba268cd02a611e324d54</id>
<content type='text'>
Signed-off-by: Andrii Melnychenko &lt;a.melnychenko@vyos.io&gt;
</content>
</entry>
<entry>
<title>l2tp: fix buffer overflow and type errors in Calling/Called Number handling</title>
<updated>2025-11-26T18:39:13+00:00</updated>
<author>
<name>Denys Fedoryshchenko</name>
<email>denys.f@collabora.com</email>
</author>
<published>2025-11-26T18:38:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=2bbf451b94a3a9a96cdc8cbdb60a559f275dc0e6'/>
<id>urn:sha1:2bbf451b94a3a9a96cdc8cbdb60a559f275dc0e6</id>
<content type='text'>
  Fix issues introduced in 88a2ebdb:

  - Fix type declaration: uint8_t *calling[254] declared an array of 254
    pointers instead of an array of 254 bytes. Remove erroneous asterisks.

  - Fix buffer overflow vulnerability: L2TP AVP values can be up to 1017
    bytes (L2TP_AVP_LEN_MASK - sizeof(avp_header)), but buffers were only
    254(*4?) bytes. A malicious packet could cause stack buffer overflow.
    Use L2TP_AVP_LEN_MASK (1023) for buffer size to handle maximum AVP length.

  - Remove useless NULL checks: Stack-allocated arrays can never be NULL,
    causing compiler warnings. The existence check is n &gt; 0 / m &gt; 1.

Signed-off-by: Denys Fedoryshchenko &lt;denys.f@collabora.com&gt;
</content>
</entry>
<entry>
<title>L2TP include calling number to calling station ID RA</title>
<updated>2024-12-05T15:00:12+00:00</updated>
<author>
<name>Yaroslav Kholod</name>
<email>y.kholod@vyos.io</email>
</author>
<published>2024-12-05T11:10:10+00:00</published>
<link rel='alternate' type='text/html' href='https://git.amelek.net/accel-ppp/accel-ppp.git/commit/?id=88a2ebdb1dbab4029f41966f39e163b45701227d'/>
<id>urn:sha1:88a2ebdb1dbab4029f41966f39e163b45701227d</id>
<content type='text'>
</content>
</entry>
</feed>
