Bug 2113931

Summary: fix use-after-free accessing error number after rpc call returns an error
Product: Red Hat Enterprise Linux 9 Reporter: Zhi Li <yieli>
Component: libtirpcAssignee: Steve Dickson <steved>
Status: CLOSED DUPLICATE QA Contact: Zhi Li <yieli>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 9.1CC: jiyin, xzhou
Target Milestone: rcKeywords: Patch, Reproducer, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-08-16 14:03:05 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Zhi Li 2022-08-02 10:57:19 UTC
This bug was initially created as a copy of Bug #2042196

I am copying this bug because: 

It seems this problem exists in rhel9.

Version-Release number of selected component (if applicable):
kernel-5.14.0-138.el9.x86_64
libtirpc-1.3.2-1.el9.x86_64

Beaker jobs:
https://beaker.engineering.redhat.com/jobs/6876111


Description of problem:

When an rpc call returns an error, lirbirpc frees the memory associated with the call before obtaining the error number stored in that memory.


Version-Release number of selected component (if applicable):

libtirpc-1.1.4-6.el8


How reproducible:

easy


Steps to Reproduce:

* add iptables rule to reject udp incoming to port 111:

	# iptables -I INPUT -p udp --dport 111 -j REJECT --reject-with=icmp-host-prohibited

* make rpc call over udp

	# valgrind rpcinfo -T udp localhost


Actual results:

# valgrind rpcinfo -T udp localhost
==2799905== Memcheck, a memory error detector
==2799905== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==2799905== Using Valgrind-3.18.1 and LibVEX; rerun with -h for copyright info
==2799905== Command: rpcinfo -T udp localhost
==2799905== 
==2799905== Invalid read of size 4
==2799905==    at 0x4E4F2B1: ??? (in /usr/lib64/libtirpc.so.3.0.0)
==2799905==    by 0x10B819: rpcbdump (rpcinfo.c:831)
==2799905==    by 0x109EE5: main (rpcinfo.c:302)
==2799905==  Address 0x74287a0 is 16 bytes inside a block of size 296 free'd
==2799905==    at 0x4C34A93: free (vg_replace_malloc.c:872)
==2799905==    by 0x4E4F2A8: ??? (in /usr/lib64/libtirpc.so.3.0.0)
==2799905==    by 0x10B819: rpcbdump (rpcinfo.c:831)
==2799905==    by 0x109EE5: main (rpcinfo.c:302)
==2799905==  Block was alloc'd at
==2799905==    at 0x4C36E4B: calloc (vg_replace_malloc.c:1328)
==2799905==    by 0x4E4F098: ??? (in /usr/lib64/libtirpc.so.3.0.0)
==2799905==    by 0x10B819: rpcbdump (rpcinfo.c:831)
==2799905==    by 0x109EE5: main (rpcinfo.c:302)


Expected results:

no use-after-free


Additional info:


The clnt_dg_call error handling reads the error number after it frees the memory that contains the error:

            for (cmsg = CMSG_FIRSTHDR (&msg); cmsg;
                 cmsg = CMSG_NXTHDR (&msg, cmsg))
              if (cmsg->cmsg_level == SOL_IP && cmsg->cmsg_type == IP_RECVERR)
                {
                  mem_free(cbuf, (outlen + 256));               <<<<<<<< 'cbuf' freed
                  e = (struct sock_extended_err *) CMSG_DATA(cmsg);
                  cu->cu_error.re_errno = e->ee_errno;          <<<<<<<< 'e' is a pointer to a location within 'cbuf' that was just freed
                  release_fd_lock(cu->cu_fd_lock, mask);
                  return (cu->cu_error.re_status = RPC_CANTRECV);
                }

patch sent upstream https://www.spinics.net/lists/linux-nfs/msg88447.html

Comment 1 Steve Dickson 2022-08-04 20:47:43 UTC
commit d0dc59e27263c6b53435d770010dcc6f397d58ee
Author: Frank Sorenson <sorenson>
Date:   Mon Jan 17 13:33:13 2022 -0500

    libtirpc: Fix use-after-free accessing the error number
    
    Free the cbuf after obtaining the error number.
    
    Signed-off-by: Frank Sorenson <sorenson>
    Signed-off-by: Steve Dickson <steved>

Comment 2 Steve Dickson 2022-08-16 14:03:05 UTC

*** This bug has been marked as a duplicate of bug 2118157 ***