Anonymous | Login | 2025-01-14 16:41 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0000074 | [1003.1(2008)/Issue 7] System Interfaces | Objection | Error | 2009-06-29 02:27 | 2013-04-16 13:06 | ||
Reporter | nick | View Status | public | ||||
Assigned To | ajosey | ||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | Nick Stoughton | ||||||
Organization | |||||||
User Reference | |||||||
Section | Pointer | ||||||
Page Number | 541 | ||||||
Line Number | 18886 | ||||||
Interp Status | Approved | ||||||
Final Accepted Text | Note: 0000205 | ||||||
Summary | 0000074: Pointer Types Problem | ||||||
Description |
_____________________________________________________________________________ OBJECTION Enhancement Request Number 11 nick:xxxxxxxxxx Bug in XSHd5.1 Pointer Types (rdvk# 1) {NMS-funcptr} Wed, 10 Sep 2008 21:05:32 +0100 (BST) _____________________________________________________________________________ In order to support the dynamic library functions (and dlsym() in particular), POSIX extends the C standard to require that a pointer to a function can be stored in a pointer to void. This explicit extension opens the door to permit conversion (via other promises in the C standard) of a pointer to a data object into a pointer to a function, thus requiring code such as below to work: char buf[1024]; void *p; int (*f)(void); // assemble instructions into buf p = buf; f = p; f(); In practice, many implementations will forbid execution of data in this form, as it is frequently a source of security vulnerabilities. Similarly, it need not necessarily be supported to try to examine the instructions that make a function by casting (or converting via a void *) a pointer-to-function into a pointer-to-object. The intent is simply to permit dlsym to use a void * as its return type. |
||||||
Desired Action |
After the sentence ending on line 18890, add the following: If a pointer to an object or incomplete type is converted to a pointer to void and then to a pointer to a function type, or vice-versa, the behaviour is undefined. |
||||||
Tags | c99, tc1-2008 | ||||||
Attached Files | |||||||
|
Relationships | |||||||||||||||||||||||||||||||||||||
|
Notes | |
(0000129) msbrown (manager) 2009-06-29 02:27 |
After the sentence ending on line 18890, add the following: If a pointer to an object or incomplete type is converted to a pointer to void and then to a pointer to a function type the behavior is undefined., If a pointer to a function type is converted to a pointer to void and then to a pointer to an object or an incomplete type the behaviour is undefined. |
(0000155) Konrad_Schwarz (reporter) 2009-07-07 07:23 edited on: 2009-07-07 08:13 |
In the description of dlsym() (lines 24689--24764), replace all occurrences of "object(s)" with "executable object file(s)" or "object file(s)", for consistency with dlopen() and because "object" has a different meaning in C. The same applies to dlclose() (lines 24469--24526) and to the later paragraphs of dlopen() (lines 24594--24688). Also, it should be clarified that a "symbol" is either a function or a (data) object. In line 24659, replace "shall be those that were" by "shall be the functions and objects that were". |
(0000156) Konrad_Schwarz (reporter) 2009-07-07 08:38 |
As an alternative suggestion to note 129, which led to much discussion on the E-mail reflector, add after the first sentence of dlsym()'s DESCRIPTION (line 24696): dlsym()'s return value, cast to a pointer to the type of the symbol, may be used to call (in case of a function) respectively access (in case of a [data] object) the symbol. Section 2.12.3 could then be struck completely; section RATIONAL of dlsym() would need to be adjusted, e.g., by striking lines 24742--24785. |
(0000203) Don Cragun (manager) 2009-08-20 21:18 |
After further discussion on this issue, it has been reopened. The descriptions of dlclose(), dlopen(), and dlsym() are being rewritten to be more consistent with terminology used in the C standard and with the use of symbol in the rest of this standard. When done, it is also expected that 0000100 will be closed as a duplicate of this problem and the changes here will fix both issues. It is also expected that this issue will need to go down the interpretations track as a DEFECT situation. |
(0000205) Don Cragun (manager) 2009-08-27 00:03 edited on: 2009-11-06 06:52 |
Interpretation response ------------------------ The standard states the requirements for pointer types , and conforming implementations must conform to this. However, concerns have been raised about this which are being referred to the sponsor. Rationale: ------------- None. Notes to the Editor (not part of this interpretation): ------------------------------------------------------- After a lengthy discussion on the e-mail list based on the proposed resolution in Note: 0000129, the committee decided to revise the text. These changes solve: 1. the issue initially raised in this report, 2. the issue raised in 0000099 (which will be closed as a dup of this bug when this bug resolution is approved), 3. the issue raised in 0000100 (which will be closed as a dup of this bug when this bug resolution is approved), 4. some inconsistencies between the uses of the term object in this standard and in ISO C (as noted by Konrad in Note: 0000155 and Note: 0000156), and 5. the inconsistent use of the term symbol in this standard (in the rest of this standard, symbol refers either to a graphic representation of a character or to a symbolic constant; in the description of dlsym(), however, symbol refers to what is known by the term identifier in ISO C. This note was discussed during the August 27, 2009 conference call and minor edits have made done in place (without creating a new note). ------------------------------------------------------------------------ Delete subclause 2.12.3 from P541, L18881-18886. ------------------------------------------------------------------------ Replace the NAME, SYNOPSIS, DESCRIPTION, RETURN VALUE, ERRORS, EXAMPLES, and APPLICATION USAGE sections of the dlclose() descripion on P728, L24469-24513 with: NAME dlclose -- close a symbol table handle SYNOPSIS #include <dlfcn.h> int dlclose(void *handle); DESCRIPTION The dlclose() function shall inform the system that the symbol table handle specified by handle is no longer needed by the application. An application writer may use dlclose() to make a statement of intent on the part of the process, but this statemen does not create any requirement upon the implementation. When the symbol table handle is closed, the implementation may unload the executable object files that were loaded by dlopen() when the symbol table handle was opened and those that were loaded by dlsym() when using the symbol table handle identified by handle. Once a symbol table handle has been closed, an application should assume that any symbols (function identifiers and data object identifiers) made visible using handle, are no longer available to the process. Although a dlclose() operation is not required to remove any functions or data objects from the address space, neither is an implementation prohibited from doing so. The only restriction on such a removal is that no function nor data object shall be removed to which references have been relocated, until or unless all such references are removed. For instance, an executable object file that had been loaded with a dlopen() operation specifying the RTLD_GLOBAL flag might provide a target for dynamic relocations performed in the processing of other relocatable objects--in such environments, an application may assume that no relocation, once made, shall be undone or remade unless the executable object file containing the relocated object has itself been removed. RETURN VALUE If the referenced symbol table handle was successfully closed, dlclose() shall return 0. If handle does not refer to an open symbol table handle or if the symbol table handle could not be closed, dlclose() shall return a non-zero value. More detailed diagnostic information shall be available through dlerror(). ERRORS No errors are defined. EXAMPLES The following example illustrates use of dlopen() and dlclose(): #include <dlfcn.h> int eret; void *mylib; ... /* Open a dynamic library and then close it ... */ mylib = dlopen("mylib.so", RTLD_LOCAL | RTLD_LAZY); ... eret = dlclose(mylib); ... APPLICATION USAGE A conforming application should employ a symbol table handle returned from a dlopen() invocation only within a given scope bracketed by a dlopen() operation and the corresponding dlclose() operation. Implementations are free to use reference counting or other techniques such that multiple calls to dlopen() referencing the same executable object file may return a pointer to the same data object as the symbol table handle. Implementations are also free to reuse a handle. For these reasons, the value of a handle must be treated as an opaque data type by the application, used only in calls to dlsym() and dlclose(). ------------------------------------------------------------------------ Replace the NAME, SYNOPSIS, DESCRIPTION, and RETURN VALUE sections of the dlopen() descripion on P732-733, L24575-24666: NAME dlopen -- open a symbol table handle SYNOPSIS #include <dlfcn.h> void *dlopen(const char *file, int mode); DESCRIPTION The dlopen() function shall make the symbols (function identifiers and data object identifiers) in the executable object file specified by file available to the calling program. The class of executable object files eligible for this operation and the manner of their construction are implementation-defined, though typically such files are shared libraries or programs. Implementations may permit the construction of embedded dependencies in executable object files. In such cases, a dlopen() operation shall load those dependencies in addition to the executable object file specified by file. Implementations may also impose specific constraints on the construction of programs that can employ dlopen() and its related services. A successful dlopen() shall return a symbol table handle which the caller may use on subsequent calls to dlsym() and dlclose(). The value of this symbol table handle should not be interpreted in any way by the caller. The file argument is used to construct a pathname to the executable object file. If file contains a <slash> character, the file argument is used as the pathname for the file. Otherwise, file is used in an implementation-defined manner to yield a pathname. If file is a null pointer, dlopen() shall return a global symbol table handle for the currently running process image. This symbol table handle shall provide access to the symbols from an ordered set of executable object files consisting of the original program image file, any executable object files loaded at program start-up as specified by that process image file (for example, shared libraries), and the set of executable object files loaded using dlopen() operations with the RTLD_GLOBAL flag. As the latter set of executable object files can change during execution, the set of symbols made available by this symbol table handle can also change dynamically. Only a single copy of an executable object file shall be brought into the address space, even if dlopen() is invoked multiple times in reference to the executable object file, and even if different pathnames are used to reference the executable object file. The mode parameter describes how dlopen() shall operate upon file with respect to the processing of relocations and the scope of visibility of the symbols provided within file. When an executable object file is brought into the address space of a process, it may contain references to symbols whose addresses are not known until the executable object file is loaded. These references shall be relocated before the symbols can be accessed. The mode parameter governs when these relocations take place and may have the following values: RTLD_LAZY Relocations shall be performed at an implementation-defined time, ranging from the time of the dlopen() call until the first reference to a given symbol occurs. Specifying RTLD_LAZY should improve performance on implementations supporting dynamic symbol binding since a process might not reference all of the symbols in an executable object file. And, for systems supporting dynamic symbol resolution for normal process execution, this behavior mimics the normal handling of process execution. RTLD_NOW All necessary relocations shall be performed when the executable object file is first loaded. This may waste some processing if relocations are performed for symbols that are never referenced. This behavior may be useful for applications that need to know that all symbols referenced during execution will be available before dlopen() returns. Any executable object file loaded by dlopen() that requires relocations against global symbols can reference the symbols in the original process image file, any executable object files loaded at program start-up, from the initial process image itself, from any other executable object file included in the same dlopen() invocation, and any executable object files that were loaded in any dlopen() invocation and which specified the RTLD_GLOBAL flag. To determine the scope of visibility for the symbols loaded with a dlopen() invocation, the mode parameter should be a bitwise-inclusive OR with one of the following values: RTLD_GLOBAL The executable object file's symbols shall be made available for relocation processing of any other executable object file. In addition, symbol lookup using dlopen(NULL, mode) and an associated dlsym() allows executable object files loaded with this mode to be searched. RTLD_LOCAL The executable object file's symbols shall not be made available for relocation processing of any other executable object file. If neither RTLD_GLOBAL nor RTLD_LOCAL are specified, the default behavior is unspecified. If an executable object file is specified in multiple dlopen() invocations, mode is interpreted at each invocation. If RTLD_NOW has been specified, all relocations shall have been completed rendering further RTLD_NOW operations redundant and any further RTLD_LAZY operations irrelevant. If RTLD_GLOBAL has been specified, the executable object file shall maintain the RTLD_GLOBAL status regardless of any previous or future specification of RTLD_LOCAL, as long as the executable object file remains in the address space (see dlclose()). Symbols introduced into the process image through calls to dlopen() may be used in relocation activities. Symbols so introduced may duplicate symbols already defined by the program or previous dlopen() operations. To resolve the ambiguities such a situation might present, the resolution of a symbol reference to symbol definition is based on a symbol resolution order. Two such resolution orders are defined: load order and dependency order. Load order establishes an ordering among symbol definitions, such that the first definition loaded (including definitions from the process image file and any dependent executable object files loaded with it) has priority over executable object files added later (by dlopen()). Load ordering is used in relocation processing. Dependency ordering uses a breadth-first order starting with a given executable object file, then all of its dependencies, then any dependents of those, iterating until all dependencies are satisfied. With the exception of the global symbol table handle obtained via a dlopen() operation with a null pointer as the file argument, dependency ordering is used by the dlsym() function. Load ordering is used in dlsym() operations upon the global symbol table handle. When an executable object file is first made accessible via dlopen(), it and its dependent executable object files are added in dependency order. Once all the executable object files are added, relocations are performed using load order. Note that if an executable object file or its dependencies had been previously loaded, the load and dependency orders may yield different resolutions. The symbols introduced by dlopen() operations and available through dlsym() are at a minimum those which are exported as identifiers of global scope by the executable object file. Typically such identifiers shall be those that were specified in (for example) C source code as having extern linkage. The precise manner in which an implementation constructs the set of exported symbols for an executable object file is implementation-defined. RETURN VALUE Upon successful completion, dlopen() shall return a symbol table handle. If file cannot be found, cannot be opened for reading, is not of an appropriate executable object file format for processing by dlopen(), or if an error occurs during the process of loading file or relocating its symbolic references, dlopen() shall return a null pointer. More detailed diagnostic information shall be available through dlerror(). ------------------------------------------------------------------------ Replace the NAME, SYNOPSIS, DESCRIPTION, RETURN VALUE, ERRORS, EXAMPLES, APPLICATION USAGE, and RATIONALE sections of the dlsym() descripion on P735-736, L24689-24748 with: NAME dlsym -- get the address of a symbol from a symbol table handle SYNOPSIS #include <dlfcn.h> void *dlsym(void *restrict handle, const char *restrict name); DESCRIPTION The dlsym() function shall obtain the address of a symbol (a function identifier or a data object identifier) defined in the symbol table identified by the handle argument. The handle argument is a symbol table handle returned from a call to dlopen() (and which has not since been released by a call to dlclose()), and name is the symbol's name as a character string. The return value from dlsym(), cast to a pointer to the type of the named symbol, can be used to call (in the case of a function) or access the contents of (in the case of a data object) the named symbol. The dlsym() function shall search for the named symbol in the symbol table referenced by handle. If the symbol table was created with lazy loading (see RTLD_LAZY in dlopen()), load ordering shall be used in dlsym() operations to relocate executable object files needed to resolve the symbol. The symbol resolution algorithm used shall be dependency order as described in dlopen(). The RTLD_DEFAULT and RTLD_NEXT symbolic constants (which may be defined in <dlfcn.h>) are reserved for future use as special values that applications may be allowed to use for handle. RETURN VALUE Upon successful completion, if name names a function identifier, dlsym() shall return the address of the function converted from type pointer to function to type pointer to void; otherwise dlsym() shall return the address of the data object associated with the data object identfier named by name converted from a pointer to the type of the data object to a pointer to void. If handle does not refer to a valid symbol table handle or if the symbol named by name cannot be found in the symbol table associated with handle, dlsym() shall return a null pointer. More detailed diagnostic information shall be available through dlerror(). ERRORS No errors are defined. EXAMPLES The following example shows how dlopen() and dlsym() can be used to access either a function or a data object. For simplicity, error checking has been omitted. void *handle; int (*fptr)(int), *iptr, result; /* open the needed symbol table */ handle = dlopen("/usr/home/me/libfoo.so", RTLD_LOCAL | RTLD_LAZY); /* find the address of the function my_function */ fptr = (int (*)(int))dlsym(handle, "my_function"); /* find the address of the data object my_object */ iptr = (int *)dlsym(handle, "my_OBJ"); /* invoke my_function, passing the value of my_OBJ as the parameter */ result = (*fptr)(*iptr); APPLICATION USAGE The following special purpose values for handle are reserved for future use and have the indicated meanings: RTLD_DEFAULT The identifier lookup happens in the normal global scope; that is, a search for a identifier using handle would find the same definition as a direct use of this identifier in the program code. RTLD_NEXT Specifies the next executable object file after this one that defines name. This one refers to the executable object file containing the invocation of dlsym(). The next executable object file is the one found upon the application of a load order symbol resolution algorithm (see dlopen()). The next symbol is either one of global scope (because it was introduced as part of the original process image or because it was added with a dlopen() operation including the RTLD_GLOBAL flag), or is in an executable object file that was included in the same dlopen() operation that loaded this one. The RTLD_NEXT flag is useful to navigate an intentionally created hierarchy of multiply-defined symbols created through interposition. For example, if a program wished to create an implementation of malloc() that embedded some statistics gathering about memory allocations, such an implementation could use the real malloc() definition to perform the memory allocation--and itself only embed the necessary logic to implement the statistics gathering function. Note that conversion from a void * pointer to a function pointer as in: fptr = (int (*)(int))dlsym(handle, "my_function"); is not defined by the ISO C Standard. This standard requires this conversion to work correctly on conforming implementations. RATIONALE None. ------------------------------------------------------------------------ |
(0000210) geoffclare (manager) 2009-08-28 09:02 edited on: 2009-08-30 02:28 |
When we progress this down the interpretations track, the accepted text needs a couple of minor editorial changes: Change "NULL pointer" to "null pointer". Change "Similarly, note that once RTLD_GLOBAL has been specified" to "If RTLD_GLOBAL has been specified". August 8, 2009, 19:27 PDT: Geoff is correct. These are editorial mistakes. These have been fixed in place in Note: 0000205. - Don Cragun |
(0000243) Don Cragun (manager) 2009-09-28 00:25 |
Further corrections were added to Note: 0000205 reflecting changes discussed on the austin-group-l alias. This discussion also led to the upcoming modification to Austin Group Interpretation reference 1003.1-2001 #003. |
Issue History | |||
Date Modified | Username | Field | Change |
2009-06-29 02:27 | msbrown | New Issue | |
2009-06-29 02:27 | msbrown | Status | New => Under Review |
2009-06-29 02:27 | msbrown | Assigned To | => ajosey |
2009-06-29 02:27 | msbrown | Name | => Mark Brown |
2009-06-29 02:27 | msbrown | Organization | => IBM |
2009-06-29 02:27 | msbrown | User Reference | => Pointer |
2009-06-29 02:27 | msbrown | Section | => (section number or name, can be interface name) |
2009-06-29 02:27 | msbrown | Page Number | => 541 |
2009-06-29 02:27 | msbrown | Line Number | => 18886 |
2009-06-29 02:27 | msbrown | Note Added: 0000129 | |
2009-06-29 02:28 | msbrown | Final Accepted Text | => Note: 0000129 |
2009-06-29 02:28 | msbrown | Status | Under Review => Resolved |
2009-06-29 02:28 | msbrown | Resolution | Open => Accepted As Marked |
2009-07-01 14:02 | msbrown | Name | Mark Brown => Nick Stoughton |
2009-07-01 14:02 | msbrown | Organization | IBM => |
2009-07-01 14:02 | msbrown | Reporter | msbrown => nick |
2009-07-01 14:03 | msbrown | User Reference | Pointer => |
2009-07-01 14:03 | msbrown | Section | (section number or name, can be interface name) => Pointer |
2009-07-07 07:23 | Konrad_Schwarz | Note Added: 0000155 | |
2009-07-07 07:28 | Konrad_Schwarz | Note Edited: 0000155 | |
2009-07-07 07:57 | Konrad_Schwarz | Note Edited: 0000155 | |
2009-07-07 08:13 | Konrad_Schwarz | Note Edited: 0000155 | |
2009-07-07 08:38 | Konrad_Schwarz | Note Added: 0000156 | |
2009-08-20 21:18 | Don Cragun | Interp Status | => --- |
2009-08-20 21:18 | Don Cragun | Final Accepted Text | Note: 0000129 => |
2009-08-20 21:18 | Don Cragun | Note Added: 0000203 | |
2009-08-20 21:18 | Don Cragun | Resolution | Accepted As Marked => Reopened |
2009-08-20 21:19 | Don Cragun | Status | Resolved => Under Review |
2009-08-27 00:03 | Don Cragun | Note Added: 0000205 | |
2009-08-27 00:14 | Don Cragun | Note Edited: 0000205 | |
2009-08-27 16:45 | Don Cragun | Note Edited: 0000205 | |
2009-08-27 16:46 | Don Cragun | Interp Status | --- => Pending |
2009-08-27 16:46 | Don Cragun | Final Accepted Text | => Note: 0000205 |
2009-08-27 16:46 | Don Cragun | Status | Under Review => Interpretation Required |
2009-08-27 16:46 | Don Cragun | Resolution | Reopened => Accepted As Marked |
2009-08-28 09:02 | geoffclare | Note Added: 0000210 | |
2009-08-30 02:24 | Don Cragun | Note Edited: 0000205 | |
2009-08-30 02:28 | Don Cragun | Note Edited: 0000210 | |
2009-08-30 02:28 | Don Cragun | Note Edited: 0000210 | |
2009-09-17 15:41 | nick | Interp Status | Pending => Proposed |
2009-09-28 00:21 | Don Cragun | Note Edited: 0000205 | |
2009-09-28 00:25 | Don Cragun | Note Added: 0000243 | |
2009-09-28 09:01 | Don Cragun | Note Edited: 0000205 | |
2009-09-28 16:33 | nick | Tag Attached: c99 | |
2009-11-06 06:52 | ajosey | Note Edited: 0000205 | |
2009-11-06 06:53 | ajosey | Interp Status | Proposed => Approved |
2009-11-12 16:47 | msbrown | Relationship added | has duplicate 0000178 |
2010-09-20 09:15 | geoffclare | Tag Attached: tc1-2008 | |
2013-04-16 13:06 | ajosey | Status | Interpretation Required => Closed |
2014-03-08 06:27 | ajosey | Relationship added | related to 0000829 |
2021-01-04 10:50 | geoffclare | Relationship added | related to 0001439 |
2021-10-14 15:47 | rhansen | Relationship added | has duplicate 0000099 |
2021-10-14 15:48 | rhansen | Relationship added | has duplicate 0000100 |
2023-03-23 16:42 | geoffclare | Relationship added | related to 0001644 |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |