]> git.ipfire.org Git - thirdparty/openwrt.git/commitdiff
ppp: update to 2.5.3 23540/head
authorQingfang Deng <dqfext@gmail.com>
Tue, 26 May 2026 09:17:21 +0000 (17:17 +0800)
committerJonas Jelonek <jelonek.jonas@gmail.com>
Fri, 12 Jun 2026 23:34:23 +0000 (01:34 +0200)
Update to 2.5.3 and use the official tarball.

Changelog: https://github.com/ppp-project/ppp/releases/tag/v2.5.3

Removed upstreamed:
- 000-pppd-session-fixed-building-with-gcc-15.patch
- 001-pppdump-fixed-building-with-gcc-15.patch
- 501-fix-memcpy-fortify.patch
- 502-remove_mru.patch

Manually rebased:
- 500-add-pptp-plugin.patch

Add a pending patch to relax the check to avoid breaking existing
configurations.

Signed-off-by: Qingfang Deng <dqfext@gmail.com>
Link: https://github.com/openwrt/openwrt/pull/23540
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
15 files changed:
package/network/services/ppp/Makefile
package/network/services/ppp/patches/000-pppd-session-fixed-building-with-gcc-15.patch [deleted file]
package/network/services/ppp/patches/001-pppdump-fixed-building-with-gcc-15.patch [deleted file]
package/network/services/ppp/patches/105-debian_demand.patch
package/network/services/ppp/patches/208-fix_status_code.patch
package/network/services/ppp/patches/310-precompile_filter.patch
package/network/services/ppp/patches/321-multilink_support_custom_iface_names.patch
package/network/services/ppp/patches/340-populate_default_gateway.patch
package/network/services/ppp/patches/400-simplify_kernel_checks.patch
package/network/services/ppp/patches/404-remove_obsolete_protocol_names.patch
package/network/services/ppp/patches/405-no_multilink_option.patch
package/network/services/ppp/patches/500-add-pptp-plugin.patch
package/network/services/ppp/patches/501-fix-memcpy-fortify.patch [deleted file]
package/network/services/ppp/patches/501-relax-and-simplify-permission-check.patch [new file with mode: 0644]
package/network/services/ppp/patches/502-remove_mru.patch [deleted file]

index 5ad68a3665d685bdd2d31ac79e1c0dd7c9a4664c..3e27a253b8d6fede62a3cfbf642fef20ab88d43e 100644 (file)
@@ -9,14 +9,12 @@ include $(TOPDIR)/rules.mk
 include $(INCLUDE_DIR)/kernel.mk
 
 PKG_NAME:=ppp
-PKG_VERSION:=2.5.2
-PKG_RELEASE:=3
-
-PKG_SOURCE_PROTO:=git
-PKG_SOURCE_URL:=https://github.com/ppp-project/ppp
-PKG_MIRROR_HASH:=381668ce1547afeaf599f08ae37935bfd3d5841747c62bca5a870c11e3e9bedb
-PKG_SOURCE_DATE:=2024-12-31
-PKG_SOURCE_VERSION:=9f612dc02c34509f062ed63b60bcc7e937e25178
+PKG_VERSION:=2.5.3
+PKG_RELEASE:=1
+
+PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
+PKG_SOURCE_URL:=https://download.samba.org/pub/ppp
+PKG_HASH:=ddda28dec8aca99a403ab6070d94ffd2b17d63e9a4c5509158e99e148f572d4f
 
 PKG_MAINTAINER:=Felix Fietkau <nbd@nbd.name>
 PKG_LICENSE:=BSD-4-Clause
