Bug 2042196

Summary: fix use-after-free accessing error number after rpc call returns an error
Product: Red Hat Enterprise Linux 8 Reporter: Frank Sorenson <fsorenso>
Component: libtirpcAssignee: Steve Dickson <steved>
Status: CLOSED ERRATA QA Contact: JianHong Yin <jiyin>
Severity: low Docs Contact:
Priority: unspecified    
Version: 8.4CC: xzhou
Target Milestone: rcKeywords: Patch, Reproducer, Triaged
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: libtirpc-1.1.4-7.el8 Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2022-11-08 10:51:52 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:
Deadline: 2022-06-20   

Description Frank Sorenson 2022-01-19 00:25:44 UTC
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 6 errata-xmlrpc 2022-11-08 10:51:52 UTC
Since the problem described in this bug report should be
resolved in a recent advisory, it has been closed with a
resolution of ERRATA.

For information on the advisory (libtirpc bug fix and enhancement update), and where to find the updated
files, follow the link below.

If the solution does not work for you, open a new bug report.

https://access.redhat.com/errata/RHBA-2022:7740