Austin Group Defect Tracker

Aardvark Mark IV


Viewing Issue Simple Details Jump to Notes ] Issue History ] Print ]
ID Category Severity Type Date Submitted Last Update
0000728 [1003.1(2013)/Issue7+TC1] System Interfaces Editorial Clarification Requested 2013-08-05 15:16 2023-09-04 10:21
Reporter dalias View Status public  
Assigned To
Priority normal Resolution Accepted As Marked  
Status Applied  
Name Rich Felker
Organization musl libc
User Reference
Section XSH 2.4.3 Signal Actions
Page Number unknown
Line Number unknown
Interp Status ---
Final Accepted Text Note: 0006430
Summary 0000728: Restrictions on signal handlers are both excessive and insufficient
Description Per XSH 2.4.3:

"the behavior is undefined if the signal handler refers to any object other than errno with static storage duration other than by assigning a value to an object declared as volatile sig_atomic_t, or if the signal handler calls any function defined in this standard other than one of the functions listed in the following table."

The intent here is that signal handlers cannot access objects which might be in a partially-modified state when the (asynchronous) signal handler is invoked. However, this is not what it says. Consider for example a program which allocates an object via malloc (or with automatic storage in main()) and stores the address in /tmp/foo. Per the language of the standard, the signal handler can legitimately open /tmp/foo (open is AS-safe), read that address (read is AS-safe), and dereference the pointer, even though the object may be in a partially-modified state.

As a second example, one can arrange for the address of such an object to be delivered to the signal handler via the sigval argument to realtime signals, timers, etc. and in fact using these features generally REQUIRES a pointer to be delivered to the signal handler.

Moreover, plenty of legitimate accesses to objects with static storage duration is wrongly forbidden:

- Access to const-qualified objects.
- Access to string literals (note in the above example, a string literal could not be passed to open; instead, the array "/dev/tmp" must be automatic).
- Access to a modifiable object of static storage duration whose last modification was sequenced before the signal handler could have been invoked via sigprocmask(), pthread_sigmask(), sigaction(), etc.

There is no reason to forbid such accesses, and to my knowledge there is no historical implementation for which they would not work.

This issue report is partly inspired by: http://www.tedunangst.com/flak/post/signal-safe-strcpy [^]
Desired Action Ideally, replace the restriction on access to static objects in XSH 2.4.3 with a proper memory model for access to objects (static or otherwise) from signal handlers based on sequencing by signal masking or other means.

Alternatively, require that no object except objects with automatic storage duration whose lifetimes began within the signal handling context be accessed from within the signal handling context. In my opinion, this would be excessively restrictive, but at least it would close the loophole/inconsistency in the existing language where access to static objects is forbidden but access to dynamic or automatic objects that exist outside the signal handler is permitted.
Tags applied_after_i8d3, issue8
Attached Files

- Relationships
related to 0000733Closed Volatile qualification of sig_atomic_t is ambigiuous 

-  Notes
(0001699)
dalias (reporter)
2013-08-05 15:18

Additionally, no restrictions on access to objects should apply when a synchronous signal is being handled (e.g. SIGPIPE) unless the invocation was a result of undefined behavior (in which case, the standard has nothing to say, anyway).
(0001838)
dalias (reporter)
2013-09-20 18:05

Some thoughts on how the memory model should work:

Access to an object which is modified by another thread without synchronization has undefined behavior [same as always; signal handlers are not special here].

Access to an object which is modified in the same thread as the signal handler runs in has undefined behavior unless one of the following conditions is met:

1. Access is sequenced by controlling the signal mask or signal disposition [or possibly other means yet to be determined; formally supporting the "self-pipe trick" would be desirable at least] so as to establish an ordering relation between the accesses from the interrupted thread and the signal handler.

2. The object has type sig_atomic_t or character type. [I included character types along with sig_atomic_t because the C11 memory model essentially requires byte-granularity writes to be supported by the hardware. If this is objectionable, it could be omitted, but I think it is the correct direction for the future.]
(0001863)
dalias (reporter)
2013-10-07 22:43

There is a small omission in note 0001838 (my previous note on this issue): under condition 2, "The object has type sig_atomic_t or character type." should instead read "The object is volatile-qualified and has type sig_atomic_t or character type."
(0006138)
geoffclare (manager)
2023-01-26 10:46

