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
0000377 [1003.1(2008)/Issue 7] System Interfaces Objection Enhancement Request 2011-02-09 07:46 2020-02-21 16:22
Reporter Don Cragun View Status public  
Assigned To ajosey
Priority normal Resolution Accepted  
Status Applied  
Name Don Cragun
Organization Self
User Reference dwc: Semaphore initialization
Section semget
Page Number 1836
Line Number 58620-58622
Interp Status ---
Final Accepted Text
Summary 0000377: Semaphore values should be initialized to zero when a semaphore set is created.
Description Background:
While examining the proposed changes to the example in Note: 0000594
in 0000335 I noticed that the description of semaphores in the
standard does not match some of the original design goals of the
implementation at AT&T Bell Labs about 30 years ago. A key missing
point in semaphores is that the original implementation guaranteed
that when a semaphore set was created, the initial values of all
semaphores in the set were required to be initialized to be zero.
Not having this implementation requirement causes applications to
have to jump through several hoops to determine when the semaphore
set creator has successfully initialized the set including needing
a sleep loop or a secondary indicator (such as the creation or
removal of a file) to indicate that the semaphores are ready to
use. Most implementations already initialize semaphores to zero,
but at least one implementation initializes them to -1 (but does
not document that it does this). I have not seen any implementation
that actually fails to initialize semaphores in some manner, since
that could leak sensitive data out of the kernel in certain
circumstances. (This is for the same reason that bytes in holes
in files are required appear as though they had been filled with
zero bytes if they are read before being written.)

There are also several inconsistencies in the description of
permissions in all of the System V IPC mechanisms that need to be
clarified as requirements in the normative text, Although the changes
provided in 0000335 match the current normative requirements, I
belive it would be better to make the standard require actions
closer to the original implementation.

Problem:

The current wording in the description of the initialization of a
semaphore set in the standard on P1836, L58620-58622 says:
        "The data structure associated with each semaphore in the
        set need not be initialized. The semctl() function with
        the command SETVAL or SETALL can be used to initialize each
        semaphore."

but this wording did not appear in SVID3 nor in XPG3 (which were the
source documents for the inclusion of <sys/sem.h>, semctl(), semget(),
and semop() into the POSIX standard). SVID3 and XPG3 were silent
as to how the semaphore set members were initialized. Furthermore,
the actual semaphores do not appear in the semid_ds data structure
as indicated in the paragraph that leads into this list.

Looking back at the original design of this IPC mechanism at AT&T
Bell Labs; the semval, sempid, semncnt, and semzcnt members of
struct sem for each semaphore created were all required to be
initialized to zero before semget() returned. This design decision
allowed semaphores to be used without the complicated verification
that the process that created a semaphore set has completed
initialization by checking the value of the sem_otime member of
struct semid_ds and hoping that no process had performed a succesful
semop() call on an unitialized semaphore.

The relationship between IPC permission bits and the file permission
bits defined in <sys/stat.h> is fairly clear for shared memory
segments and message queues, but is not as obvious for semaphore
queues.
Desired Action
On P496, L17043-17050 in XBD subclause 2.7.1 (IPC General Description)
change:
        The values of the bits are given below in octal notation.
                Bit     Meaning
                ====    ================
                0400    Read by user.
                0200    Write by user.
                0040    Read by group.
                0020    Write by group.
                0004    Read by others.
                0002    Write by others.
to:
        The values of the bits are given below in octal notation
        along with the symbolic constants defined in <sys/stat.h>
        that can be used to represent them.
                        <sys/stat.h>
                Octal   Symbolic
                Value   Constant        Meaning
                =====   ========        ==========================
                0400    S_IRUSR         Read by user.
                0200    S_IWUSR         Write (for shared memory &
                                        message queues) or alter
                                        (for semaphores) by user.
                0040    S_IRGRP         Read by group.
                0020    S_IWGRP         Write or alter by group.
                0004    S_IROTH         Read by others.
                0002    S_IWOTH         Write or alter by others.

Delete P1836, L58620-58622 from the DESCRIPTION of semget().

Add a new paragraph at the end of the DESCRIPTION of semget() after
P1836, 58622 (indented to the same level as L58611-58612):
        Upon creation, the value of the semval, sempid, semncnt, and
        semzcnt members of all <italic>nsems</italic> semaphores
        in the associated semaphore set shall be set to zero.

