Reviewed-by: Jayaprakash N <n.jayaprak...@intel.com> 

Regards,
JP
-----Original Message-----
From: devel@edk2.groups.io <devel@edk2.groups.io> On Behalf Of Jayaprakash, N
Sent: Monday, August 28, 2023 4:01 PM
To: devel@edk2.groups.io
Cc: Jayaprakash, N <n.jayaprak...@intel.com>; Rebecca Cran <rebe...@bsdio.com>; 
Kinney, Michael D <michael.d.kin...@intel.com>; Kloper, Dimitry 
<dimitry.klo...@intel.com>
Subject: [edk2-devel] [edk2-libc Patch 1/1] edk2-libc: Socket completion 
functions are not called on Linux Compilation

REF: https://bugzilla.tianocore.org/show_bug.cgi?id=983

>From the bug description:
Analysis and root cause
----------------------------

After some investigation and debugging I have figured out the following:

The following function is implemented in file  edk2/StdLib/EfiSocketLib/Tcp4.c

VOID
EslTcp4ListenComplete (
  IN EFI_EVENT Event,
  IN ESL_PORT * pPort
);

The function is used in EslTcp4Listen() as a callback for connection 
notification event, it is created by the following code:

Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,
                            TPL_SOCKETS,
                            (EFI_EVENT_NOTIFY)EslTcp4ListenComplete,
                            pPort,
                            &pTcp4->ListenToken.CompletionToken.Event );

And this is actually introduces a bug: the CreateEvent() third parameter is of 
type EFI_EVENT_NOTIFY which is defined as

typedef
VOID
(EFIAPI *EFI_EVENT_NOTIFY) (
   IN EFI_EVENT Event,
   IN VOID *Context
);

That EFIAPI tag is important since it defines an ABI that is used by compiler 
in order to call the callback function. Note that EslTcp4ListenComplete() is 
not marked as EFIAPI.

Thus, on Linux, where gcc defaults to SYSV ABI, there will be mismatch between 
arguments passed to EslTcp4ListenComplete() by the event dispatcher. It expects 
function with WIN64 ABI, while its code compiled with default SYSV ABI. It will 
look in wrong registers for arguments.

Specifically pPort pointer references an wrong memory location. Luckily
EslTcp4ListenComplete() performs sanity check of the pPort structure and 
discovers that it is invalid. This causes discarding of all incoming 
connections.

Proposed fix
---------------

The fix is trivial - mark EslTcp4ListenComplete() as EFIAPI. This is a little 
more complicated, since there are additional callback functions that suffer 
from the same problem. In addition fixing those causes some compiler warnings 
that shall be addressed. Attached patch fixes the problem for me.

Cc: Rebecca Cran <rebe...@bsdio.com>
Cc: Michael D Kinney <michael.d.kin...@intel.com>
Cc: Jayaprakash N <n.jayaprak...@intel.com>
Signed-off-by: Dimitry Kloper <dimitry.klo...@intel.com>
---
 StdLib/EfiSocketLib/Ip4.c    | 11 +++++++----
 StdLib/EfiSocketLib/Socket.c |  5 +++--  StdLib/EfiSocketLib/Socket.h | 12 
++++++------
 StdLib/EfiSocketLib/Tcp4.c   | 35 ++++++++++++++++++++---------------
 StdLib/EfiSocketLib/Tcp6.c   | 35 ++++++++++++++++++++---------------
 StdLib/EfiSocketLib/Udp4.c   | 10 ++++++----
 StdLib/EfiSocketLib/Udp6.c   | 10 ++++++----
 7 files changed, 68 insertions(+), 50 deletions(-)

diff --git a/StdLib/EfiSocketLib/Ip4.c b/StdLib/EfiSocketLib/Ip4.c index 
4b8f05b..8d25537 100644
--- a/StdLib/EfiSocketLib/Ip4.c
+++ b/StdLib/EfiSocketLib/Ip4.c
@@ -588,16 +588,17 @@ EslIp4RemoteAddressSet (
   @param [in] pIo       The address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslIp4RxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   size_t LengthInBytes;
   ESL_PACKET * pPacket;
   EFI_IP4_RECEIVE_DATA * pRxData;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT *)context;
 
   DBG_ENTER ( );
 