In the January 2023 ballot resolution meeting, WG14 decided not to make any change to the signal handler requirements in C23. This means we are free to change this as we please (with CX shading) without worrying about the potential for a mis-match with an equivalent change in C23.

A useful piece of feedback from them is that we need to be careful about the phrase "const-qualified objects". If a modifiable object of type T is accessed via a pointer to const T, this could be interpreted as accessing a const-qualified object, but obviously should not be allowed. I suggest the text should say that access to "non-modifiable objects" is allowed and give as examples: string literals, objects that were defined with a const-qualified type, and objects in memory that was mapped read-only.

Issue 8 will have the definition of "happens before" from C17, so we could use that to add something about sequencing. Perhaps something along the lines of "the previous modification (if any) to the object happens before the signal handler is called and the return from the signal handler happens before the next modification (if any) to the object".

Note that there will be changes in this area in draft 3 (talking about lock-free atomic objects) so we should wait for draft 3 before working on wording changes.
(0006430)
geoffclare (manager)
2023-08-14 15:57

On Issue 8 draft 3 page 516 line 18330 section 2.4.3, change:
the behavior is undefined if the signal handler refers to any object other than errno with static or thread storage duration that is not a lock-free atomic object, other than by assigning a value to an object declared as volatile sig_atomic_t, or if the signal handler calls any function or function-like macro defined in this standard other than one of the functions and macros specified below as being async-signal-safe.
to:
the behavior is undefined if:
  • The signal handler refers to any object other than errno with static or thread storage duration that is not a lock-free atomic object, and not a non-modifiable object (for example, string literals, objects that were defined with a const-qualified type, and objects in memory that is mapped read-only), other than by assigning a value to an object declared as volatile sig_atomic_t, unless the previous modification (if any) to the object happens before the signal handler is called and the return from the signal handler happens before the next modification (if any) to the object.

  • The signal handler calls any function or function-like macro defined in this standard other than one of the functions and macros specified below as being async-signal-safe.

On Issue 8 draft 3 page 2049 line 67324 section signal(), change:
the behavior is undefined if the signal handler refers to any object [CX]other than errno[/CX] with static or thread storage duration that is not a lock-free atomic object, other than by assigning a value to an object declared as volatile sig_atomic_t, or if the signal handler calls any function defined in this standard other than [CX]one of the functions listed in Section 2.4 (on page 511)[/CX].
to:
the behavior is undefined if:
  • The signal handler refers to any object [CX]other than errno[/CX] with static or thread storage duration that is not a lock-free atomic object, [CX]and not a non-modifiable object (for example, string literals, objects that were defined with a const-qualified type, and objects in memory that is mapped read-only)[/CX], other than by assigning a value to an object declared as volatile sig_atomic_t, [CX]unless the previous modification (if any) to the object happens before the signal handler is called and the return from the signal handler happens before the next modification (if any) to the object[/CX].

  • The signal handler calls any function defined in this standard other than [CX]one of the functions listed in Section 2.4 (on page 511)[/CX].


- Issue History
Date Modified Username Field Change
2013-08-05 15:16 dalias New Issue
2013-08-05 15:16 dalias Name => Rich Felker
2013-08-05 15:16 dalias Organization => musl libc
2013-08-05 15:16 dalias Section => XSH 2.4.3 Signal Actions
2013-08-05 15:16 dalias Page Number => unknown
2013-08-05 15:16 dalias Line Number => unknown
2013-08-05 15:18 dalias Note Added: 0001699
2013-08-15 15:36 eblake Relationship added related to 0000733
2013-09-20 18:05 dalias Note Added: 0001838
2013-09-20 18:17 eadler Issue Monitored: eadler
2013-10-07 22:43 dalias Note Added: 0001863
2023-01-26 10:46 geoffclare Note Added: 0006138
2023-08-14 15:57 geoffclare Note Added: 0006430
2023-08-14 15:58 geoffclare Interp Status => ---
2023-08-14 15:58 geoffclare Final Accepted Text => Note: 0006430
2023-08-14 15:58 geoffclare Status New => Resolved
2023-08-14 15:58 geoffclare Resolution Open => Accepted As Marked
2023-08-14 15:58 geoffclare Tag Attached: issue8
2023-09-04 10:21 geoffclare Status Resolved => Applied
2023-09-04 10:21 geoffclare Tag Attached: applied_after_i8d3


Mantis 1.1.6[^]
Copyright © 2000 - 2008 Mantis Group
Powered by Mantis Bugtracker