From 49a94430c090068ca96f1dc38ed24cd93c2e324d Mon Sep 17 00:00:00 2001 From: Denys Fedoryshchenko Date: Sun, 9 Aug 2026 06:54:53 +0300 Subject: pptp: drop the out-of-tree kernel driver drivers/pptp is version 0.8.5 of the PPTP driver, the direct ancestor of mainline drivers/net/ppp/pptp.c. Mainline merged that code in 2.6.37 (2011) from the same author and has maintained it since; this copy received none of the subsequent fixes and is no longer worth carrying: - It cannot be built. struct flowi's nl_u union, the 3-argument ip_route_output_key(), sock_no_poll, the old ip_select_ident() signature and nf_reset() all disappeared long ago, so nothing past roughly 2.6.36 compiles and -DBUILD_PPTP_DRIVER=TRUE is a build failure everywhere. - It is not needed. The PPTP bits of accel-pppd/include/if_pppox.h are identical to the mainline UAPI header, so ctrl/pptp's socket(AF_PPPOX, SOCK_STREAM, PX_PROTO_PPTP) reaches the in-kernel module (alias net-pf-24-proto-2) unchanged. The daemon uses no interface the bundled driver added. The deleted drivers/pptp/if_pppox.h was included only by drivers/pptp/pptp.c; all other if_pppox.h includes use either the kernel UAPI header or accel-pppd's userspace copy. - It is unsafe. Among others: the pskb_may_pull() in pptp_rcv() is commented out, so the GRE header is parsed with no length validation at all; the skb->len - headersize comparison in pptp_rcv_core() underflows and leads to an out-of-bounds read and a negative skb_pull(); pptp_getname() copies uninitialised stack to userspace; and pptp_bind()/pptp_connect() never check sockaddr_len (CVE-2015-8569). Mainline fixed each of these years ago. Remove the directory along with the BUILD_PPTP_DRIVER option, the accel-pptp-kmod package and the ip_gre conflict warning, which only existed because this module claimed IPPROTO_GRE. accel-pppd/ctrl/pptp and accel-pppd/include/if_pppox.h are unaffected. PPTP now requires the kernel's own pptp module; kernels older than 2.6.37 are no longer supported. --- drivers/pptp/gre.c | 220 ----------------------------------------------------- 1 file changed, 220 deletions(-) delete mode 100644 drivers/pptp/gre.c (limited to 'drivers/pptp/gre.c') diff --git a/drivers/pptp/gre.c b/drivers/pptp/gre.c deleted file mode 100644 index a3c9625a..00000000 --- a/drivers/pptp/gre.c +++ /dev/null @@ -1,220 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "gre.h" - -struct gre_protocol *gre_proto[GREPROTO_MAX] ____cacheline_aligned_in_smp; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static rwlock_t gre_proto_lock=RW_LOCK_UNLOCKED; -#else -static DEFINE_SPINLOCK(gre_proto_lock); -#endif - -int gre_add_protocol(struct gre_protocol *proto, u8 version) -{ - int ret; - - if (version >= GREPROTO_MAX) - return -EINVAL; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - write_lock_bh(&gre_proto_lock); -#else - spin_lock(&gre_proto_lock); -#endif - if (gre_proto[version]) { - ret = -EAGAIN; - } else { -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - gre_proto[version] = proto; -#else - rcu_assign_pointer(gre_proto[version], proto); -#endif - ret = 0; - } -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - write_unlock_bh(&gre_proto_lock); -#else - spin_unlock(&gre_proto_lock); -#endif - - return ret; -} - -int gre_del_protocol(struct gre_protocol *proto, u8 version) -{ - if (version >= GREPROTO_MAX) - goto out_err; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - write_lock_bh(&gre_proto_lock); -#else - spin_lock(&gre_proto_lock); -#endif - if (gre_proto[version] == proto) -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - gre_proto[version] = NULL; -#else - rcu_assign_pointer(gre_proto[version], NULL); -#endif - else - goto out_err_unlock; -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - write_unlock_bh(&gre_proto_lock); -#else - spin_unlock(&gre_proto_lock); - synchronize_rcu(); -#endif - return 0; - -out_err_unlock: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - write_unlock_bh(&gre_proto_lock); -#else - spin_unlock(&gre_proto_lock); -#endif -out_err: - return -EINVAL; -} - -static int gre_rcv(struct sk_buff *skb) -{ - u8 ver; - int ret; - struct gre_protocol *proto; - - if (!pskb_may_pull(skb, 12)) - goto drop_nolock; - - ver = skb->data[1]&0x7f; - if (ver >= GREPROTO_MAX) - goto drop_nolock; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_lock(&gre_proto_lock); - proto = gre_proto[ver]; -#else - rcu_read_lock(); - proto = rcu_dereference(gre_proto[ver]); -#endif - if (!proto || !proto->handler) - goto drop; - - ret = proto->handler(skb); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_unlock(&gre_proto_lock); -#else - rcu_read_unlock(); -#endif - - return ret; - -drop: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_unlock(&gre_proto_lock); -#else - rcu_read_unlock(); -#endif -drop_nolock: - kfree_skb(skb); - return NET_RX_DROP; -} - -static void gre_err(struct sk_buff *skb, u32 info) -{ - u8 ver; - struct gre_protocol *proto; - - if (!pskb_may_pull(skb, 12)) - goto drop_nolock; - - ver=skb->data[1]&0x7f; - if (ver>=GREPROTO_MAX) - goto drop_nolock; - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_lock(&gre_proto_lock); - proto = gre_proto[ver]; -#else - rcu_read_lock(); - proto = rcu_dereference(gre_proto[ver]); -#endif - if (!proto || !proto->err_handler) - goto drop; - - proto->err_handler(skb, info); -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_unlock(&gre_proto_lock); -#else - rcu_read_unlock(); -#endif - - return; - -drop: -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - read_unlock(&gre_proto_lock); -#else - rcu_read_unlock(); -#endif -drop_nolock: - kfree_skb(skb); -} - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) -static struct inet_protocol net_gre_protocol = { - .handler = gre_rcv, - .err_handler = gre_err, - .protocol = IPPROTO_GRE, - .name = "GRE", -}; -#else -static struct net_protocol net_gre_protocol = { - .handler = gre_rcv, - .err_handler = gre_err, -#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,24) - .netns_ok=1, -#endif -}; -#endif - -static int __init gre_init(void) -{ - printk(KERN_INFO "GRE over IPv4 demultiplexor driver"); - -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - inet_add_protocol(&net_gre_protocol); -#else - if (inet_add_protocol(&net_gre_protocol, IPPROTO_GRE) < 0) { - printk(KERN_INFO "gre: can't add protocol\n"); - return -EAGAIN; - } -#endif - return 0; -} - -static void __exit gre_exit(void) -{ -#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) - inet_del_protocol(&net_gre_protocol); -#else - inet_del_protocol(&net_gre_protocol, IPPROTO_GRE); -#endif -} - -module_init(gre_init); -module_exit(gre_exit); - -MODULE_DESCRIPTION("GRE over IPv4 demultiplexor driver"); -MODULE_AUTHOR("Kozlov D. (xeb@mail.ru)"); -MODULE_LICENSE("GPL"); -EXPORT_SYMBOL_GPL(gre_add_protocol); -EXPORT_SYMBOL_GPL(gre_del_protocol); -- cgit v1.2.3