Discussion:
[1003.1(2013)/Issue7+TC1 0000836]: accept() should not modify address_len on failure
Austin Group Bug Tracker
2014-04-24 13:15:31 UTC
Permalink
The following issue has been SUBMITTED.
======================================================================
http://austingroupbugs.net/view.php?id=836
======================================================================
Reported By: eblake
Assigned To:
======================================================================
Project: 1003.1(2013)/Issue7+TC1
Issue ID: 836
Category: System Interfaces
Type: Enhancement Request
Severity: Objection
Priority: normal
Status: New
Name: Eric Blake
Organization: Red Hat
User Reference: eblake.accept
Section: accept
Page Number: 563
Line Number: 19506
Interp Status: ---
Final Accepted Text:
======================================================================
Date Submitted: 2014-04-24 13:15 UTC
Last Modified: 2014-04-24 13:15 UTC
======================================================================
Summary: accept() should not modify address_len on failure
Description:
The standard states that accept() modifies the address_len parameter on
output to record the size of the stored address, but does not state whether
this modification occurs even on failure. Thus, an implementation could
feasibly set this parameter to 0 on failure, and an application that
does:<code>
addrlen = sizeof(addr);
do {
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>risks failure, in comparison to:<code>
do {
addrlen = sizeof(addr);
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>

But traditionally, implementations only modify the address_len parameter on
success. Guaranteeing this fact will make it so that applications do not
have to worry whether their EINTR retry loop has a subtle bug if the input
size is set outside of the while loop.
Desired Action:
At line 19523 [XSH accept() ERRORS], change:<blockquote>
Otherwise, -1 shall be returned and <i>errno</i> set to indicate the
error.
</blockquote>to:<blockquote>
Otherwise, -1 shall be returned, <i>errno</i> shall be set to indicate the
error, and any object pointed to by <i>address_len</i> shall remain
unchanged.
</blockquote>
======================================================================

Issue History
Date Modified Username Field Change
======================================================================
2014-04-24 13:15 eblake New Issue
2014-04-24 13:15 eblake Name => Eric Blake
2014-04-24 13:15 eblake Organization => Red Hat
2014-04-24 13:15 eblake User Reference => eblake.accept
2014-04-24 13:15 eblake Section => accept
2014-04-24 13:15 eblake Page Number => 563
2014-04-24 13:15 eblake Line Number => 19506
2014-04-24 13:15 eblake Interp Status => ---
======================================================================
Austin Group Bug Tracker
2014-04-24 13:17:16 UTC
Permalink
The following issue has been UPDATED.
======================================================================
http://austingroupbugs.net/view.php?id=836
======================================================================
Reported By: eblake
Assigned To:
======================================================================
Project: 1003.1(2013)/Issue7+TC1
Issue ID: 836
Category: System Interfaces
Type: Enhancement Request
Severity: Objection
Priority: normal
Status: New
Name: Eric Blake
Organization: Red Hat
User Reference: eblake.accept
Section: accept
Page Number: 563
Line Number: 19506
Interp Status: ---
Final Accepted Text:
======================================================================
Date Submitted: 2014-04-24 13:15 UTC
Last Modified: 2014-04-24 13:17 UTC
======================================================================
Summary: accept() should not modify address_len on failure
======================================================================

Issue History
Date Modified Username Field Change
======================================================================
2014-04-24 13:15 eblake New Issue
2014-04-24 13:15 eblake Name => Eric Blake
2014-04-24 13:15 eblake Organization => Red Hat
2014-04-24 13:15 eblake User Reference => eblake.accept
2014-04-24 13:15 eblake Section => accept
2014-04-24 13:15 eblake Page Number => 563
2014-04-24 13:15 eblake Line Number => 19506
2014-04-24 13:15 eblake Interp Status => ---
2014-04-24 13:17 eblake Description Updated
======================================================================
Jilles Tjoelker
2014-05-08 21:15:20 UTC
Permalink
Post by Austin Group Bug Tracker
The following issue has been SUBMITTED.
======================================================================
http://austingroupbugs.net/view.php?id=836
======================================================================
Reported By: eblake
======================================================================
Project: 1003.1(2013)/Issue7+TC1
Issue ID: 836
Category: System Interfaces
Type: Enhancement Request
Severity: Objection
Priority: normal
Status: New
Name: Eric Blake
Organization: Red Hat
User Reference: eblake.accept
Section: accept
Page Number: 563
Line Number: 19506
Interp Status: ---
======================================================================
Date Submitted: 2014-04-24 13:15 UTC
Last Modified: 2014-04-24 13:15 UTC
======================================================================
Summary: accept() should not modify address_len on failure
The standard states that accept() modifies the address_len parameter on
output to record the size of the stored address, but does not state whether
this modification occurs even on failure. Thus, an implementation could
feasibly set this parameter to 0 on failure, and an application that
does:<code>
addrlen = sizeof(addr);
do {
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>risks failure, in comparison to:<code>
do {
addrlen = sizeof(addr);
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>
But traditionally, implementations only modify the address_len parameter on
success. Guaranteeing this fact will make it so that applications do not
have to worry whether their EINTR retry loop has a subtle bug if the input
size is set outside of the while loop.
FYI, FreeBSD sets address_len to 0 in some rare failure cases: if a
connection was closed while waiting in the queue ([ECONNABORTED] error)
or if the underlying protocol otherwise detects an error while there is
a waiting connection in the queue. I think this is a bug.

The pasted samples should be safe, though, since this does not happen
when accept() is interrupted by a signal while waiting for a connection.
--
Jilles Tjoelker
Rich Felker
2014-05-11 14:13:03 UTC
Permalink
Post by Jilles Tjoelker
Post by Austin Group Bug Tracker
The following issue has been SUBMITTED.
======================================================================
http://austingroupbugs.net/view.php?id=836
======================================================================
Reported By: eblake
======================================================================
Project: 1003.1(2013)/Issue7+TC1
Issue ID: 836
Category: System Interfaces
Type: Enhancement Request
Severity: Objection
Priority: normal
Status: New
Name: Eric Blake
Organization: Red Hat
User Reference: eblake.accept
Section: accept
Page Number: 563
Line Number: 19506
Interp Status: ---
======================================================================
Date Submitted: 2014-04-24 13:15 UTC
Last Modified: 2014-04-24 13:15 UTC
======================================================================
Summary: accept() should not modify address_len on failure
The standard states that accept() modifies the address_len parameter on
output to record the size of the stored address, but does not state whether
this modification occurs even on failure. Thus, an implementation could
feasibly set this parameter to 0 on failure, and an application that
does:<code>
addrlen = sizeof(addr);
do {
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>risks failure, in comparison to:<code>
do {
addrlen = sizeof(addr);
ret = accept(sock, (struct sockaddr *)&addr, &addrlen);
} while (ret == -1 && errno == EINTR);
</code>
But traditionally, implementations only modify the address_len parameter on
success. Guaranteeing this fact will make it so that applications do not
have to worry whether their EINTR retry loop has a subtle bug if the input
size is set outside of the while loop.
FYI, FreeBSD sets address_len to 0 in some rare failure cases: if a
connection was closed while waiting in the queue ([ECONNABORTED] error)
or if the underlying protocol otherwise detects an error while there is
a waiting connection in the queue. I think this is a bug.
I agree that's a bug. Accepting of the connection should (morally, if
nothing else) be atomic. If failure is detected after it's accepted,
it should behave (from the application's perspective) as closure/error
immediately after successful accept.

Rich

Loading...