summaryrefslogtreecommitdiff
path: root/drivers/pptp/gre.c
diff options
context:
space:
mode:
authorDenys Fedoryshchenko <denys.f@collabora.com>2026-08-09 06:54:53 +0300
committerDenys Fedoryshchenko <denys.f@collabora.com>2026-08-09 13:30:39 +0300
commit49a94430c090068ca96f1dc38ed24cd93c2e324d (patch)
tree25cfcecac00c6326ba3ffb0414895989832a45ce /drivers/pptp/gre.c
parent11271e9019ef1511b127b75e1c69e9c57f9cba49 (diff)
downloadaccel-ppp-49a94430c090068ca96f1dc38ed24cd93c2e324d.tar.gz
accel-ppp-49a94430c090068ca96f1dc38ed24cd93c2e324d.zip
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.
Diffstat (limited to 'drivers/pptp/gre.c')
-rw-r--r--drivers/pptp/gre.c220
1 files changed, 0 insertions, 220 deletions
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 <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/skbuff.h>
-#include <linux/in.h>
-#include <linux/netdevice.h>
-#include <linux/version.h>
-#include <linux/spinlock.h>
-#include <net/protocol.h>
-
-#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);