• Vasily Averin's avatar
    sunrpc: use-after-free in svc_process_common() · d4b09acf
    Vasily Averin authored
    if node have NFSv41+ mounts inside several net namespaces
    it can lead to use-after-free in svc_process_common()
    
    svc_process_common()
            /* Setup reply header */
            rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr(rqstp); <<< HERE
    
    svc_process_common() can use incorrect rqstp->rq_xprt,
    its caller function bc_svc_process() takes it from serv->sv_bc_xprt.
    The problem is that serv is global structure but sv_bc_xprt
    is assigned per-netnamespace.
    
    According to Trond, the whole "let's set up rqstp->rq_xprt
    for the back channel" is nothing but a giant hack in order
    to work around the fact that svc_process_common() uses it
    to find the xpt_ops, and perform a couple of (meaningless
    for the back channel) tests of xpt_flags.
    
    All we really need in svc_process_common() is to be able to run
    rqstp->rq_xprt->xpt_ops->xpo_prep_reply_hdr()
    
    Bruce J Fields points that this xpo_prep_reply_hdr() call
    is an awfully roundabout way just to do "svc_putnl(resv, 0);"
    in the tcp case.
    
    This patch does not initialiuze rqstp->rq_xprt in bc_svc_process(),
    now it calls svc_process_common() with rqstp->rq_xprt = NULL.
    
    To adjust reply header svc_process_common() just check
    rqstp->rq_prot and calls svc_tcp_prep_reply_hdr() for tcp case.
    
    To handle rqstp->rq_xprt = NULL case in functions called from
    svc_process_common() patch intruduces net namespace pointer
    svc_rqst->rq_bc_net and adjust SVC_NET() definition.
    Some other function was also adopted to properly handle described case.
    Signed-off-by: default avatarVasily Averin <vvs@virtuozzo.com>
    Cc: stable@vger.kernel.org
    Fixes: 23c20ecd ("NFS: callback up - users counting cleanup")
    Signed-off-by: default avatarJ. Bruce Fields <bfields@redhat.com>
    d4b09acf
svcsock.c 41.4 KB