Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 14 Jan 2009 15:20:13 +0000 (UTC)
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        cvs-src-old@freebsd.org
Subject:   cvs commit: src/sys/kern sysv_sem.c
Message-ID:  <200901141520.n0EFKJQS076201@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
kib         2009-01-14 15:20:13 UTC

  FreeBSD src repository

  Modified files:
    sys/kern             sysv_sem.c 
  Log:
  SVN rev 187223 on 2009-01-14 15:20:13Z by kib
  
  It seems that there are at least three issues with IPC_RMID operation
  on SysV semaphores.
  
    The squeeze of the semaphore array in the kern_semctl() modifies
    sem_base for the semaphores with sem_base greater then sem_base of
    the removed semaphore, as well as the values of the semaphores,
    without locking their mutex. This can lead to (killable) hangs or
    unexpected behaviour of the processes performing any sem operations
    while other process does IPC_RMID.
  
    The semexit_myhook() eventhandler unlocks SEMUNDO_LOCK() while
    accessing *suptr. This allows for IPC_RMID for the sem id to be
    performed in parallel with undo hook referenced by the current undo
    structure. This leads to the panic("semexit - semid not allocated") [1].
  
    The semaphore creation is protected by Giant, while IPC_RMID is done
    while only semaphore mutex is held. This seems to result in invalid
    values for semtot, causing random ENOSPC error returns [2].
  
  Redo the locking of the semaphores lifetime cycle. Delegate the
  sem_mtx to the sole purpose of protecting semget() and
  semctl(IPC_RMID). Introduce new sem_undo_mtx to protect SEM_UNDO
  handling. Remove the Giant remnants from the code.
  Note that  mac_sysvsem_check_semget() and mac_sysvsem_create() are
  now called while sem_mtx is held, as well as mac_sysvsem_cleanup() [3].
  
  When semaphore is removed, acquire semaphore locks for all semaphores
  with sem_base that is going to be changed by squeeze of the sema
  array. The lock order is not important there, because the region is
  protected by sem_mtx.
  
  Organize both used and free sem_undo structures into the lists,
  protected by sem_undo_mtx. In semexit_myhook(), remove sem_undo
  structure that is being processed, from used list, without putting it
  onto the free to prevent modifications by other threads. This allows
  for sem_undo_lock to be dropped to acquire individial semaphore locks
  without violating lock order. Since IPC_RMID may no longer find this
  sem_undo, do tolerate references to unallocated semaphores in undo
  structure, and check sequential number to not undo unrelated semaphore
  with the same id.
  
  While there, convert functions definitions to ANSI C and fix small
  style(9) glitches.
  
  Reported by:    Omer Faruk Sen <omerfsen gmail com> [1], pho [2]
  Reviewed by:    rwatson [3]
  Tested by:      pho
  MFC after:      1 month
  
  Revision  Changes    Path
  1.92      +125 -152  src/sys/kern/sysv_sem.c



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200901141520.n0EFKJQS076201>