Marco d'Itri [Sat, 4 Apr 2020 17:10:47 +0000 (19:10 +0200)]
pppd: Add lcp-echo-adaptive option
This adds an option that has been added by Debian and other distros
for a while now.
When adaptive LCP echo is enabled, LCP echo requests are only sent if the
link is idle, avoiding the common situation where a congested PPP link
(e.g. during torrenting) is falsely detected as disconnected because the
LCP replies are not received in time.
gettimeofday() suffers from time jumps due ntp or any manual change,
so duration measurements and scheduling can not be accurate.
let's use monotonic time source instead, if available.
it's known glibc (< 2.3.4) & old uclibc don't provide CLOCK_MONOTONIC
denine, but kernel may have it supported. so, use clock_gettime()
with fallback to gettimeofday() if first call has failed.
several gettimeofday()/time() calls still have to be preserved for
debug, pseudoterminal timestamping and string formatting. all the
rest calls are replaced to new get_time() call.
solaris kept with gettimeofday() as before, corresponding get_time()
system implementation can be updated/added in any future.
Paul Mackerras [Sat, 21 Mar 2020 04:13:42 +0000 (15:13 +1100)]
pppd: Obfuscate password argument string
After processing the argument to the 'password' option, this
overwrites the original argument on the stack with '?' characters,
and for good measure makes the argument pointer point to a constant
string "********" so as not to reveal the length of the password.
This is so that tools such as ps don't show the actual password
when displaying the process arguments. Nevertheless, it is still
better to get the password from a file, since there is inevitably
still a window of time when the password would be visible.
Paul Mackerras [Mon, 3 Feb 2020 05:31:42 +0000 (16:31 +1100)]
pppd: Ignore received EAP messages when not doing EAP
This adds some basic checks to the subroutines of eap_input to check
that we have requested or agreed to doing EAP authentication before
doing any processing on the received packet. The motivation is to
make it harder for a malicious peer to disrupt the operation of pppd
by sending unsolicited EAP packets. Note that eap_success() already
has a check that the EAP client state is reasonable, and does nothing
(apart from possibly printing a debug message) if not.
Paul Mackerras [Mon, 3 Feb 2020 04:53:28 +0000 (15:53 +1100)]
pppd: Fix bounds check in EAP code
Given that we have just checked vallen < len, it can never be the case
that vallen >= len + sizeof(rhostname). This fixes the check so we
actually avoid overflowing the rhostname array.
Reported-by: Ilja Van Sprundel <ivansprundel@ioactive.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Paul Mackerras [Sat, 4 Jan 2020 01:01:32 +0000 (12:01 +1100)]
radius: Prevent buffer overflow in rc_mksid()
On some systems getpid() can return a value greater than 65535.
Increase the size of buf[] to allow for this, and use slprintf()
to make sure we never overflow it.
Paul Mackerras [Tue, 31 Dec 2019 00:12:07 +0000 (11:12 +1100)]
pppd: Avoid use of strnlen (and strlen) in vslprintf
Commit b311e98b ("pppd: Limit memory accessed by string formats with
max length specified") added calls to strnlen() in vslprintf().
Unfortunately, strnlen() is not provided in some standard C libraries.
This changes the code to avoid using strnlen(). Using the observation
that the number of characters we can use from the input string is
bounded by buflen, the number of bytes of output buffer available,
we can also avoid doing strlen() on a potentially long string.
James Carlson [Tue, 31 Dec 2019 00:18:48 +0000 (11:18 +1100)]
pppd: Fix IPv6 default route code for Solaris
Commit 388597ee ("pppd: Add defaultroute6 and related options") added
code to pppd/sys-solaris.c which only works on Linux. Solaris doesn't
allow the use of the SICORT* family of ioctls for IPv6. They're legacy
IPv4 only. Routing sockets are much more flexible than the ioctls.
This rewrites the Solaris code to use a routing socket to set the
default route.
Paul Mackerras [Sun, 29 Dec 2019 23:22:40 +0000 (10:22 +1100)]
plugins/rp-pppoe: Make tag parsing loop condition more accurate
The loop in parsePacket() that parses the tags in a received PPPoE
packet uses a loop condition that checks if there is at least one
more byte to be read; however, the tag header is 4 bytes. Thus it
could read 3 bytes past the end of the received data. However,
there is no possibility of reading past the end of the
packet->payload array, since we previously checked that
len <= ETH_JUMBO_LEN (which is sizeof(packet->payload)) - 6.
Also, the tag length check will always fail (except for a tag
type of TAG_END_OF_LIST, which terminates processing).
This fixes the loop condition to require at least 4 bytes
remaining, so that we know that the tag header is within the
received data.
Paul Mackerras [Sun, 29 Dec 2019 22:32:18 +0000 (09:32 +1100)]
pppd: Make sure word read from options file is null-terminated
If a word read from an options file was longer than MAXWORDLEN,
we could pass it to option_error() without null termination,
which could have lead to an out-of-bounds access in vslprintf.
Make sure word[] is null terminated in all cases.
Reported-by: Florian Kohnhäuser <florian@kohnhaeuser.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Paul Mackerras [Sun, 29 Dec 2019 22:24:54 +0000 (09:24 +1100)]
pppd: Limit memory accessed by string formats with max length specified
Currently, calls to [v]slprintf that have a string format (%s, %v,
%q) with a maximum length specified (e.g. %.20s) do a strlen() on
the string, and can therefore access memory beyond the maximum
length specified. If the string is not null-terminated, this could
result in an out-of-bounds read.
This makes vslprintf use strnlen() in cases where a maximum length
has been specified, so that we don't access the string beyond the
maximum length that was given.
Paul Mackerras [Sun, 1 Dec 2019 10:32:37 +0000 (21:32 +1100)]
pppd: Eliminate some more compiler warnings
Recent versions of gcc produce warnings on code where strncpy will
produce a result that is not NULL terminated. This changes the
code to eliminate these warnings. In two cases this is done by
changing strncpy to strlcpy, which could in principle cause a loss
of the information in the last byte. This is not a concern in
these cases because:
- In sys-linux.c, the interface names in struct ifreq were possibly
not NULL terminated. The Linux kernel clears the last byte to make
them NULL terminated anyway, so there is no loss of information.
- In session.c, the lastlog ll_line and ll_host fields were possibly
not NULL terminated. These fields are quite long and it is unlikely
that the last byte is needed.
In the other cases strlcpy and strlcat are used to give the same
effect as the old code but without warnings.
This also changes %ld to %d in one place to eliminate a format warning.
Kurt Van Dijck [Fri, 4 Oct 2019 17:40:46 +0000 (19:40 +0200)]
pppd: Include time.h header before using time_t
Since include/net/ppp_defs.h is used in both kernelspace and userland
it is hard to include <time.h> there.
This commit fixes the problems in userspace code individually and leaves
ppp_defs.h as-is.
Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Paul Mackerras [Sun, 1 Dec 2019 03:30:55 +0000 (14:30 +1100)]
pppd: Don't free static string
Commit fcb076c2 ("Various fixes for errors found by coverity static
analysis (#109)", 2019-05-06) added statements to free the result
returned from get_first_ethernet(). However, the result of
get_first_ethernet() is not dynamically allocated, either on Linux
or Solaris. Hence this removes the unnecessary (and dangerous)
free() statements.
Fixes: fcb076c2 ("Various fixes for errors found by coverity static analysis (#109)") Reported-by: Florian Kohnhäuser <florian@kohnhaeuser.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
fhost [Sat, 19 Oct 2019 06:05:28 +0000 (08:05 +0200)]
pppd: Fix `ifname` option in case of multilink (#105)
Make pppd use the unit and not the interface name to get the bundle.
pppd was looking for the default interface name (`pppX`) in the
database to retreive the bundle id on which a new link should
attach, and fails if the `ifname` option is used.
Paul Mackerras [Sat, 19 Oct 2019 06:02:59 +0000 (17:02 +1100)]
pppd: Fix variable reference syntax in Makefile.linux
References to the variable called CC in makefiles need to be
written as $(CC) not $CC. Make interprets the latter as a reference
to the (nonexistent) variable C followed by a literal C.
Fixes: 4e713175 ("make: Avoid using host include for cross-compiling") Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Check that pointer to the tdb is not NULL before calling tdb_close().
It is possible that the file could not be opened/created due to
permission issues. This change prevents the crash that happens in that
case.
Signed-off-by: Alfonso Sánchez-Beato <alfonso.sanchez-beato@canonical.com>
/opt/SUNWspro/bin/cc -D_KERNEL -DSVR4 -DSOL2 -DPRIOQ -DDEBUG
-I../include -O -Xa -xO2 -xspace -W0,-Lt -c ppp.c
"ppp.c", line 113: identifier redeclared: time
current : long
previous: function(pointer to long) returning long :
"/usr/include/iso/time_iso.h", line 91
cc: acomp failed for ppp.c
The include/net/ppp_defs.h header is used in the Solaris kernel
driver and hence can't include userland headers.
Kurt Van Dijck [Thu, 26 Sep 2019 07:21:06 +0000 (09:21 +0200)]
pppd: Refactor setjmp/longjmp with pipe pair in event wait loop
setjmp/longjmp isn't supported by all compilers.
Having a pipe pair to wake an event wait loop from within a signal handler
is rather portable and common enough.
Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Kurt Van Dijck [Mon, 30 Sep 2019 12:45:08 +0000 (14:45 +0200)]
pppoe: Remove the use of cdefs
sys/cdefs.h contains the __P() macro.
The header doesn't exist in my musl toolchain,
the __P() macro has been obsoleted even by glibc,
and it's never used in the code.
This commit removes the need for this remainder.
Signed-off-by: Kurt Van Dijck <dev.kurt@vandijck-laurijssen.be> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Paul Mackerras [Mon, 10 Jun 2019 07:58:07 +0000 (17:58 +1000)]
Add Submitting-patches.md
This adds a file that describes the standards expected for patches and
pull requests. The standards are different from those for most
projects on github.com and hence need to be spelled out.
rp-pppoe plugin: Add options to tune discovery timeout and number of attempts
Add new options pppoe-padi-timeout and pppoe-padi-attempts.
These modifications are the similar to the ones done on
pppoe-discovery in commit 70a8ad3d ("pppoe-discovery: add options to
tune discovery timeout and attempts", 2017-12-07).
Signed-off-by: Alexis Cellier <alexis.cellier@smile.fr> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Matteo Croce [Sat, 4 May 2019 16:48:53 +0000 (18:48 +0200)]
pppoe: Custom host-uniq tag
Add pppoe 'host-uniq' option to set an arbitrary
host-uniq tag instead of the pppd pid.
Some ISPs use such tag to authenticate the CPE,
so it must be set to a proper value to connect.
Paul Mackerras [Sat, 18 May 2019 08:18:53 +0000 (18:18 +1000)]
plugins/rp-pppoe: Fix compile errors
This fixes compile errors introduced in commit fcb076c ("Various fixes
for errors found by coverity static analysis (#109)", 2019-05-06).
Including pppd.h gave errors on some systems (e.g. recent Debian and
Ubuntu) regarding the type 'u_char' being undefined. To fix this, we
simply take out the lines that define _POSIX_SOURCE.
pppd: Use openssl for the DES instead of the libcrypt / glibc
It seems the latest glibc (in Fedora glibc-2.27.9000-12.fc29) dropped
libcrypt. The libxcrypt standalone package can be used instead, but
it dropped the old setkey/encrypt API which ppp uses for DES. There
is support for using openssl in pppcrypt.c, but it contains typos
preventing it from compiling and seems to be written for an ancient
openssl version.
This updates the code to use current openssl.
[paulus@ozlabs.org - wrote the commit description, fixed comment in
Makefile.linux.]
Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Paul Mackerras [Sat, 23 Jun 2018 07:26:42 +0000 (17:26 +1000)]
pppd: Don't try to free(NULL - 1)
A logic bug in update_script_environment() means that it can call
remove_script_env() even when the variable being removed is not
present in the script_env array. The result of that is that
remove_script_env() will call free() with argument NULL - 1.
To fix this, we avoid calling remove_script_env() in this case.
Paul Mackerras [Sat, 23 Jun 2018 06:40:27 +0000 (16:40 +1000)]
pppd: Fix compile warning due to comparing pointer to NUL character
Evidently this means to check for arg pointing to an empty string,
not arg being NULL, since the ensuing error talks about the variable
name being missing.
Vegard Nossum [Wed, 13 Jun 2018 10:38:53 +0000 (12:38 +0200)]
pppd: Fix printing call in print_option()
print_option() was in this case passing p/opt->addr2 as the format string
instead of the string to be printed (as a quoted string). That could lead
to a nasty crash.
Signed-off-by: Vegard Nossum <vegard.nossum@oracle.com> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
This makes the makefiles include $(LDFLAGS) as a parameter when
linking executables. Distros use this as a way of applying linker
flags across all the executables they build.
[paulus@ozlabs.org - supplied the patch description]
Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
Jacob Floyd [Sat, 11 Mar 2017 05:25:23 +0000 (23:25 -0600)]
Use systemd's sd_notify with option up_sdnotify
This adds an up_sdnotify option so that systemd services of
Type=notify can have pppd send the READY=1 signal to systemd
once a network protocol (typically IP) is up.
To use up_sdnotify, pppd must be compiled with SYSTEMD=y.
up_sdnotify is safe as a non-priveleged option because systemd will
ignore any notifications that it is not expecting. If systemd starts
pppd in a unit-file that is Type=notify, then (and only then) will it
handle the READY=1 signal. If systemd didn't start the process, it
ignroes any notifications unless the signaling process was started by a
service that systemd is monitoring (directly or indirectly, such as a
grandchild process in the same cgroup as a process that systemd started)
AND that service is Type=notify, AND that service is explicitly
configured to allow other processes to send a notification on behalf of
that service by setting NotifyAccess=all.
Also, the socket used is defined in an environment variable provided and
deleted by systemd, allowing system and user services to use a different
socket. I really don't think there's any way to use that socket (even via
the sd_notify api of their library) to gain elevated privileges.
Another reason that up_sdnotify is a non-priveleged option is for cases
where ppp should be started as a system service under a non-priveleged
account. There may be other issues with running ppp under other
accounts, but systemd does not require root--or other privileged--access
in order to use the notification feature. Instead the security for this
feature is provided at the process level in that systemd knows which
processes it did and did not start, and which processes those processes
started (ie other processes in the systemd unit's cgroup), as explained
above.
Lubomir Rintel [Mon, 9 Jan 2017 13:34:23 +0000 (13:34 +0000)]
pppoe: include netinet/in.h before linux/in.h
This fixes builds with newer kernels. Basically, <netinet/in.h> needs to be
included before <linux/in.h> otherwise the earlier, unaware of the latter,
tries to redefine symbols and structures. Also, <linux/if_pppox.h> doesn't work
alone anymore, since it pulls the headers in the wrong order, so we better
include <netinet/in.h> early.
Nathan Hintz [Sun, 4 Dec 2016 20:37:33 +0000 (12:37 -0800)]
pppd: fix pppol2tp option printing
PPPD crashes (SEGV) when the 'dump' or 'dryrun' options are specified and
the 'pppol2tp' option is specified. The crash occurs because the
'pppol2tp' option value is not saved when the parameter is processed (in
the pppol2tp plugin), but is then referenced when printed. This was
encountered using xl2tpd and the l2tp_ppp kernel module.
Modify the 'pppol2tp' plugin to save the option value.
Stefan Nickl [Wed, 10 Aug 2016 14:52:12 +0000 (16:52 +0200)]
pppd: Provide error() implementation in pppoe-discovery
The pppoe-discovery program calls error() from the CHECK_ROOM macro
defined in pppoe.h. Since pppoe-discovery is a standalone program not
linked with the rest of pppd, the only way this could build is by
linking to glibc's proprietary error(3) function instead of the function
of the same name (but with different arguments) defined in pppd/utils.c.
So with glibc this builds, but will probably crash when the assertion is
triggered. As the assertion is unlikely to fail, nobody has noticed.
The build however fails with musl libc or uClibc since they don't
provide the doppelganger.
Signed-off-by: Stefan Nickl <Stefan.Nickl@gmail.com>
Paul Mackerras [Tue, 23 Aug 2016 06:10:21 +0000 (16:10 +1000)]
pppd: allow use of arbitrary interface names
This is a modified version of a patch from openSUSE that enables PPP interfaces
to be called arbitrary names, rather than simply pppX where X is the unit
number.
The modifications from the stock openSUSE patch are:
- refresh patch on top of 018_ip-up_option.diff
- fix a printf format-string vulnerability in pppd/main.c:set_ifunit()
- clarify the pppd.8 manpage additions
- patch pppstats/pppstats.c to query renamed interfaces without complaint
Origin: SUSE
Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=458646
Forwarded: no Reviewed-by: Chris Boot <bootc@debian.org> Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Once we've terminated the PPP session, there is no chance of a PPP layer
disconnect. Some PPPoE relays don't detect the PPP session going down, and
depend on a long timeout or a PPPoE PADT to terminate the session.
Send a PADT on disconnect to work around these buggy relays.
Signed-off-by: Simon Farnsworth <simon@farnz.org.uk>
pppd: Fix sign-extension when displaying bytes in octal
print_string() displays characters as \\%.03o but without first
casting it from "char" to "unsigned char" so it gets sign-extended
to an int. This causes output like \37777777630 instead of \230.
Signed-off-by: Philip A. Prindeville <philipp@redfish-solutions.com>
Natanael Copa [Tue, 3 Jun 2014 08:53:47 +0000 (08:53 +0000)]
pppd: add support for defaultroute-metric option
This allows user to specify the 'metric' (or 'prio') for the default
route set by pppd. This is useful in multi-ISP setups where there
might be more than one default gateway.
Signed-off-by: Natanael Copa <ncopa@alpinelinux.org>
The current recursive loops do not check the exit status of make
in subdirs which leads to `make` passing even when a subdir failed
to compile or install.
URL: https://bugs.gentoo.org/334727 Signed-off-by: Martin von Gagern <Martin.vGagern@gmx.net> Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Paul Mackerras [Fri, 1 Aug 2014 11:40:18 +0000 (21:40 +1000)]
winbind plugin: Add -DMPPE=1 to eliminate compiler warnings
When compiling the winbind plugin, we need an equivalent definition
of the MPPE symbol to that which applied when the main pppd was
compiled. This adds that to Makefile.linux.
Reported-by: Mike Gilbert <floppym@gentoo.org> Signed-off-by: Paul Mackerras <paulus@samba.org>
Paul Mackerras [Fri, 1 Aug 2014 07:32:15 +0000 (17:32 +1000)]
pppd: Eliminate memory leak with multiple instances of a string option
This eliminates the memory leak which occurs when a user gives the
same string option multiple times. Although the leak is trivial under
normal conditions, the fact that it can be triggered by the user
means that it may be of interest to attackers, so let's plug the leak.
This also means that any o_string option without OPT_STATIC set needs
to have opt->addr pointing to a pointer which starts out NULL. That
is the case for all current uses of o_string.
Paul Mackerras [Fri, 1 Aug 2014 06:05:42 +0000 (16:05 +1000)]
pppd: Eliminate potential integer overflow in option parsing
When we are reading in a word from an options file, we maintain a count
of the length we have seen so far in 'len', which is an int. When len
exceeds MAXWORDLEN - 1 (i.e. 1023) we cease storing characters in the
buffer but we continue to increment len. Since len is an int, it will
wrap around to -2147483648 after it reaches 2147483647. At that point
our test of (len < MAXWORDLEN-1) will succeed and we will start writing
characters to memory again.
This may enable an attacker to overwrite the heap and thereby corrupt
security-relevant variables. For this reason it has been assigned a
CVE identifier, CVE-2014-3158.
This fixes the bug by ceasing to increment len once it reaches MAXWORDLEN.
Reported-by: Lee Campbell <leecam@google.com> Signed-off-by: Paul Mackerras <paulus@samba.org>