diff --git a/package/network/services/ppp/patches/000-pppd-session-fixed-building-with-gcc-15.patch b/package/network/services/ppp/patches/000-pppd-session-fixed-building-with-gcc-15.patch
deleted file mode 100644 (file)
index 6b4f1bd..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-From 5edcb01f1d8d521c819d45df1f1bb87697252130 Mon Sep 17 00:00:00 2001
-From: Khem Raj <raj.khem@gmail.com>
-Date: Mon, 17 Mar 2025 14:38:26 -0700
-Subject: [PATCH] pppd/session: Fixed building with GCC 15
-
-Fixed building with GCC 15 which defaults to C23
-and find conflicting declration of getspnam() here
-with the one provided by shadow.h (extern struct spwd *getspnam (const char *__name);)
-
-Fixes
-../../ppp-2.5.2/pppd/session.c: In function 'session_start':
-../../ppp-2.5.2/pppd/session.c:185:18: error: conflicting types for 'getspnam'; have 'struct spwd *(void)'
-  185 |     struct spwd *getspnam();
-      |                  ^~~~~~~~
-
-Signed-off-by: Khem Raj <raj.khem@gmail.com>
----
- pppd/session.c | 1 -
- 1 file changed, 1 deletion(-)
-
---- a/pppd/session.c
-+++ b/pppd/session.c
-@@ -182,7 +182,6 @@ session_start(const int flags, const cha
-     char *cbuf;
- #ifdef HAVE_SHADOW_H
-     struct spwd *spwd;
--    struct spwd *getspnam();
-     long now = 0;
- #endif /* #ifdef HAVE_SHADOW_H */
- #endif /* #ifdef PPP_WITH_PAM */
diff --git a/package/network/services/ppp/patches/001-pppdump-fixed-building-with-gcc-15.patch b/package/network/services/ppp/patches/001-pppdump-fixed-building-with-gcc-15.patch
deleted file mode 100644 (file)
index cd3f670..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-From c6c84c77c16878745be4955f2f5baac1f2280c96 Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= <jskarvad@redhat.com>
-Date: Thu, 27 Feb 2025 11:44:08 +0100
-Subject: [PATCH] Fixed building with GCC 15
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-GCC 15 defaults to C23 which does not allow K&R declarations.
-
-Credit Yaakov Selkowitz in:
-https://src.fedoraproject.org/rpms/ppp/pull-request/12
-
-Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
----
- pppdump/pppdump.c | 20 +++++++-------------
- 1 file changed, 7 insertions(+), 13 deletions(-)
-
---- a/pppdump/pppdump.c
-+++ b/pppdump/pppdump.c
-@@ -42,14 +42,12 @@ int tot_sent, tot_rcvd;
- extern int optind;
- extern char *optarg;
--void dumplog();
--void dumpppp();
--void show_time();
-+void dumplog(FILE *);
-+void dumpppp(FILE *);
-+void show_time(FILE *, int);
- int
--main(ac, av)
--    int ac;
--    char **av;
-+main(int ac, char **av)
- {
-     int i;
-     char *p;
-@@ -97,8 +95,7 @@ main(ac, av)
- }
- void
--dumplog(f)
--    FILE *f;
-+dumplog(FILE *f)
- {
-     int c, n, k, col;
-     int nb, c2;
-@@ -241,8 +238,7 @@ struct pkt {
- unsigned char dbuf[8192];
- void
--dumpppp(f)
--    FILE *f;
-+dumpppp(FILE *f)
- {
-     int c, n, k;
-     int nb, nl, dn, proto, rv;
-@@ -375,9 +371,7 @@ dumpppp(f)
- }
- void
--show_time(f, c)
--    FILE *f;
--    int c;
-+show_time(FILE *f, int c)
- {
-     time_t t;
-     int n;
index 25f1644aa4b367baedfc4c7d31113ac774fe366c..56d9488e36925a46cb848388fba600d84880dd38 100644 (file)
        } else {
 --- a/pppd/ipcp.c
 +++ b/pppd/ipcp.c
-@@ -1915,7 +1915,7 @@ ipcp_up(fsm *f)
+@@ -1930,7 +1930,7 @@ ipcp_up(fsm *f)
                    proxy_arp_set[f->unit] = 1;
  
        }
      } else {
 --- a/pppd/ipv6cp.c
 +++ b/pppd/ipv6cp.c
-@@ -1338,7 +1338,7 @@ ipv6cp_up(fsm *f)
+@@ -1344,7 +1344,7 @@ ipv6cp_up(fsm *f)
                if (sif6defaultroute(f->unit, go->ourid, ho->hisid))
                    default_route_set[f->unit] = 1;
        }
      } else {
 --- a/pppd/pppd-private.h
 +++ b/pppd/pppd-private.h
-@@ -370,7 +370,7 @@ void demand_conf(void);    /* config interf
+@@ -375,7 +375,7 @@ void demand_conf(void);    /* config interf
  void demand_block(void);      /* set all NPs to queue up packets */
  void demand_unblock(void); /* set all NPs to pass packets */
  void demand_discard(void); /* set all NPs to discard packets */
index 2d1e02742e30b3ce635def60146c1aa48cdd1df6..8c2fdea55b516bb4bb5ae4b3a6aff1c24dfd6830 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
 
 --- a/pppd/main.c
 +++ b/pppd/main.c
-@@ -1150,7 +1150,8 @@ get_input(void)
+@@ -1159,7 +1159,8 @@ get_input(void)
        }
        notice("Modem hangup");
        hungup = 1;
index 6a6d276979656334049d2487750faea81de4a92e..d88cab8bcc65fcc0de96e270f78823ab12179b81 100644 (file)
@@ -23,7 +23,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  #
  # SunOS provides a version of libpcap that would work, but SunOS has no support for activity filter
  AM_CONDITIONAL([PPP_WITH_FILTER], [ test "x${with_pcap}" = "xyes" && test "x${build_sunos}" != "xyes" ])
-@@ -348,6 +351,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION
+@@ -349,6 +352,7 @@ $PACKAGE_NAME version $PACKAGE_VERSION
      With libatm..........: ${with_atm:-no}
      With libpam..........: ${with_pam:-no}
      With libpcap.........: ${with_pcap:-no}
@@ -56,7 +56,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  /*
   * There have been 3 or 4 different names for this in libpcap CVS, but
   * this seems to be what they have settled on...
-@@ -182,6 +183,13 @@ static int setlogfile(char **);
+@@ -186,6 +187,13 @@ static int setlogfile(char **);
  static int loadplugin(char **);
  #endif
  
@@ -70,7 +70,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  #ifdef PPP_WITH_FILTER
  static int setpassfilter(char **);
  static int setactivefilter(char **);
-@@ -391,6 +399,14 @@ struct option general_options[] = {
+@@ -404,6 +412,14 @@ struct option general_options[] = {
        "set filter for active pkts", OPT_PRIO },
  #endif
  
@@ -85,7 +85,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { "maxoctets", o_int, &maxoctets,
        "Set connection traffic limit",
        OPT_PRIO | OPT_LLIMIT | OPT_NOINCR | OPT_ZEROINF },
-@@ -1666,6 +1682,27 @@ callfile(char **argv)
+@@ -1690,6 +1706,27 @@ callfile(char **argv)
      return ok;
  }
  
index 2070ab7d09199c87ed96a62f4f91841cc0333a92..15551992baa9ea4d559844dd140a976bc7c8dd0d 100644 (file)
@@ -119,7 +119,7 @@ Signed-off-by: George Kashperko <george@znau.edu.ua>
                        && memcmp(vd.dptr, key.dptr, vd.dsize) == 0;
 --- a/pppd/sys-linux.c
 +++ b/pppd/sys-linux.c
-@@ -980,6 +980,16 @@ void cfg_bundle(int mrru, int mtru, int
+@@ -1111,6 +1111,16 @@ void cfg_bundle(int mrru, int mtru, int
        add_fd(ppp_dev_fd);
  }
  
@@ -136,7 +136,7 @@ Signed-off-by: George Kashperko <george@znau.edu.ua>
  /*
   * make_new_bundle - create a new PPP unit (i.e. a bundle)
   * and connect our channel to it.  This should only get called
-@@ -998,6 +1008,8 @@ void make_new_bundle(int mrru, int mtru,
+@@ -1129,6 +1139,8 @@ void make_new_bundle(int mrru, int mtru,
  
        /* set the mrru and flags */
        cfg_bundle(mrru, mtru, rssn, tssn);
index 7d20f0449d7f39a6d411501c5a2553d6a3901b2f..a915af60fb748a83de149ccc0376ef0538dd5dab 100644 (file)
@@ -13,7 +13,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
 
 --- a/pppd/sys-linux.c
 +++ b/pppd/sys-linux.c
-@@ -2247,6 +2247,9 @@ int sifdefaultroute (int unit, u_int32_t
+@@ -2374,6 +2374,9 @@ int sifdefaultroute (int unit, u_int32_t
      memset (&rt, 0, sizeof (rt));
      SET_SA_FAMILY (rt.rt_dst, AF_INET);
  
@@ -23,7 +23,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      rt.rt_dev = ifname;
      rt.rt_metric = dfl_route_metric + 1; /* +1 for binary compatibility */
  
-@@ -2255,7 +2258,7 @@ int sifdefaultroute (int unit, u_int32_t
+@@ -2382,7 +2385,7 @@ int sifdefaultroute (int unit, u_int32_t
        SIN_ADDR(rt.rt_genmask) = 0L;
      }
  
index 014831a3a4259548901af93b1dfa1193ce53f90c..2f5febd440e21e7c603a794204cd7a9f82a8cb82 100644 (file)
@@ -10,8 +10,8 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
 
 --- a/pppd/sys-linux.c
 +++ b/pppd/sys-linux.c
-@@ -220,14 +220,10 @@ static fd_set in_fds;            /* set of fds tha
- static int max_in_fd;         /* highest fd set in in_fds */
+@@ -218,14 +218,10 @@ static int chindex;              /* channel index (n
+ static unsigned routing_table_id = RT_TABLE_MAIN;
  
  static int has_proxy_arp       = 0;
 -static int driver_version      = 0;
@@ -26,7 +26,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  
  static char loop_name[20];
  static unsigned char inbuf[512]; /* buffer for chars read from loopback */
-@@ -245,9 +241,8 @@ static int dynaddr_set;            /* 1 if ip_dyna
+@@ -241,9 +237,8 @@ static int dynaddr_set;            /* 1 if ip_dyna
  static int    looped;                 /* 1 if using loop */
  static int    link_mtu;               /* mtu for the link (not bundle) */
  
@@ -37,7 +37,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  
  #define MAX_IFS               100
  
-@@ -1966,11 +1961,12 @@ int ccp_fatal_error (int unit)
+@@ -2067,11 +2062,12 @@ int ccp_fatal_error (int unit)
   *
   * path_to_procfs - find the path to the proc file system mount point
   */
@@ -52,7 +52,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      struct mntent *mntent;
      FILE *fp;
  
-@@ -1992,6 +1988,7 @@ static char *path_to_procfs(const char *
+@@ -2093,6 +2089,7 @@ static char *path_to_procfs(const char *
            fclose (fp);
        }
      }
@@ -60,7 +60,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  
      strlcpy(proc_path + proc_path_len, tail,
            sizeof(proc_path) - proc_path_len);
-@@ -2883,6 +2880,8 @@ ppp_registered(void)
+@@ -2874,6 +2871,8 @@ ppp_registered(void)
  
  int ppp_check_kernel_support(void)
  {
@@ -69,7 +69,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      int s, ok, fd;
      struct ifreq ifr;
      int    size;
-@@ -3010,6 +3009,7 @@ int ppp_check_kernel_support(void)
+@@ -3001,6 +3000,7 @@ int ppp_check_kernel_support(void)
      }
      close(s);
      return ok;
@@ -77,7 +77,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  }
  
  #ifndef HAVE_LOGWTMP
-@@ -3571,6 +3571,7 @@ get_pty(int *master_fdp, int *slave_fdp,
+@@ -3562,6 +3562,7 @@ get_pty(int *master_fdp, int *slave_fdp,
      }
  #endif /* TIOCGPTN */
  
@@ -85,7 +85,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      if (sfd < 0) {
        /* the old way - scan through the pty name space */
        for (i = 0; i < 64; ++i) {
-@@ -3595,6 +3596,7 @@ get_pty(int *master_fdp, int *slave_fdp,
+@@ -3586,6 +3587,7 @@ get_pty(int *master_fdp, int *slave_fdp,
            }
        }
      }
@@ -93,7 +93,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
  
      if (sfd < 0)
        return 0;
-@@ -3710,6 +3712,7 @@ get_host_seed(void)
+@@ -3701,6 +3703,7 @@ get_host_seed(void)
  int
  sys_check_options(void)
  {
@@ -101,7 +101,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      if (demand && driver_is_old) {
        ppp_option_error("demand dialling is not supported by kernel driver "
                     "version %d.%d.%d", driver_version, driver_modification,
-@@ -3720,6 +3723,7 @@ sys_check_options(void)
+@@ -3711,6 +3714,7 @@ sys_check_options(void)
        warn("Warning: multilink is not supported by the kernel driver");
        multilink = 0;
      }
@@ -147,7 +147,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      info("PPPoE plugin from pppd %s", PPPD_VERSION);
 --- a/pppd/plugins/pppol2tp/pppol2tp.c
 +++ b/pppd/plugins/pppol2tp/pppol2tp.c
-@@ -501,10 +501,6 @@ static void pppol2tp_cleanup(void)
+@@ -502,10 +502,6 @@ static void pppol2tp_cleanup(void)
  void plugin_init(void)
  {
  #if defined(__linux__)
index 5738118c5f7e9fe6201d46099138b012d76bb9b5..d8194239f3c6d2f52d60ae422a141039cf52c386 100644 (file)
@@ -7,7 +7,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
 
 --- a/pppd/main.c
 +++ b/pppd/main.c
-@@ -982,14 +982,17 @@ struct protocol_list {
+@@ -991,14 +991,17 @@ struct protocol_list {
      const char        *name;
  } protocol_list[] = {
      { 0x21,   "IP" },
@@ -25,7 +25,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x33,   "Stream Protocol ST-II" },
      { 0x35,   "Banyan Vines" },
      { 0x39,   "AppleTalk EDDP" },
-@@ -1003,8 +1006,11 @@ struct protocol_list {
+@@ -1012,8 +1015,11 @@ struct protocol_list {
      { 0x49,   "Serial Data Transport Protocol (PPP-SDTP)" },
      { 0x4b,   "SNA over 802.2" },
      { 0x4d,   "SNA" },
@@ -37,7 +37,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x53,   "Encryption" },
      { 0x55,   "Individual Link Encryption" },
      { 0x57,   "IPv6" },
-@@ -1015,12 +1021,15 @@ struct protocol_list {
+@@ -1024,12 +1030,15 @@ struct protocol_list {
      { 0x65,   "RTP IPHC Compressed non-TCP" },
      { 0x67,   "RTP IPHC Compressed UDP 8" },
      { 0x69,   "RTP IPHC Compressed RTP 8" },
@@ -53,7 +53,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x0203, "IBM Source Routing BPDU" },
      { 0x0205, "DEC LANBridge100 Spanning Tree" },
      { 0x0207, "Cisco Discovery Protocol" },
-@@ -1032,15 +1041,19 @@ struct protocol_list {
+@@ -1041,15 +1050,19 @@ struct protocol_list {
      { 0x0231, "Luxcom" },
      { 0x0233, "Sigma Network Systems" },
      { 0x0235, "Apple Client Server Protocol" },
@@ -73,7 +73,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x4001, "Cray Communications Control Protocol" },
      { 0x4003, "CDPD Mobile Network Registration Protocol" },
      { 0x4005, "Expand accelerator protocol" },
-@@ -1051,8 +1064,10 @@ struct protocol_list {
+@@ -1060,8 +1073,10 @@ struct protocol_list {
      { 0x4023, "RefTek Protocol" },
      { 0x4025, "Fibre Channel" },
      { 0x4027, "EMIT Protocols" },
@@ -84,7 +84,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x8023, "OSI Network Layer Control Protocol" },
      { 0x8025, "Xerox NS IDP Control Protocol" },
      { 0x8027, "DECnet Phase IV Control Protocol" },
-@@ -1061,7 +1076,9 @@ struct protocol_list {
+@@ -1070,7 +1085,9 @@ struct protocol_list {
      { 0x8031, "Bridging NCP" },
      { 0x8033, "Stream Protocol Control Protocol" },
      { 0x8035, "Banyan Vines Control Protocol" },
@@ -94,7 +94,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x803f, "NETBIOS Framing Control Protocol" },
      { 0x8041, "Cisco Systems Control Protocol" },
      { 0x8043, "Ascom Timeplex" },
-@@ -1070,18 +1087,24 @@ struct protocol_list {
+@@ -1079,18 +1096,24 @@ struct protocol_list {
      { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" },
      { 0x804b, "SNA over 802.2 Control Protocol" },
      { 0x804d, "SNA Control Protocol" },
@@ -119,7 +119,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
      { 0x8207, "Cisco Discovery Protocol Control" },
      { 0x8209, "Netcs Twin Routing" },
      { 0x820b, "STP - Control Protocol" },
-@@ -1090,24 +1113,29 @@ struct protocol_list {
+@@ -1099,24 +1122,29 @@ struct protocol_list {
      { 0x8281, "MPLSCP" },
      { 0x8285, "IEEE p1284.4 standard - Protocol Control" },
      { 0x8287, "ETSI TETRA TNP1 Control Protocol" },
index 654bebd56920c7d7a419167edd4d6f564ad175e8..d70bf6c04a9aa79246b7b0cb9e9bcb6b96b5cab1 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Jo-Philipp Wich <jo@mein.io>
 
 --- a/pppd/options.c
 +++ b/pppd/options.c
-@@ -379,13 +379,14 @@ struct option general_options[] = {
+@@ -392,13 +392,14 @@ struct option general_options[] = {
        "Enable multilink operation", OPT_PRIOSUB | OPT_ALIAS | 1 },
      { "nomultilink", o_bool, &multilink,
        "Disable multilink operation", OPT_PRIOSUB | 0 },
index 38b0c82506584a17eabbc2276d5ea3b3fbec8f8b..e786ed42bd602525a0222f210eb5801fc5ae6c99 100644 (file)
@@ -1,9 +1,9 @@
 --- a/configure.ac
 +++ b/configure.ac
-@@ -333,6 +333,7 @@ AC_CONFIG_FILES([
-     pppd/plugins/pppoatm/Makefile
+@@ -334,6 +334,7 @@ AC_CONFIG_FILES([
      pppd/plugins/pppol2tp/Makefile
      pppd/plugins/radius/Makefile
+     pppd/plugins/dhcpv6relay/Makefile
 +    pppd/plugins/pptp/Makefile
      pppdump/Makefile
      pppstats/Makefile
@@ -14,8 +14,8 @@
  winbind_la_SOURCES = winbind.c
  
  if !SUNOS
--SUBDIRS = pppoe pppoatm pppol2tp radius
-+SUBDIRS = pppoe pppoatm pppol2tp radius pptp
+-SUBDIRS = pppoe pppoatm pppol2tp radius dhcpv6relay
++SUBDIRS = pppoe pppoatm pppol2tp radius dhcpv6relay pptp
  endif
 --- /dev/null
 +++ b/pppd/plugins/pptp/Makefile.am
diff --git a/package/network/services/ppp/patches/501-fix-memcpy-fortify.patch b/package/network/services/ppp/patches/501-fix-memcpy-fortify.patch
deleted file mode 100644 (file)
index b32f87f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-From f8d994052e3858848ce11318085e04fe7a1cfb28 Mon Sep 17 00:00:00 2001
-From: LGA1150 <9155358+LGA1150@users.noreply.github.com>
-Date: Thu, 5 Mar 2026 05:41:30 +0800
-Subject: [PATCH] pppd: fix memcpy overlap (#579)
-
-memcpy() with overlapping src and dest buffers is an undefined behavior
-in C. In the current code, a ConfRej response is generated by copying
-input data in-place, where the dest address is lower than the src.
-This happens to work in practice because memcpy() forward-copies data,
-matching the behavior of memmove() in this case.
-
-However, if FORTIFY_SOURCE or Address Sanitizer is enabled, memcpy()
-will detect the overlap at run time and abort the program.
-
-Replace the memcpy() with memmove() to ensure a well-defined behavior.
-
-Reported-by: Filippo Carletti <filippo.carletti@gmail.com>
-Closes: #576
-
-Signed-off-by: Qingfang Deng <dqfext@gmail.com>
----
- pppd/pppd-private.h | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/pppd/pppd-private.h b/pppd/pppd-private.h
-index 5f841824..29ea940c 100644
---- a/pppd/pppd-private.h
-+++ b/pppd/pppd-private.h
-@@ -525,7 +525,7 @@ int parse_dotted_ip(char *, u_int32_t *)
- #define TIMEOUT(r, f, t)      ppp_timeout((r), (f), (t), 0)
- #define UNTIMEOUT(r, f)               ppp_untimeout((r), (f))
--#define BCOPY(s, d, l)                memcpy(d, s, l)
-+#define BCOPY(s, d, l)                memmove(d, s, l)
- #define BZERO(s, n)           memset(s, 0, n)
- #define       BCMP(s1, s2, l)         memcmp(s1, s2, l)
diff --git a/package/network/services/ppp/patches/501-relax-and-simplify-permission-check.patch b/package/network/services/ppp/patches/501-relax-and-simplify-permission-check.patch
new file mode 100644 (file)
index 0000000..f059f90
--- /dev/null
@@ -0,0 +1,749 @@
+From 71d3d3a6703fce993432151d363f405b51e7b75c Mon Sep 17 00:00:00 2001
+From: Qingfang Deng <dqfext@gmail.com>
+Date: Fri, 12 Jun 2026 10:52:39 +0800
+Subject: [PATCH] pppd: relax and simplify permission check
+
+The additional check added in v2.5.3 is intended to mitigate symlink
+attacks, but it checks the permissions of every component of a path and
+is too strict, breaking existing configurations. Relax and simplify the
+check by only checking the opened file descriptor of a path, so the path
+is resolved only once.
+
+Signed-off-by: Qingfang Deng <dqfext@gmail.com>
+---
+ configure.ac        |   2 +
+ pppd/auth.c         | 146 +++++++++++++++++++++++++-------------------
+ pppd/main.c         |  46 ++++++++++----
+ pppd/options.c      |  56 +++++++++++++----
+ pppd/pppd-private.h |   2 +-
+ pppd/pppd.8         |  10 ---
+ pppd/pppd.h         |   2 +-
+ pppd/utils.c        |  84 ++++++-------------------
+ 8 files changed, 184 insertions(+), 164 deletions(-)
+
+--- a/configure.ac
++++ b/configure.ac
+@@ -2,6 +2,7 @@ AC_PREREQ([2.69])
+ AC_INIT([ppp],
+         [2.5.3],
+         [https://github.com/ppp-project/ppp])
++AC_USE_SYSTEM_EXTENSIONS
+ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])])
+ AC_CONFIG_MACRO_DIR([m4])
+@@ -93,6 +94,7 @@ AC_CHECK_SIZEOF(unsigned short)
+ # Checks for library functions.
+ AC_CHECK_FUNCS([    \
++    fexecve         \
+     mmap            \
+     logwtmp         \
+     strerror])
+--- a/pppd/auth.c
++++ b/pppd/auth.c
+@@ -307,7 +307,7 @@ static int  setupapfile (char **);
+ static int  privgroup (char **);
+ static int  set_noauth_addr (char **);
+ static int  set_permitted_number (char **);
+-static void check_access (FILE *, char *);
++static void check_access (int, const char *);
+ static int  wordlist_count (struct wordlist *);
+ static void check_maxoctets (void *);
+@@ -532,7 +532,7 @@ setupapfile(char **argv)
+         free(fname);
+       return 0;
+     }
+-    check_access(ufile, fname);
++    check_access(fileno(ufile), fname);
+     uafname = fname;
+     /* get username */
+@@ -1543,8 +1543,7 @@ check_passwd(int unit,
+      * Open the file of pap secrets and scan for a suitable secret
+      * for authenticating this user.
+      */
+-    if (!ppp_check_access(path_upapfile, &filename, 0, 0))
+-          return UPAP_AUTHNAK;
++    filename = path_upapfile;
+     addrs = opts = NULL;
+     ret = UPAP_AUTHNAK;
+     f = fopen(filename, "r");
+@@ -1552,7 +1551,13 @@ check_passwd(int unit,
+       error("Can't open PAP password file %s: %m", filename);
+     } else {
+-      check_access(f, filename);
++      int fd = fileno(f);
++
++      if (!ppp_check_access(fd, filename, 0)) {
++          fclose(f);
++          return UPAP_AUTHNAK;
++      }
++      check_access(fd, filename);
+       if (scan_authfile(f, user, our_name, secret, &addrs, &opts, filename, 0) < 0) {
+           warn("no PAP secret found for %s", user);
+       } else {
+@@ -1586,7 +1591,6 @@ check_passwd(int unit,
+       }
+       fclose(f);
+     }
+-    free(filename);
+     if (ret == UPAP_AUTHNAK) {
+         if (**msg == 0)
+@@ -1646,21 +1650,24 @@ null_login(int unit)
+      * Open the file of pap secrets and scan for a suitable secret.
+      */
+     if (ret <= 0) {
+-      if (!ppp_check_access(path_upapfile, &filename, 0, 0))
+-          return 0;
++      int fd;
++
++      filename = path_upapfile;
+       addrs = NULL;
+       f = fopen(filename, "r");
+-      if (f == NULL) {
+-          free(filename);
++      if (f == NULL)
++          return 0;
++      fd = fileno(f);
++      if (!ppp_check_access(fd, filename, 0)) {
++          fclose(f);
+           return 0;
+       }
+-      check_access(f, filename);
++      check_access(fd, filename);
+       i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0);
+       ret = i >= 0 && secret[0] == 0;
+       BZERO(secret, sizeof(secret));
+       fclose(f);
+-      free(filename);
+     }
+     if (ret)
+@@ -1701,7 +1708,7 @@ get_pap_passwd(char *passwd)
+     f = fopen(filename, "r");
+     if (f == NULL)
+       return 0;
+-    check_access(f, filename);
++    check_access(fileno(f), filename);
+     ret = scan_authfile(f, user,
+                       (remote_name[0]? remote_name: NULL),
+                       secret, NULL, NULL, filename, 0);
+@@ -1734,18 +1741,18 @@ have_pap_secret(int *lacks_ipp)
+           return ret;
+     }
+-    if (!ppp_check_access(path_upapfile, &filename, 0, 0))
+-      return 0;
++    filename = path_upapfile;
+     f = fopen(filename, "r");
+-    if (f == NULL) {
+-      free(filename);
++    if (f == NULL)
+       return 0;
+-    }
++    if (!ppp_check_access(fileno(f), filename, 0)) {
++      fclose(f);
++      return 0;
++    }
+     ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name,
+                       NULL, &addrs, NULL, filename, 0);
+     fclose(f);
+-    free(filename);
+     if (ret >= 0 && !some_ip_ok(addrs)) {
+       if (lacks_ipp != 0)
+           *lacks_ipp = 1;
+@@ -1780,11 +1787,13 @@ have_chap_secret(char *client, char *ser
+       }
+     }
+-    if (!ppp_check_access(path_chapfile, &filename, 0, 0))
+-          return 0;
++    filename = path_chapfile;
+     f = fopen(filename, "r");
+-    if (f == NULL) {
+-      free(filename);
++    if (f == NULL)
++      return 0;
++
++    if (!ppp_check_access(fileno(f), filename, 0)) {
++      fclose(f);
+       return 0;
+     }
+@@ -1795,7 +1804,6 @@ have_chap_secret(char *client, char *ser
+     ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
+     fclose(f);
+-    free(filename);
+     if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
+       if (lacks_ipp != 0)
+           *lacks_ipp = 1;
+@@ -1822,11 +1830,13 @@ have_srp_secret(char *client, char *serv
+     char *filename;
+     struct wordlist *addrs;
+-    if (!ppp_check_access(PPP_PATH_SRPFILE, &filename, 0, 0))
+-      return 0;
++    filename = PPP_PATH_SRPFILE;
+     f = fopen(filename, "r");
+-    if (f == NULL) {
+-      free(filename);
++    if (f == NULL)
++      return 0;
++
++    if (!ppp_check_access(fileno(f), filename, 0)) {
++      fclose(f);
+       return 0;
+     }
+@@ -1837,7 +1847,6 @@ have_srp_secret(char *client, char *serv
+     ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0);
+     fclose(f);
+-    free(filename);
+     if (ret >= 0 && need_ip && !some_ip_ok(addrs)) {
+       if (lacks_ipp != 0)
+           *lacks_ipp = 1;
+@@ -1874,22 +1883,27 @@ get_secret(int unit, char *client, char
+           return 0;
+       }
+     } else {
+-      if (!ppp_check_access(path_chapfile, &filename, 0, 0))
+-          return 0;
++      int fd;
++
++      filename = path_chapfile;
+       addrs = NULL;
+       secbuf[0] = 0;
+       f = fopen(filename, "r");
+       if (f == NULL) {
+           error("Can't open chap secret file %s: %m", filename);
+-          free(filename);
+           return 0;
+       }
+-      check_access(f, filename);
++
++      fd = fileno(f);
++      if (!ppp_check_access(fd, filename, 0)) {
++          fclose(f);
++          return 0;
++      }
++      check_access(fd, filename);
+       ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0);
+       fclose(f);
+-      free(filename);
+       if (ret < 0)
+           return 0;
+@@ -1931,23 +1945,27 @@ get_srp_secret(int unit, char *client, c
+     if (!am_server && passwd[0] != '\0') {
+       strlcpy(secret, passwd, MAXWORDLEN);
+     } else {
+-      if (!ppp_check_access(PPP_PATH_SRPFILE, &filename, 0, 0))
+-          return 0;
+-      addrs = NULL;
++      int fd;
++      filename = PPP_PATH_SRPFILE;
++      addrs = NULL;
+       fp = fopen(filename, "r");
+       if (fp == NULL) {
+           error("Can't open srp secret file %s: %m", filename);
+-          free(filename);
+           return 0;
+       }
+-      check_access(fp, filename);
++
++      fd = fileno(fp);
++      if (!ppp_check_access(fd, filename, 0)) {
++          fclose(fp);
++          return 0;
++      }
++      check_access(fd, filename);
+       secret[0] = '\0';
+       ret = scan_authfile(fp, client, server, secret, &addrs, &opts,
+           filename, am_server);
+       fclose(fp);
+-      free(filename);
+       if (ret < 0)
+           return 0;
+@@ -2214,11 +2232,11 @@ auth_number(void)
+  * check_access - complain if a secret file has too-liberal permissions.
+  */
+ static void
+-check_access(FILE *f, char *filename)
++check_access(int fd, const char *filename)
+ {
+     struct stat sbuf;
+-    if (fstat(fileno(f), &sbuf) < 0) {
++    if (fstat(fd, &sbuf) < 0) {
+       warn("cannot stat secret file %s: %m", filename);
+     } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) {
+       warn("Warning - secret file %s has world and/or group access",
+@@ -2326,25 +2344,25 @@ scan_authfile(FILE *f, char *client, cha
+            * Special syntax: @/pathname means read secret from file.
+            */
+           if (word[0] == '@' && word[1] == '/') {
+-              char *realname;
++              int fd;
+               strlcpy(atfile, word+1, sizeof(atfile));
+-              if (!ppp_check_access(atfile, &realname, 0, 0))
+-                  continue;
+-              if ((sf = fopen(realname, "r")) == NULL) {
++              if ((sf = fopen(atfile, "r")) == NULL) {
+                   warn("can't open indirect secret file %s", atfile);
+-                  free(realname);
+                   continue;
+               }
+-              check_access(sf, atfile);
++              fd = fileno(sf);
++              if (!ppp_check_access(fd, atfile, 0)) {
++                  fclose(sf);
++                  continue;
++              }
++              check_access(fd, atfile);
+               if (!getword(sf, word, &xxx, atfile)) {
+                   warn("no secret in indirect secret file %s", atfile);
+                   fclose(sf);
+-                  free(realname);
+                   continue;
+               }
+               fclose(sf);
+-              free(realname);
+           }
+           strlcpy(lsecret, word, sizeof(lsecret));
+       }
+@@ -2503,14 +2521,15 @@ have_eaptls_secret_server(char *client,
+     char cacertfile[MAXWORDLEN];
+     char pkfile[MAXWORDLEN];
+-    if (!ppp_check_access(PPP_PATH_EAPTLSSERVFILE, &filename, 0, 0))
+-      return 0;
++    filename = PPP_PATH_EAPTLSSERVFILE;
+     f = fopen(filename, "r");
+-    if (f == NULL) {
+-      free(filename);
++    if (f == NULL)
+       return 0;
+-    }
++    if (!ppp_check_access(fileno(f), filename, 0)) {
++      fclose(f);
++      return 0;
++    }
+     if (client != NULL && client[0] == 0)
+               client = NULL;
+     else if (server != NULL && server[0] == 0)
+@@ -2522,7 +2541,6 @@ have_eaptls_secret_server(char *client,
+                            0);
+     fclose(f);
+-    free(filename);
+ /*
+     if (ret >= 0 && !eaptls_init_ssl(1, cacertfile, servcertfile,
+@@ -2782,26 +2800,28 @@ get_eaptls_secret(int unit, char *client
+       }
+       else
+       {
++              int fd;
++
+               filename = (am_server ? PPP_PATH_EAPTLSSERVFILE : PPP_PATH_EAPTLSCLIFILE);
+               addrs = NULL;
+-              if (!ppp_check_access(filename, &filename, 0, 0))
+-                      return 0;
+               fp = fopen(filename, "r");
+-              if (fp == NULL)
+-              {
++              if (fp == NULL) {
+                       error("Can't open eap-tls secret file %s: %m", filename);
+-                      free(filename);
+                       return 0;
+               }
+-              check_access(fp, filename);
++              fd = fileno(fp);
++              if (!ppp_check_access(fd, filename, 0)) {
++                      fclose(fp);
++                      return 0;
++              }
++              check_access(fd, filename);
+               ret = scan_authfile_eaptls(fp, client, server, clicertfile, servcertfile,
+                               cacertfile, pkfile, &addrs, &opts, filename, 0);
+               fclose(fp);
+-              free(filename);
+               if (ret < 0) return 0;
+       }
+--- a/pppd/main.c
++++ b/pppd/main.c
+@@ -1952,22 +1952,37 @@ update_script_environment(void)
+ pid_t
+ run_program(char *prog, char * const *args, int must_exist, void (*done)(void *), void *arg, int wait)
+ {
+-    int pid, status, ret;
+-    char *rpath;
++    int fd, pid, status, ret;
+     /*
+      * First check if the file exists and is executable by root,
+      * and couldn't have been modified by a non-root process.
+      */
+-    if (!ppp_check_access(prog, &rpath, must_exist, 1))
++#if defined(O_PATH)
++    fd = open(prog, O_PATH);
++#elif defined(O_EXEC)
++    fd = open(prog, O_EXEC);
++#else
++    fd = open(prog, O_RDONLY);
++#endif
++    if (fd < 0) {
++      if (errno != ENOENT || must_exist)
++          error("Can't access %s: %m", prog);
++      return 0;
++    }
++    if (!ppp_check_access(fd, prog, 1)) {
++      close(fd);
+       return 0;
++    }
+     pid = ppp_safe_fork(fd_devnull, fd_devnull, fd_devnull);
+     if (pid == -1) {
+       error("Failed to create child process for %s: %m", prog);
++      close(fd);
+       return -1;
+     }
+     if (pid != 0) {
++      close(fd);
+       if (debug)
+           dbglog("Script %s started (pid %d)", prog, pid);
+       record_child(pid, prog, done, arg, 0);
+@@ -1979,7 +1994,6 @@ run_program(char *prog, char * const *ar
+           }
+           forget_child(pid, status);
+       }
+-      free(rpath);
+       return pid;
+     }
+@@ -2007,14 +2021,24 @@ run_program(char *prog, char * const *ar
+     /* run the program */
+     update_script_environment();
+-    execve(rpath, args, script_env);
+-    if (must_exist || errno != ENOENT) {
+-      /* have to reopen the log, there's nowhere else
+-         for the message to go. */
+-      reopen_log();
+-      syslog(LOG_ERR, "Can't execute %s: %m", rpath);
+-      closelog();
++#ifdef HAVE_FEXECVE
++    fexecve(fd, args, script_env);
++#else
++    {
++      char fdpath[32];
++
++      snprintf(fdpath, sizeof(fdpath), "/dev/fd/%d", fd);
++      execve(fdpath, args, script_env);
++      if (errno == ENOENT) {
++          snprintf(fdpath, sizeof(fdpath), "/proc/self/fd/%d", fd);
++          execve(fdpath, args, script_env);
++      }
+     }
++#endif
++    /* have to reopen the log, there's nowhere else for the message to go. */
++    reopen_log();
++    syslog(LOG_ERR, "Can't execute %s: %m", prog);
++    closelog();
+     _exit(99);
+ }
+--- a/pppd/options.c
++++ b/pppd/options.c
+@@ -210,6 +210,8 @@ static struct option *find_option(char *
+ static int process_option(struct option *, char *, char **);
+ static int n_arguments(struct option *);
+ static int number_option(char *, u_int32_t *, int);
++static int ppp_options_open(const char *, int, int, FILE **);
++static int ppp_options_from_fp(FILE *, const char *, int);
+ /*
+  * Structure to store extra lists of options.
+@@ -588,14 +590,23 @@ int
+ ppp_options_from_file(char *filename, int must_exist, int check_prot, int priv)
+ {
+     FILE *f;
+-    int i, newline, ret, err;
+-    struct option *opt;
+-    int oldpriv, n;
+-    char *oldsource;
++
++    if (!ppp_options_open(filename, must_exist, check_prot, &f))
++      return 0;
++    if (f == NULL)
++      return 1;
++    return ppp_options_from_fp(f, filename, priv);
++}
++
++/*
++ * ppp_options_open - Open a file for options
++ */
++static int
++ppp_options_open(const char *filename, int must_exist, int check_prot, FILE **fp)
++{
+     uid_t euid;
+-    char *argv[MAXARGS];
+-    char args[MAXARGS][MAXWORDLEN];
+-    char cmd[MAXWORDLEN];
++    FILE *f;
++    int err;
+     euid = geteuid();
+     if (check_prot && seteuid(getuid()) == -1) {
+@@ -606,6 +617,7 @@ ppp_options_from_file(char *filename, in
+     err = errno;
+     if (check_prot && seteuid(euid) == -1)
+       fatal("unable to regain privileges");
++    *fp = f;
+     if (f == NULL) {
+       errno = err;
+       if (!must_exist) {
+@@ -616,6 +628,22 @@ ppp_options_from_file(char *filename, in
+       ppp_option_error("Can't open options file %s: %m", filename);
+       return 0;
+     }
++    return 1;
++}
++
++/*
++ * Parse options from an open FILE pointer.
++ */
++static int
++ppp_options_from_fp(FILE *f, const char *filename, int priv)
++{
++    int i, newline, ret;
++    struct option *opt;
++    int oldpriv, n;
++    char *oldsource;
++    char *argv[MAXARGS];
++    char args[MAXARGS][MAXWORDLEN];
++    char cmd[MAXWORDLEN];
+     oldpriv = privileged_option;
+     privileged_option = priv;
+@@ -1371,7 +1399,7 @@ readable(int fd)
+  * \<newline> is ignored.
+  */
+ int
+-getword(FILE *f, char *word, int *newlinep, char *filename)
++getword(FILE *f, char *word, int *newlinep, const char *filename)
+ {
+     int c, len, escape;
+     int quoted, comment;
+@@ -1666,7 +1694,7 @@ callfile(char **argv)
+ {
+     char *fname, *arg, *p;
+     int l, ok;
+-    char *realname;
++    FILE *f;
+     arg = *argv;
+     ok = 1;
+@@ -1695,15 +1723,19 @@ callfile(char **argv)
+     slprintf(fname, l, "%s%s", PPP_PATH_PEERFILES, arg);
+     ppp_script_setenv("CALL_FILE", arg, 0);
+-    if (!ppp_check_access(fname, &realname, 1, 0)) {
++    if (!ppp_options_open(fname, 1, 1, &f)) {
++      free(fname);
++      return 0;
++    }
++    if (!ppp_check_access(fileno(f), fname, 0)) {
+       free(fname);
++      fclose(f);
+       return 0;
+     }
+-    ok = ppp_options_from_file(realname, 1, 1, 1);
++    ok = ppp_options_from_fp(f, fname, 1);
+     free(fname);
+-    free(realname);
+     return ok;
+ }
+--- a/pppd/pppd-private.h
++++ b/pppd/pppd-private.h
+@@ -470,7 +470,7 @@ int  get_first_ether_hwaddr(unsigned cha
+ int setipaddr(char *, char **, int); /* Set local/remote ip addresses */
+ int  parse_args(int argc, char **argv);
+                               /* Parse options from arguments given */
+-int  getword(FILE *f, char *word, int *newlinep, char *filename);
++int  getword(FILE *f, char *word, int *newlinep, const char *filename);
+                               /* Read a word from a file */
+ int  options_from_user(void); /* Parse options from user's .ppprc */
+ int  options_for_tty(void); /* Parse options from /etc/ppp/options.tty */
+--- a/pppd/pppd.8
++++ b/pppd/pppd.8
+@@ -1334,16 +1334,6 @@ file under /etc/ppp/peers, the system ad
+ establish a ppp connection via a device which they would not normally
+ have permission to access.  Otherwise pppd uses the invoking user's
+ real UID when opening the device.
+-.PP
+-To avoid the possibility of privileged options files, secrets files,
+-and other files which contain sensitive information being compromised,
+-\fIpppd\fR performs a path check on these files before opening them.
+-This involves first translating the file path into a real absolute path
+-containing no symlinks or ".." components.  Then each component from
+-the root down is checked to ensure that it is owned by root and that
+-its permissions do not permit writing by group or other.  Failure to
+-conform to these requirements will cause \fIpppd\fR to exit with a
+-suitable error message.
+ .SH AUTHENTICATION
+ Authentication is the process whereby one peer convinces the other of
+ its identity.  This involves the first peer sending its name to the
+--- a/pppd/pppd.h
++++ b/pppd/pppd.h
+@@ -300,7 +300,7 @@ void pr_log(void *, char *, ...);
+ void end_pr_log(void);
+ /* Check that a file can safely be used */
+-int ppp_check_access(const char *path, char **path_to_use, int must_exist, int exec);
++int ppp_check_access(int fd, const char *path, int exec);
+ /*
+  * Get the current exist status of pppd
+--- a/pppd/utils.c
++++ b/pppd/utils.c
+@@ -75,98 +75,50 @@ struct buffer_info {
+ };
+ /*
+- * Check that a file is owned by root, not writable by group or other,
+- * and that all the directories in the path leading to it is likewise
+- * owned by root and not writable by group or other.  The real path to
+- * the file is returned in *path_to_use, which should be freed after
+- * use (real meaning not containing any symlinks or ".." components).
++ * Check that a file descriptor is owned by root, not writable by group or
++ * other.
+  * If exec is true, check for execute permission, otherwise for read
+  * permission.
++ * Note: the path argument is only used for log messages.
+  * Returns 1 if OK; if not, prints an error message and returns 0.
+  */
+ int
+-ppp_check_access(const char *path, char **path_to_use, int must_exist, int exec)
++ppp_check_access(int fd, const char *path, int exec)
+ {
+-    char *rpath, *slash, *part;
+     struct stat sbuf;
+     int perm;
+-    /*
+-     * Resolve symlinks such that we eliminate a few potential ToCToU
+-     * attack avenues (eg, changing symlinks).
+-     */
+-    rpath = realpath(path, NULL);
+-    if (!rpath) {
+-      if (errno == ENOMEM)
+-          fatal("Insufficient memory for real path");
+-      if (must_exist || errno != ENOENT)
+-          error("Can't access %s: %m", path);
+-      return 0;
++    if (fstat(fd, &sbuf) != 0) {
++      error("Can't stat %v: %m", path);
++      goto err;
+     }
+-    /*
+-     * full check the entire path, must be root: owned, and NOT be writable
+-     * to group/other (which incorporates FACL bits somehow, so we can ignore
+-     * explicit FACL checks).
+-     */
+-    part = "/";
+-    slash = rpath;
+-    for (;;) {
+-      bool ok = false;
+-      const char *pname = (slash? part: "it");
+-
+-      if (lstat(part, &sbuf) != 0) {
+-          if (must_exist || errno != ENOENT) {
+-              if (!slash) {
+-                  error("Can't access %v: %m", rpath);
+-              } else {
+-                  error("Can't use %v, because of error accessing", path);
+-                  error("path component %v: %m");
+-              }
+-          }
+-          goto err;
+-      }
+-
+-      if (sbuf.st_uid != 0) {
+-          error("Can't safely use %v because %v is not owned by root",
+-                path, pname);
+-          goto err;
+-      }
+-
+-      if (0 != (sbuf.st_mode & (S_IWGRP | S_IWOTH))) {
+-          error("Can't safely use %v because %v is group or other writable",
+-                path, pname);
+-          goto err;
+-      }
+-
+-      if (!slash)
+-          break;
+-
+-      *slash = '/';
+-      part = rpath;
+-
+-      slash = strchr(slash + 1, '/');
+-      if (slash)
+-          *slash = 0;
++    if (!S_ISREG(sbuf.st_mode)) {
++      error("Can't use %v: not a regular file", path);
++      goto err;
+     }
+-    if (!S_ISREG(sbuf.st_mode)) {
+-      error("Can't use %v: not a regular file", rpath);
++    if (sbuf.st_uid != 0) {
++      error("Can't safely use %v because it is not owned by root", path);
++      goto err;
++    }
++
++    if (0 != (sbuf.st_mode & (S_IWGRP | S_IWOTH))) {
++      error("Can't safely use %v because it is group or other writable",
++            path);
+       goto err;
+     }
+     perm = exec? S_IXUSR : S_IRUSR;
+     if ((sbuf.st_mode & perm) == 0) {
+-      error("Can't use %v: not %sable by root", rpath,
++      error("Can't use %v: not %sable by root", path,
+             exec? "execut": "read");
+       goto err;
+     }
+-    *path_to_use = rpath;
+     return 1;
+  err:
+-    free(rpath);
+     return 0;
+ }
diff --git a/package/network/services/ppp/patches/502-remove_mru.patch b/package/network/services/ppp/patches/502-remove_mru.patch
deleted file mode 100644 (file)
index a1e093c..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-From f691c224e12ee13a1b317a1838d150f1ffef14a1 Mon Sep 17 00:00:00 2001
-From: Mateusz Poliwczak <mpoliwczak34@gmail.com>
-Date: Wed, 11 Feb 2026 00:40:14 +0100
-Subject: [PATCH] Remove MRU limit on PPPoE (#573)
-
-Fixes #331
-
-Signed-off-by: Mateusz Poliwczak <mpoliwczak34@gmail.com>
----
- pppd/plugins/pppoe/plugin.c | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/pppd/plugins/pppoe/plugin.c b/pppd/plugins/pppoe/plugin.c
-index b429a2fd..0f672166 100644
---- a/pppd/plugins/pppoe/plugin.c
-+++ b/pppd/plugins/pppoe/plugin.c
-@@ -446,11 +446,6 @@ void pppoe_check_options(void)
-     lcp_allowoptions[0].neg_pcompression = 0;
-     lcp_wantoptions[0].neg_pcompression = 0;
--    if (lcp_allowoptions[0].mru > MAX_PPPOE_MTU)
--      lcp_allowoptions[0].mru = MAX_PPPOE_MTU;
--    if (lcp_wantoptions[0].mru > MAX_PPPOE_MTU)
--      lcp_wantoptions[0].mru = MAX_PPPOE_MTU;
--
-     /* Save configuration */
-     conn->storedmtu = lcp_allowoptions[0].mru;
-     conn->storedmru = lcp_wantoptions[0].mru;