*** Note that the changes specified by 0000335
*** are to be made in TC1-2008. The changes below are not to be made
*** until the next revision and do not affect the text that should
*** appear in TC1.

Change the entire semop() EXAMPLES section to:

        Setting Values in Semaphores

        The following example sets the values of the two semaphores
        associated with the semid identifier to the values contained
        in the sb array.

        #include <sys/sem.h>
        ...
        int semid;
        struct sembuf sb[2];
        int nsops = 2;
        int result;

        // Code to initialize semid.
        ...
        // Adjust value of semaphore in the semaphore array semid.
        sb[0].sem_num = 0;
        sb[0].sem_op = -1;
        sb[0].sem_flg = SEM_UNDO | IPC_NOWAIT;
        sb[1].sem_num = 1;
        sb[1].sem_op = 1;
        sb[1].sem_flg = 0;

        result = semop(semid, sb, nsops);


        Creating a Semaphore Identifier

        The following example gets a semaphore key using the ftok()
        function, then creates or uses an existing semaphore set
        associated with that key using the semget() function.

        If this process creates the semaphore set, the program uses
        a call to and semop() to initialize it to the value in the
        sbuf array. The number of processes that can execute
        concurrently is set to 2.

        The final call to semop() acquires the semaphore and waits
        until it is free; the SEM_UNDO option releases the semaphore
        when the process exits, waiting until there are less than
        two processes running concurrently.

        #include <errno.h>
        #include <stdio.h>
        #include <stdlib.h>
        #include <sys/sem.h>
        #include <sys/stat.h>
        ...
        struct sembuf sbuf;
        int semid;
        key_t semkey;
        ...
        // Get a key for the semaphore set.
        if ((semkey = ftok("/tmp", ’a’)) == (key_t) -1) {
                perror("IPC error: ftok");
                exit(1);
        }

        // Create the semaphore set associated with this key.
        if ((semid = semget(semkey, 1, IPC_CREAT | IPC_EXCL | S_IRUSR |
                S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH)) != -1) {

                // Initialize the semaphore.
                sbuf.sem_num = 0;
                sbuf.sem_op = 2; // Set the number of runs without queuing.
                sbuf.sem_flg = 0;
                if (semop(semid, &sbuf, 1) == -1) {
                        perror("IPC error: semop");
                        exit(1);
                }
        } else if (errno == EEXIST) {

                // The semaphore set already exists; get its semaphore ID.
                if ((semid = semget(semkey, 0, 0)) == -1) {
                        perror("IPC error 1: semget");
                        exit(1);
                }
        } else {
        perror("IPC error 2: semget");
                exit(1);
        }

        // Since the semget() initialized the semaphore to 0, the
        // following semop() will block until the creating process
        // completes the initialization above. Processes will also
        // block in the following semop() call if two other processes
        // have already passed this point and are still running.
        sbuf.sem_num = 0;
        sbuf.sem_op = -1;
        sbuf.sem_flg = SEM_UNDO;
        if (semop(semid, &sbuf, 1) == -1) {
                perror("IPC Error: semop");
                exit(1);
        }

Tags issue8
Attached Files

- Relationships
related to 0000335Closedajosey semget() and semop() examples do not initialize semval 

There are no notes attached to this issue.

- Issue History
Date Modified Username Field Change
2011-02-09 07:46 Don Cragun New Issue
2011-02-09 07:46 Don Cragun Status New => Under Review
2011-02-09 07:46 Don Cragun Assigned To => ajosey
2011-02-09 07:46 Don Cragun Name => Don Cragun
2011-02-09 07:46 Don Cragun Organization => Self
2011-02-09 07:46 Don Cragun User Reference => dwc: Semaphore initialization
2011-02-09 07:46 Don Cragun Section => semget
2011-02-09 07:46 Don Cragun Page Number => 1836
2011-02-09 07:46 Don Cragun Line Number => 58620-58622
2011-02-09 07:46 Don Cragun Interp Status => ---
2011-02-09 07:49 Don Cragun Relationship added related to 0000335
2011-02-17 17:23 eblake Status Under Review => Resolved
2011-02-17 17:23 eblake Resolution Open => Accepted
2011-02-17 17:23 eblake Tag Attached: issue8
2020-02-21 16:22 geoffclare Status Resolved => Applied


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