lkml.org 
[lkml]   [2019]   [Aug]   [8]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.2 53/56] compat_ioctl: pppoe: fix PPPOEIOCSFWD handling
    Date
    From: Arnd Bergmann <arnd@arndb.de>

    [ Upstream commit 055d88242a6046a1ceac3167290f054c72571cd9 ]

    Support for handling the PPPOEIOCSFWD ioctl in compat mode was added in
    linux-2.5.69 along with hundreds of other commands, but was always broken
    sincen only the structure is compatible, but the command number is not,
    due to the size being sizeof(size_t), or at first sizeof(sizeof((struct
    sockaddr_pppox)), which is different on 64-bit architectures.

    Guillaume Nault adds:

    And the implementation was broken until 2016 (see 29e73269aa4d ("pppoe:
    fix reference counting in PPPoE proxy")), and nobody ever noticed. I
    should probably have removed this ioctl entirely instead of fixing it.
    Clearly, it has never been used.

    Fix it by adding a compat_ioctl handler for all pppoe variants that
    translates the command number and then calls the regular ioctl function.

    All other ioctl commands handled by pppoe are compatible between 32-bit
    and 64-bit, and require compat_ptr() conversion.

    This should apply to all stable kernels.

    Acked-by: Guillaume Nault <g.nault@alphalink.fr>
    Signed-off-by: Arnd Bergmann <arnd@arndb.de>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ppp/pppoe.c | 3 +++
    drivers/net/ppp/pppox.c | 13 +++++++++++++
    drivers/net/ppp/pptp.c | 3 +++
    fs/compat_ioctl.c | 3 ---
    include/linux/if_pppox.h | 3 +++
    net/l2tp/l2tp_ppp.c | 3 +++
    6 files changed, 25 insertions(+), 3 deletions(-)

    --- a/drivers/net/ppp/pppoe.c
    +++ b/drivers/net/ppp/pppoe.c
    @@ -1115,6 +1115,9 @@ static const struct proto_ops pppoe_ops
    .recvmsg = pppoe_recvmsg,
    .mmap = sock_no_mmap,
    .ioctl = pppox_ioctl,
    +#ifdef CONFIG_COMPAT
    + .compat_ioctl = pppox_compat_ioctl,
    +#endif
    };

    static const struct pppox_proto pppoe_proto = {
    --- a/drivers/net/ppp/pppox.c
    +++ b/drivers/net/ppp/pppox.c
    @@ -17,6 +17,7 @@
    #include <linux/string.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    +#include <linux/compat.h>
    #include <linux/errno.h>
    #include <linux/netdevice.h>
    #include <linux/net.h>
    @@ -98,6 +99,18 @@ int pppox_ioctl(struct socket *sock, uns

    EXPORT_SYMBOL(pppox_ioctl);

    +#ifdef CONFIG_COMPAT
    +int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
    +{
    + if (cmd == PPPOEIOCSFWD32)
    + cmd = PPPOEIOCSFWD;
    +
    + return pppox_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
    +}
    +
    +EXPORT_SYMBOL(pppox_compat_ioctl);
    +#endif
    +
    static int pppox_create(struct net *net, struct socket *sock, int protocol,
    int kern)
    {
    --- a/drivers/net/ppp/pptp.c
    +++ b/drivers/net/ppp/pptp.c
    @@ -623,6 +623,9 @@ static const struct proto_ops pptp_ops =
    .recvmsg = sock_no_recvmsg,
    .mmap = sock_no_mmap,
    .ioctl = pppox_ioctl,
    +#ifdef CONFIG_COMPAT
    + .compat_ioctl = pppox_compat_ioctl,
    +#endif
    };

    static const struct pppox_proto pppox_pptp_proto = {
    --- a/fs/compat_ioctl.c
    +++ b/fs/compat_ioctl.c
    @@ -638,9 +638,6 @@ COMPATIBLE_IOCTL(PPPIOCDISCONN)
    COMPATIBLE_IOCTL(PPPIOCATTCHAN)
    COMPATIBLE_IOCTL(PPPIOCGCHAN)
    COMPATIBLE_IOCTL(PPPIOCGL2TPSTATS)
    -/* PPPOX */
    -COMPATIBLE_IOCTL(PPPOEIOCSFWD)
    -COMPATIBLE_IOCTL(PPPOEIOCDFWD)
    /* Big A */
    /* sparc only */
    /* Big Q for sound/OSS */
    --- a/include/linux/if_pppox.h
    +++ b/include/linux/if_pppox.h
    @@ -80,6 +80,9 @@ extern int register_pppox_proto(int prot
    extern void unregister_pppox_proto(int proto_num);
    extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
    extern int pppox_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
    +extern int pppox_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
    +
    +#define PPPOEIOCSFWD32 _IOW(0xB1 ,0, compat_size_t)

    /* PPPoX socket states */
    enum {
    --- a/net/l2tp/l2tp_ppp.c
    +++ b/net/l2tp/l2tp_ppp.c
    @@ -1681,6 +1681,9 @@ static const struct proto_ops pppol2tp_o
    .recvmsg = pppol2tp_recvmsg,
    .mmap = sock_no_mmap,
    .ioctl = pppox_ioctl,
    +#ifdef CONFIG_COMPAT
    + .compat_ioctl = pppox_compat_ioctl,
    +#endif
    };

    static const struct pppox_proto pppol2tp_proto = {

    \
     
     \ /
      Last update: 2019-08-08 21:26    [W:2.384 / U:0.028 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site