From: "Jayaprakash, N" <n.jayaprakash@intel.com>
To: devel@edk2.groups.io
Cc: Jayaprakash N <n.jayaprakash@intel.com>,
Rebecca Cran <rebecca@bsdio.com>,
Michael D Kinney <michael.d.kinney@intel.com>,
Dimitry Kloper <dimitry.kloper@intel.com>
Subject: [edk2-devel] [edk2-libc Patch 1/1] edk2-libc: Socket completion functions are not called on Linux Compilation
Date: Mon, 28 Aug 2023 16:01:06 +0530 [thread overview]
Message-ID: <20230828103106.1624-2-n.jayaprakash@intel.com> (raw)
In-Reply-To: <20230828103106.1624-1-n.jayaprakash@intel.com>
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 <rebecca@bsdio.com>
Cc: Michael D Kinney <michael.d.kinney@intel.com>
Cc: Jayaprakash N <n.jayaprakash@intel.com>
Signed-off-by: Dimitry Kloper <dimitry.kloper@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 (#108056): https://edk2.groups.io/g/devel/message/108056
Mute This Topic: https://groups.io/mt/101006991/7686176
Group Owner: devel+owner@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io]
-=-=-=-=-=-=-=-=-=-=-=-
next prev parent reply other threads:[~2023-08-28 10:31 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2023-08-28 10:31 [edk2-devel] [edk2-libc Patch 0/1] Socket completion functions not called on Linux Compilation Jayaprakash, N
2023-08-28 10:31 ` Jayaprakash, N [this message]
[not found] ` <177F857066635B47.29523@groups.io>
2023-08-30 3:20 ` [edk2-devel] [edk2-libc Patch 1/1] edk2-libc: Socket completion functions are " Jayaprakash, N
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20230828103106.1624-2-n.jayaprakash@intel.com \
--to=devel@edk2.groups.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox