fix: recvfrom() error handling
Hello List,
while chasing an unrelated bug i found the description of recvfrom() was missing some error description. I would suggest to add a few lines to make this confusing state more clear.
CU
recv.2 renamed from recv.2.org +17 -0
@@ -299,6 +299,23 @@ and .I addrlen should be specified as NULL. +If +.I src_addr +is NULL +.I addrlen +will be ignored. + +If +.I src_addr +is not NULL and +.I addrlen +is less than null the call will return with +.IR EINVAL . +If +.I addrlen +is less than sizeof struct sockaddr_in the src_addr will +not be modified. + .\" .SS recv() The
Alejandro Colomar
maintainerHi Peter,
recv.2
Quoted 9 lines · Peter Radisson
Hello List,
while chasing an unrelated bug i found the description ofrecvfrom()was missing some error description. I would suggest to add a few lines to make this confusing state more clear.CU
recv.2 renamed from recv.2.org +0
-0
Could you please use git-format-patch(1)?
recv.2 line 307
Quoted 10 lines
recv.2 renamed from recv.2.org +6
-0@@ -299,6 +299,23 @@ and .I addrlen should be specified as NULL. +If +.I src_addr +is NULL +.I addrlen +will be ignored. +
Please don't use blank lines in man(7) source. Use paragraphing macros (.P is for a normal paragraph, and .IP is an indented paragraph).
recv.2 line 312
Quoted 5 lines
recv.2 renamed from recv.2.org +5
-0+If +.I src_addr +is not NULL and +.I addrlen +is less than null the call will return with
What do you mean by "less than null"? Pointers don't have a sign, so it's not possible to have a pointer be less than null.
alx@devuan:~/tmp$ cat p.c
int
main(void)
{
void *p = (void *) -1;return p < (void *) 0; } alx@devuan:~/tmp$ gcc -Wall -Wextra -Wtautological-compare p.c p.c: In function ‘main’: p.c:6:18: warning: ordered comparison of pointer with null pointer [-Wextra] 6 | return p < (void *) 0; | ^ alx@devuan:~/tmp$ ./a.out alx@devuan:~/tmp$ echo $? 0
Have a lovely day!
Alex
Quoted 10 lines
recv.2 renamed from recv.2.org +6
-0+.IR EINVAL . +If +.I addrlen +is less than sizeof struct sockaddr_in the src_addr will +not be modified. + .\" .SS recv() The
Signature · 1 line
<https://www.alejandro-colomar.es/>
V2:
* removed 1 empty line
* and changed wording to "content of" to make clear *addrlen is used.
To replicate the problem:
// intended use
struct sockaddr_in sock_out;
int slen=sizeof(sock_out); //socklen_trecv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);
// error case
struct sockaddr_in sock_out;
int slen=1;recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);
funfact: this escapes the error handling in the linux kernel (no crash) set slen=-1 and you get EINVAL.
hope that helps.
From 056b50b50dca9f08d203d1d56fdcb6e84d228dba Mon Sep 17 00:00:00 2001
From: Peter Radisson <--show-origin>
Date: Thu, 27 Mar 2025 17:05:51 +0100
Subject: [PATCH] Be more verbose about recvfrom(2) error handling
--- man2/recv.2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
man2/recv.2 +0 -0
@@ -293,6 +293,22 @@ The returned address is truncated if the buffer
provided is too small;
in this case,
.I addrlen
will return a value greater than was supplied to the call.
+If
+.I src_addr
+is NULL
+.I addrlen
+will be ignored.
+If
+.I src_addr
+is not NULL and the content of
+.I addrlen
+is less than null the call will return with
+.IR EINVAL .
+If
+.I addrlen
+is less than sizeof struct sockaddr_in the src_addr will +not be modified.
+
.PP
If the caller is not interested in the source address, .I src_addr
--
2.35.3
Alejandro Colomar
maintainerQuoted 42 lines · Peter Radisson
V2:
* removed 1 empty line
* and changed wording to "content of" to make clear *addrlen is used.To replicate the problem:
// intended use
structsockaddr_insock_out;
int slen=sizeof(sock_out); //socklen_trecv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);// error case
structsockaddr_insock_out;
int slen=1;recv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);funfact: this escapes the error handling in the linux kernel (no crash) set slen=-1 and you get EINVAL.
hope that helps.
From
056b50b50dca9f08d203d1d56fdcb6e84d228dbaMon Sep 17 00:00:00 2001
From: Peter Radisson <--show-origin>
Date: Thu, 27 Mar 2025 17:05:51 +0100
Subject: [PATCH] Be more verbose about recvfrom(2) error handlingSigned-off-by Peter Radisson <--show-origin>--- man2/recv.2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)man2/recv.2 +0
-0@@ -293,6 +293,22 @@ The returned address is truncated if the buffer provided is too small; in this case, .I addrlen will return a value greater than was supplied to the call.
man2/recv.2 The returned address is truncated if the buffer · line 306
Quoted 10 lines
man2/recv.2 +10
-0+If +.I src_addr +is NULL +.I addrlen +will be ignored. +If +.I src_addr +is not NULL and the content of +.I addrlen +is less than null the call will return with
Hi Peter,
An integer cannot be compared to null. Do you mean zero? You could rewrite it as
and
.I addrlen
is negative, ...
Cheers,
Alex
Quoted 14 lines
man2/recv.2 +6
-0+.IR EINVAL . +If +.I addrlen +is less than sizeof struct sockaddr_in the src_addr will +not be modified. + .PP If the caller is not interested in the source address,.I
src_addr
--
2.35.3
Signature · 1 line
<https://www.alejandro-colomar.es/>
Am 27.03.25 um 18:28 schrieb Alejandro Colomar:
Quoted 4 lines · Peter Radisson
Quoted 3 lines
V2:
* removed 1 empty line
* and changed wording to "content of" to make clear *addrlen is used.
V3:
* changed wording:
less that null -> negativ
thx for fast reply, unfortunately i noticed an other problem with the page. I will report in an other mail.
Quoted 14 lines
Quoted 14 lines
To replicate the problem:
// intended use
structsockaddr_insock_out;
int slen=sizeof(sock_out); //socklen_trecv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);// error case
structsockaddr_insock_out;
int slen=1;recv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);
Quoted 5 lines
Quoted 5 lines
funfact: this escapes the error handling in the linux kernel (no crash) set slen=-1 and you get EINVAL.
hope that helps.
From 9f464fde8dd168b71430ca29f631153e3e3fb2e5 Mon Sep 17 00:00:00 2001
From: Peter Radisson <--show-origin>
Date: Thu, 27 Mar 2025 18:39:29 +0100
Subject: [PATCH] Be more verbose about recvfrom(2) error handling
--- man2/recv.2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)
man2/recv.2 +0 -0
@@ -293,6 +293,22 @@ The returned address is truncated if the buffer
provided is too small;
in this case,
.I addrlen
will return a value greater than was supplied to the call.
+If
+.I src_addr
+is NULL
+.I addrlen
+will be ignored.
+If
+.I src_addr
+is not NULL and the content of
+.I addrlen
+is negativ the call will return with
+.IR EINVAL .
+If
+.I addrlen
+is less than sizeof struct sockaddr_in the src_addr will +not be modified.
+
.PP
If the caller is not interested in the source address, .I src_addr
--
2.35.3
Quoted 9 lines · Peter Radisson
Am 27.03.25 um 18:28 schrieb Alejandro Colomar:
Quoted 4 lines · Peter Radisson
Quoted 3 lines
V2:
* removed 1 empty line
* and changed wording to "content of" to make clear *addrlen is used.V3:
* changed wording:
less that null -> negativ
s/negativ/negative/g
Quoted 43 lines
thx for fast reply, unfortunately i noticed an other problem with the page. I will report in an other mail.
Quoted 14 lines
Quoted 14 lines
To replicate the problem:
// intended use
struct sockaddr_insock_out;
int slen=sizeof(sock_out); //socklen_trecv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);// error case
struct sockaddr_insock_out;
int slen=1;recv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);Quoted 5 lines
Quoted 5 lines
funfact: this escapes the error handling in the linux kernel (no crash) set slen=-1 and you get EINVAL.
hope that helps.
From
9f464fde8dd168b71430ca29f631153e3e3fb2e5Mon Sep 17 00:00:00 2001
From: Peter Radisson <--show-origin>
Date: Thu, 27 Mar 2025 18:39:29 +0100
Subject: [PATCH] Be more verbose about recvfrom(2) error handlingSigned-off-by Peter Radisson <--show-origin>--- man2/recv.2 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+)man2/recv.2 +0
-0@@ -293,6 +293,22 @@ The returned address is truncated if the buffer provided is too small; in this case, .I addrlen will return a value greater than was supplied to the call.
man2/recv.2 The returned address is truncated if the buffer · line 306
Quoted 10 lines
man2/recv.2 +10
-0+If +.I src_addr +is NULL +.I addrlen +will be ignored. +If +.I src_addr +is not NULL and the content of +.I addrlen +is negativ the call will return with
s/negativ/negative/g
man2/recv.2 The returned address is truncated if the buffer · line 311
Quoted 5 lines
man2/recv.2 +5
-0+.IR EINVAL . +If +.I addrlen +is less than sizeof struct sockaddr_in the src_addr will +not be modified.
My suggestion would be to place this as an entry under ERRORS for EINVAL.
Adding all of this conditional text under recvfrom() seems overly complicated.
We should document the success case and how it work for truncation.
Quoted 9 lines
man2/recv.2 +1
-0+ .PP If the caller is not interested in the source address,.I
src_addrSignature · 1 line
2.35.3
Signature · 2 lines
Cheers, Carlos.
Am 28.03.25 um 23:45 schrieb Carlos O'Donell:
Quoted 78 lines · Peter Radisson
Quoted 9 lines
Am 27.03.25 um 18:28 schrieb Alejandro Colomar:
Quoted 4 lines · Peter Radisson
Quoted 3 lines
V2:
* removed 1 empty line
* and changed wording to "content of" to make clear *addrlen is used.V3:
* changed wording:
less that null -> negativs/negativ/negative/g
Quoted 43 lines
thx for fast reply, unfortunately i noticed an other problem with the page. I will report in an other mail.
Quoted 14 lines
Quoted 14 lines
To replicate the problem:
// intended use
struct sockaddr_insock_out;
int slen=sizeof(sock_out); //socklen_trecv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);// error case
struct sockaddr_insock_out;
int slen=1;recv_len=recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &sock_out, &slen);Quoted 5 lines
Quoted 5 lines
funfact: this escapes the error handling in the linux kernel (no crash) set slen=-1 and you get EINVAL.
hope that helps.
From
9f464fde8dd168b71430ca29f631153e3e3fb2e5Mon Sep 17 00:00:00 2001
From: Peter Radisson <--show-origin>
Date: Thu, 27 Mar 2025 18:39:29 +0100
Subject: [PATCH] Be more verbose about recvfrom(2) error handlingSigned-off-by Peter Radisson <--show-origin>---
man2/recv.2 | 16 ++++++++++++++++1 file changed, 16 insertions(+)man2/recv.2 +0
-0@@ -293,6 +293,22 @@ The returned address is truncated if the buffer provided is too small; in this case,.I addrlen
will return a value greater than was supplied to the call.man2/recv.2
Quoted 10 lines
man2/recv.2 +10
-0+If +.I src_addr +is NULL +.I addrlen +will be ignored. +If +.I src_addr +is not NULL and the content of +.I addrlen +is negativ the call will return withs/negativ/negative/g
man2/recv.2
Quoted 5 lines
+.IR EINVAL .
man2/recv.2 +4
-0+If +.I addrlen +is less than sizeof struct sockaddr_in the src_addr will +not be modified.My suggestion would be to place this as an entry under ERRORS for EINVAL.
Quoted 5 lines
Adding all of this conditional text under
recvfrom()seems overly complicated.We should document the success case and how it work for truncation.
IMHO is the error handling broken. Anything less that sizeof(struct sockaddr_in) should cause an error. It does not so this behavier should be documented here so everybody is aware about it.
(second thought: BUGS section ?)
ym2c
Quoted 11 lines
Quoted 9 lines
+
.PP
If the caller is not interested in the source address, .Isrc_addr
--
2.35.3