@@ -1117,10 +1118,10 @@ EslIp4TxBuffer (
   @param [in] pIo       The address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslIp4TxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -1128,6 +1129,7 @@ EslIp4TxComplete (
   ESL_PACKET * pPacket;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
@@ -1341,6 +1343,7 @@ CONST ESL_PROTOCOL_API cEslIp4Api = {
   OFFSET_OF ( ESL_PORT, Context.Ip4.ModeData.ConfigData ),
   OFFSET_OF ( ESL_LAYER, pIp4List ),
   OFFSET_OF ( struct sockaddr_in, sin_zero ),
+
   sizeof ( struct sockaddr_in ),
   AF_INET,
   sizeof (((ESL_PACKET *)0 )->Op.Ip4Rx ), diff --git 
a/StdLib/EfiSocketLib/Socket.c b/StdLib/EfiSocketLib/Socket.c index 
59b8efa..ee15b62 100644
--- a/StdLib/EfiSocketLib/Socket.c
+++ b/StdLib/EfiSocketLib/Socket.c
@@ -3970,14 +3970,15 @@ EslSocketPortClose (
   @param[in]  Event     The close completion event
   @param[in]  pPort     Address of an ::ESL_PORT structure.
 **/
-VOID
+VOID EFIAPI
 EslSocketPortCloseComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   )
 {
   ESL_IO_MGMT * pIo;
   EFI_STATUS Status;
+  ESL_PORT * pPort = (ESL_PORT*) context;
 
   DBG_ENTER ( );
   VERIFY_AT_TPL ( TPL_SOCKETS );
diff --git a/StdLib/EfiSocketLib/Socket.h b/StdLib/EfiSocketLib/Socket.h index 
d7d55e6..81d3b2c 100644
--- a/StdLib/EfiSocketLib/Socket.h
+++ b/StdLib/EfiSocketLib/Socket.h
@@ -591,9 +591,9 @@ EFI_STATUS
 **/
 typedef
 VOID
-(* PFN_API_IO_COMPLETE) (
+(EFIAPI * PFN_API_IO_COMPLETE) (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *pIo //IN ESL_IO_MGMT * pIo
   );
 
 /**
@@ -909,9 +909,9 @@ EFI_STATUS
 **/
 typedef
 VOID
-(* PFN_API_TX_COMPLETE) (
+(EFIAPI * PFN_API_TX_COMPLETE) (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *pIo //IN ESL_IO_MGMT * pIo
   );
 
 /**
@@ -1433,10 +1433,10 @@ EslSocketPortClose (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslSocketPortCloseComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   );
 
 /**
diff --git a/StdLib/EfiSocketLib/Tcp4.c b/StdLib/EfiSocketLib/Tcp4.c index 
143b54b..0bd54ac 100644
--- a/StdLib/EfiSocketLib/Tcp4.c
+++ b/StdLib/EfiSocketLib/Tcp4.c
@@ -68,10 +68,10 @@ EslTcp4ConnectStart (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4ListenComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *contet
   );
 
 
@@ -185,10 +185,10 @@ EslTcp4Accept (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4ConnectComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   )
 {
   BOOLEAN bRemoveFirstPort;
@@ -197,6 +197,7 @@ EslTcp4ConnectComplete (
   ESL_SOCKET * pSocket;
   ESL_TCP4_CONTEXT * pTcp4;
   EFI_STATUS Status;
+  ESL_PORT * pPort = (ESL_PORT*)context;
 
   DBG_ENTER ( );
 
@@ -653,7 +654,7 @@ EslTcp4Listen (
         pTcp4 = &pPort->Context.Tcp4;
         Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,
                                     TPL_SOCKETS,
-                                    (EFI_EVENT_NOTIFY)EslTcp4ListenComplete,
+                                    EslTcp4ListenComplete,
                                     pPort,
                                     &pTcp4->ListenToken.CompletionToken.Event 
);
         if ( EFI_ERROR ( Status )) {
@@ -825,10 +826,10 @@ EslTcp4Listen (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4ListenComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   )
 {
   EFI_HANDLE ChildHandle;
@@ -842,6 +843,7 @@ EslTcp4ListenComplete (
   EFI_STATUS Status;
   EFI_HANDLE TcpPortHandle;
   EFI_STATUS TempStatus;
+  ESL_PORT * pPort = (ESL_PORT*)context;
 
   DBG_ENTER ( );
   VERIFY_AT_TPL ( TPL_SOCKETS );
@@ -1263,7 +1265,7 @@ EslTcp4PortAllocate (
     pTcp4 = &pPort->Context.Tcp4;
     Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,
                                  TPL_SOCKETS,
-                                 (EFI_EVENT_NOTIFY)EslSocketPortCloseComplete,
+                                 EslSocketPortCloseComplete,
                                  pPort,
                                  &pTcp4->CloseToken.CompletionToken.Event);
     if ( EFI_ERROR ( Status )) {
@@ -1282,7 +1284,7 @@ EslTcp4PortAllocate (
     //
     Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,
                                  TPL_SOCKETS,
-                                 (EFI_EVENT_NOTIFY)EslTcp4ConnectComplete,
+                                 EslTcp4ConnectComplete,
                                  pPort,
                                  &pTcp4->ConnectToken.CompletionToken.Event);
     if ( EFI_ERROR ( Status )) {
@@ -1732,16 +1734,17 @@ EslTcp4RemoteAddressSet (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4RxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   BOOLEAN bUrgent;
   size_t LengthInBytes;
   ESL_PACKET * pPacket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
@@ -2121,10 +2124,10 @@ EslTcp4TxBuffer (
   @param [in] pIo       The ESL_IO_MGMT structure address
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4TxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -2132,6 +2135,7 @@ EslTcp4TxComplete (
   ESL_PORT * pPort;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
@@ -2178,10 +2182,10 @@ EslTcp4TxComplete (
   @param [in] pIo       The ESL_IO_MGMT structure address
 
 **/
-VOID
+VOID EFIAPI
 EslTcp4TxOobComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -2189,6 +2193,7 @@ EslTcp4TxOobComplete (
   ESL_PORT * pPort;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
diff --git a/StdLib/EfiSocketLib/Tcp6.c b/StdLib/EfiSocketLib/Tcp6.c index 
2014298..62ebf00 100644
--- a/StdLib/EfiSocketLib/Tcp6.c
+++ b/StdLib/EfiSocketLib/Tcp6.c
@@ -68,10 +68,10 @@ EslTcp6ConnectStart (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6ListenComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *pPort // IN ESL_PORT * pPort
   );
 
 
@@ -179,10 +179,10 @@ EslTcp6Accept (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6ConnectComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   )
 {
   BOOLEAN bRemoveFirstPort;
@@ -191,6 +191,7 @@ EslTcp6ConnectComplete (
   ESL_SOCKET * pSocket;
   ESL_TCP6_CONTEXT * pTcp6;
   EFI_STATUS Status;
+  ESL_PORT * pPort = (ESL_PORT*)context;
 
   DBG_ENTER ( );
 
@@ -684,7 +685,7 @@ EslTcp6Listen (
         pTcp6 = &pPort->Context.Tcp6;
         Status = gBS->CreateEvent ( EVT_NOTIFY_SIGNAL,
                                     TPL_SOCKETS,
-                                    (EFI_EVENT_NOTIFY)EslTcp6ListenComplete,
+                                    EslTcp6ListenComplete,
                                     pPort,
                                     &pTcp6->ListenToken.CompletionToken.Event 
);
         if ( EFI_ERROR ( Status )) {
@@ -856,10 +857,10 @@ EslTcp6Listen (
   @param [in] pPort     Address of an ::ESL_PORT structure.
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6ListenComplete (
   IN EFI_EVENT Event,
-  IN ESL_PORT * pPort
+  IN VOID *context
   )
 {
   EFI_HANDLE ChildHandle;
@@ -873,6 +874,7 @@ EslTcp6ListenComplete (
   EFI_STATUS Status;
   EFI_HANDLE TcpPortHandle;
   EFI_STATUS TempStatus;
+  ESL_PORT * pPort = (ESL_PORT*)context;
 
   DBG_ENTER ( );
   VERIFY_AT_TPL ( TPL_SOCKETS );
@@ -1314,7 +1316,7 @@ EslTcp6PortAllocate (
     pTcp6 = &pPort->Context.Tcp6;
     Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,
                                  TPL_SOCKETS,
-                                 (EFI_EVENT_NOTIFY)EslSocketPortCloseComplete,
+                                 EslSocketPortCloseComplete,
                                  pPort,
                                  &pTcp6->CloseToken.CompletionToken.Event);
     if ( EFI_ERROR ( Status )) {
@@ -1333,7 +1335,7 @@ EslTcp6PortAllocate (
     //
     Status = gBS->CreateEvent (  EVT_NOTIFY_SIGNAL,
                                  TPL_SOCKETS,
-                                 (EFI_EVENT_NOTIFY)EslTcp6ConnectComplete,
+                                 EslTcp6ConnectComplete,
                                  pPort,
                                  &pTcp6->ConnectToken.CompletionToken.Event);
     if ( EFI_ERROR ( Status )) {
@@ -1801,16 +1803,17 @@ EslTcp6RemoteAddressSet (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6RxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   BOOLEAN bUrgent;
   size_t LengthInBytes;
   ESL_PACKET * pPacket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
@@ -2190,10 +2193,10 @@ EslTcp6TxBuffer (
   @param [in] pIo       The ESL_IO_MGMT structure address
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6TxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -2201,6 +2204,7 @@ EslTcp6TxComplete (
   ESL_PORT * pPort;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
@@ -2247,10 +2251,10 @@ EslTcp6TxComplete (
   @param [in] pIo       The ESL_IO_MGMT structure address
 
 **/
-VOID
+VOID EFIAPI
 EslTcp6TxOobComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -2258,6 +2262,7 @@ EslTcp6TxOobComplete (
   ESL_PORT * pPort;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
 
   DBG_ENTER ( );
 
diff --git a/StdLib/EfiSocketLib/Udp4.c b/StdLib/EfiSocketLib/Udp4.c index 
eafa014..ceaf3f4 100644
--- a/StdLib/EfiSocketLib/Udp4.c
+++ b/StdLib/EfiSocketLib/Udp4.c
@@ -484,16 +484,17 @@ EslUdp4RemoteAddressSet (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslUdp4RxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   size_t LengthInBytes;
   ESL_PACKET * pPacket;
   EFI_UDP4_RECEIVE_DATA * pRxData;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
   
   DBG_ENTER ( );
 
@@ -969,10 +970,10 @@ EslUdp4TxBuffer (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslUdp4TxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -980,6 +981,7 @@ EslUdp4TxComplete (
   ESL_PACKET * pPacket;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
   
   DBG_ENTER ( );
   
diff --git a/StdLib/EfiSocketLib/Udp6.c b/StdLib/EfiSocketLib/Udp6.c index 
67dbd32..dca55ec 100644
--- a/StdLib/EfiSocketLib/Udp6.c
+++ b/StdLib/EfiSocketLib/Udp6.c
@@ -478,16 +478,17 @@ EslUdp6RemoteAddressSet (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslUdp6RxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   size_t LengthInBytes;
   ESL_PACKET * pPacket;
   EFI_UDP6_RECEIVE_DATA * pRxData;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
   
   DBG_ENTER ( );
 
@@ -1021,10 +1022,10 @@ EslUdp6TxBuffer (
   @param [in] pIo       Address of an ::ESL_IO_MGMT structure
 
 **/
-VOID
+VOID EFIAPI
 EslUdp6TxComplete (
   IN EFI_EVENT Event,
-  IN ESL_IO_MGMT * pIo
+  IN VOID *context
   )
 {
   UINT32 LengthInBytes;
@@ -1032,6 +1033,7 @@ EslUdp6TxComplete (
   ESL_PACKET * pPacket;
   ESL_SOCKET * pSocket;
   EFI_STATUS Status;
+  ESL_IO_MGMT * pIo = (ESL_IO_MGMT*)context;
   
   DBG_ENTER ( );
   
--
2.40.0.windows.1








-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#108112): https://edk2.groups.io/g/devel/message/108112
Mute This Topic: https://groups.io/mt/101046088/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to