FreeBSD kernel kern code
sysv_sem.c File Reference
#include <sys/cdefs.h>
#include "opt_sysvipc.h"
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
#include <sys/abi_compat.h>
#include <sys/eventhandler.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/racct.h>
#include <sys/sem.h>
#include <sys/sx.h>
#include <sys/syscall.h>
#include <sys/syscallsubr.h>
#include <sys/sysent.h>
#include <sys/sysctl.h>
#include <sys/uio.h>
#include <sys/malloc.h>
#include <sys/jail.h>
#include <security/audit/audit.h>
#include <security/mac/mac_framework.h>
Include dependency graph for sysv_sem.c:

Go to the source code of this file.

Data Structures

struct  sem_undo
 
struct  __semctl_args
 
struct  semget_args
 
struct  semop_args
 

Macros

#define DPRINTF(a)
 
#define SEMUNDO_MTX   sem_undo_mtx
 
#define SEMUNDO_LOCK()   mtx_lock(&SEMUNDO_MTX);
 
#define SEMUNDO_UNLOCK()   mtx_unlock(&SEMUNDO_MTX);
 
#define SEMUNDO_LOCKASSERT(how)   mtx_assert(&SEMUNDO_MTX, (how));
 
#define SEMMNI   50 /* # of semaphore identifiers */
 
#define SEMMNS   340 /* # of semaphores in system */
 
#define SEMUME   50 /* max # of undo entries per process */
 
#define SEMMNU   150 /* # of undo structures in system */
 
#define SEMMSL   SEMMNS /* max # of semaphores per id */
 
#define SEMOPM   100 /* max # of operations per semop call */
 
#define SEMVMX   32767 /* semaphore maximum value */
 
#define SEMAEM   16384 /* adjust on exit max value */
 
#define SEM_ALIGN(bytes)   roundup2(bytes, sizeof(long))
 
#define SEMUSZ(x)   SEM_ALIGN(offsetof(struct sem_undo, un_ent[(x)]))
 
#define SEMU(ix)    ((struct sem_undo *)(((intptr_t)semu) + (ix) * seminfo.semusz))
 
#define SMALL_SOPS   8
 

Functions

 __FBSDID ("$FreeBSD$")
 
 FEATURE (sysv_sem, "System V semaphores support")
 
static MALLOC_DEFINE (M_SEM, "sem", "SVID compatible semaphores")
 
static int seminit (void)
 
static int sysvsem_modload (struct module *, int, void *)
 
static int semunload (void)
 
static void semexit_myhook (void *arg, struct proc *p)
 
static int sysctl_sema (SYSCTL_HANDLER_ARGS)
 
static int semvalid (int semid, struct prison *rpr, struct semid_kernel *semakptr)
 
static void sem_remove (int semidx, struct ucred *cred)
 
static struct prison * sem_find_prison (struct ucred *)
 
static int sem_prison_cansee (struct prison *, struct semid_kernel *)
 
static int sem_prison_check (void *, void *)
 
static int sem_prison_set (void *, void *)
 
static int sem_prison_get (void *, void *)
 
static int sem_prison_remove (void *, void *)
 
static void sem_prison_cleanup (struct prison *)
 
int __semctl (struct thread *td, struct __semctl_args *uap)
 
int semget (struct thread *td, struct semget_args *uap)
 
int semop (struct thread *td, struct semop_args *uap)
 
static struct sem_undosemu_alloc (struct thread *td)
 
static int semundo_adjust (struct thread *td, struct sem_undo **supptr, int semid, int semseq, int semnum, int adjval)
 
static void semundo_clear (int semid, int semnum)
 
 LIST_HEAD (sem_undo)
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semmni, CTLFLAG_RDTUN, &seminfo.semmni, 0, "Number of semaphore identifiers")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semmns, CTLFLAG_RDTUN, &seminfo.semmns, 0, "Maximum number of semaphores in the system")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semmnu, CTLFLAG_RDTUN, &seminfo.semmnu, 0, "Maximum number of undo structures in the system")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semmsl, CTLFLAG_RWTUN, &seminfo.semmsl, 0, "Max semaphores per id")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semopm, CTLFLAG_RDTUN, &seminfo.semopm, 0, "Max operations per semop call")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semume, CTLFLAG_RDTUN, &seminfo.semume, 0, "Max undo entries per process")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semusz, CTLFLAG_RD, &seminfo.semusz, 0, "Size in bytes of undo structure")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semvmx, CTLFLAG_RWTUN, &seminfo.semvmx, 0, "Semaphore maximum value")
 
 SYSCTL_INT (_kern_ipc, OID_AUTO, semaem, CTLFLAG_RWTUN, &seminfo.semaem, 0, "Adjust on exit max value")
 
 SYSCTL_PROC (_kern_ipc, OID_AUTO, sema, CTLTYPE_OPAQUE|CTLFLAG_RD|CTLFLAG_MPSAFE, NULL, 0, sysctl_sema, "", "Array of struct semid_kernel for each potential semaphore")
 
 DECLARE_MODULE (sysvsem, sysvsem_mod, SI_SUB_SYSV_SEM, SI_ORDER_FIRST)
 
 MODULE_VERSION (sysvsem, 1)
 
static int semu_try_free (struct sem_undo *suptr)
 
int sys___semctl (struct thread *td, struct __semctl_args *uap)
 
int kern_semctl (struct thread *td, int semid, int semnum, int cmd, union semun *arg, register_t *rval)
 
int sys_semget (struct thread *td, struct semget_args *uap)
 
int sys_semop (struct thread *td, struct semop_args *uap)
 
static int sem_prison_remove (void *obj, void *data __unused)
 
 SYSCTL_JAIL_PARAM_SYS_NODE (sysvsem, CTLFLAG_RW, "SYSV semaphores")
 

Variables

static struct mtx sem_mtx
 
static struct mtx sem_undo_mtx
 
static int semtot = 0
 
static struct semid_kernel * sema
 
static struct mtxsema_mtx
 
static struct sem * sem
 
struct seminfo seminfo
 
static struct syscall_helper_data sem_syscalls []
 
static moduledata_t sysvsem_mod
 

Macro Definition Documentation

◆ DPRINTF

#define DPRINTF (   a)

Definition at line 83 of file sysv_sem.c.

◆ SEM_ALIGN

#define SEM_ALIGN (   bytes)    roundup2(bytes, sizeof(long))

Definition at line 187 of file sysv_sem.c.

◆ SEMAEM

#define SEMAEM   16384 /* adjust on exit max value */

Definition at line 180 of file sysv_sem.c.

◆ SEMMNI

#define SEMMNI   50 /* # of semaphore identifiers */

Definition at line 159 of file sysv_sem.c.

◆ SEMMNS

#define SEMMNS   340 /* # of semaphores in system */

Definition at line 162 of file sysv_sem.c.

◆ SEMMNU

#define SEMMNU   150 /* # of undo structures in system */

Definition at line 168 of file sysv_sem.c.

◆ SEMMSL

#define SEMMSL   SEMMNS /* max # of semaphores per id */

Definition at line 173 of file sysv_sem.c.

◆ SEMOPM

#define SEMOPM   100 /* max # of operations per semop call */

Definition at line 176 of file sysv_sem.c.

◆ SEMU

#define SEMU (   ix)     ((struct sem_undo *)(((intptr_t)semu) + (ix) * seminfo.semusz))

Definition at line 195 of file sysv_sem.c.

◆ SEMUME

#define SEMUME   50 /* max # of undo entries per process */

Definition at line 165 of file sysv_sem.c.

◆ SEMUNDO_LOCK

#define SEMUNDO_LOCK ( )    mtx_lock(&SEMUNDO_MTX);

◆ SEMUNDO_LOCKASSERT

#define SEMUNDO_LOCKASSERT (   how)    mtx_assert(&SEMUNDO_MTX, (how));

◆ SEMUNDO_MTX

#define SEMUNDO_MTX   sem_undo_mtx

◆ SEMUNDO_UNLOCK

#define SEMUNDO_UNLOCK ( )    mtx_unlock(&SEMUNDO_MTX);

◆ SEMUSZ

#define SEMUSZ (   x)    SEM_ALIGN(offsetof(struct sem_undo, un_ent[(x)]))

Definition at line 190 of file sysv_sem.c.

◆ SEMVMX

#define SEMVMX   32767 /* semaphore maximum value */

Definition at line 179 of file sysv_sem.c.

◆ SMALL_SOPS

#define SMALL_SOPS   8

Function Documentation

◆ __FBSDID()

__FBSDID ( "$FreeBSD$"  )

◆ __semctl()

int __semctl ( struct thread *  td,
struct __semctl_args uap 
)

◆ DECLARE_MODULE()

DECLARE_MODULE ( sysvsem  ,
sysvsem_mod  ,
SI_SUB_SYSV_SEM  ,
SI_ORDER_FIRST   
)

◆ FEATURE()

FEATURE ( sysv_sem  ,
"System V semaphores support"   
)

◆ kern_semctl()

int kern_semctl ( struct thread *  td,
int  semid,
int  semnum,
int  cmd,
union semun *  arg,
register_t *  rval 
)

Definition at line 693 of file sysv_sem.c.

References count, DPRINTF, free(), ipcperm(), malloc(), mtx, sem, sem_find_prison(), sem_mtx, sem_prison_cansee(), sem_remove(), sema, sema_mtx, seminfo, semundo_clear(), SEMUNDO_LOCK, SEMUNDO_UNLOCK, semvalid(), time_second, and wakeup().

Referenced by sys___semctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ LIST_HEAD()

LIST_HEAD ( sem_undo  )

Definition at line 122 of file sysv_sem.c.

◆ MALLOC_DEFINE()

static MALLOC_DEFINE ( M_SEM  ,
"sem"  ,
"SVID compatible semaphores"   
)
static

◆ MODULE_VERSION()

MODULE_VERSION ( sysvsem  ,
 
)

◆ sem_find_prison()

static struct prison * sem_find_prison ( struct ucred *  cred)
static

Definition at line 601 of file sysv_sem.c.

References pr.

Referenced by kern_semctl(), sys_semget(), sys_semop(), and sysctl_sema().

Here is the caller graph for this function:

◆ sem_prison_cansee()

static int sem_prison_cansee ( struct prison *  rpr,
struct semid_kernel *  semakptr 
)
static

Definition at line 613 of file sysv_sem.c.

References prison_ischild().

Referenced by kern_semctl(), semvalid(), sys_semop(), and sysctl_sema().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sem_prison_check()

static int sem_prison_check ( void *  obj,
void *  data 
)
static

Definition at line 1554 of file sysv_sem.c.

References data, pr, and vfs_copyopt().

Referenced by seminit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sem_prison_cleanup()

static void sem_prison_cleanup ( struct prison *  pr)
static

Definition at line 1710 of file sysv_sem.c.

References pr, sem_mtx, sem_remove(), sema, sema_mtx, and seminfo.

Referenced by sem_prison_remove(), and sem_prison_set().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sem_prison_get()

static int sem_prison_get ( void *  obj,
void *  data 
)
static

Definition at line 1676 of file sysv_sem.c.

References data, pr, and vfs_setopt().

Referenced by seminit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sem_prison_remove() [1/2]

static int sem_prison_remove ( void *  ,
void *   
)
static

Referenced by seminit().

Here is the caller graph for this function:

◆ sem_prison_remove() [2/2]

static int sem_prison_remove ( void *  obj,
void *data  __unused 
)
static

Definition at line 1696 of file sysv_sem.c.

References pr, and sem_prison_cleanup().

Here is the call graph for this function:

◆ sem_prison_set()

static int sem_prison_set ( void *  obj,
void *  data 
)
static

Definition at line 1589 of file sysv_sem.c.

References data, osd_free_reserved(), osd_reserve(), pr, sem_prison_cleanup(), vfs_copyopt(), and vfs_flagopt().

Referenced by seminit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sem_remove()

static void sem_remove ( int  semidx,
struct ucred *  cred 
)
static

Definition at line 555 of file sysv_sem.c.

References crfree(), sem, sem_mtx, sema, sema_mtx, seminfo, semtot, semundo_clear(), SEMUNDO_LOCK, SEMUNDO_UNLOCK, and wakeup().

Referenced by kern_semctl(), and sem_prison_cleanup().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semexit_myhook()

static void semexit_myhook ( void *  arg,
struct proc *  p 
)
static

Definition at line 1419 of file sysv_sem.c.

References DPRINTF, mtx, panic(), sema, sema_mtx, SEMUNDO_LOCK, SEMUNDO_UNLOCK, sem_undo::un_ent, and wakeup().

Referenced by seminit().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semget()

int semget ( struct thread *  td,
struct semget_args uap 
)

◆ seminit()

static int seminit ( void  )
static

Definition at line 270 of file sysv_sem.c.

References allprison, allprison_lock, malloc(), mtx, osd_free_reserved(), osd_reserve(), pr, prison0, sem, sem_mtx, sem_prison_check(), sem_prison_get(), sem_prison_remove(), sem_prison_set(), sem_syscalls, sem_undo_mtx, sema, sema_mtx, semexit_myhook(), seminfo, SEMU, SEMUSZ, and syscall_helper_register().

Referenced by sysvsem_modload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semop()

int semop ( struct thread *  td,
struct semop_args uap 
)

◆ semu_alloc()

static struct sem_undo * semu_alloc ( struct thread *  td)
static

Definition at line 413 of file sysv_sem.c.

References SEMUNDO_LOCKASSERT.

Referenced by semundo_adjust().

Here is the caller graph for this function:

◆ semu_try_free()

static int semu_try_free ( struct sem_undo suptr)
static

Definition at line 428 of file sysv_sem.c.

References SEMUNDO_LOCKASSERT.

Referenced by semundo_adjust(), and semundo_clear().

Here is the caller graph for this function:

◆ semundo_adjust()

static int semundo_adjust ( struct thread *  td,
struct sem_undo **  supptr,
int  semid,
int  semseq,
int  semnum,
int  adjval 
)
static

Definition at line 445 of file sysv_sem.c.

References seminfo, semu_alloc(), semu_try_free(), SEMUNDO_LOCKASSERT, and sem_undo::un_ent.

Referenced by sys_semop().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semundo_clear()

static void semundo_clear ( int  semid,
int  semnum 
)
static

Definition at line 518 of file sysv_sem.c.

References semu_try_free(), SEMUNDO_LOCKASSERT, and sem_undo::un_ent.

Referenced by kern_semctl(), and sem_remove().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semunload()

static int semunload ( void  )
static

Definition at line 347 of file sysv_sem.c.

References free(), sem, sem_mtx, sem_syscalls, sem_undo_mtx, sema, sema_mtx, seminfo, semtot, and syscall_helper_unregister().

Referenced by sysvsem_modload().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ semvalid()

static int semvalid ( int  semid,
struct prison *  rpr,
struct semid_kernel *  semakptr 
)
static

Definition at line 546 of file sysv_sem.c.

References sem_prison_cansee().

Referenced by kern_semctl().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ sys___semctl()

int sys___semctl ( struct thread *  td,
struct __semctl_args uap 
)

Definition at line 635 of file sysv_sem.c.

References __semctl_args::arg, __semctl_args::cmd, kern_semctl(), __semctl_args::semid, and __semctl_args::semnum.

Here is the call graph for this function:

◆ sys_semget()

int sys_semget ( struct thread *  td,
struct semget_args uap 
)

Definition at line 967 of file sysv_sem.c.

References crhold(), DPRINTF, ipcperm(), semget_args::key, semget_args::nsems, sem, sem_find_prison(), sem_mtx, sema, sema_mtx, semget_args::semflg, seminfo, semtot, and time_second.

Here is the call graph for this function:

◆ sys_semop()

int sys_semop ( struct thread *  td,
struct semop_args uap 
)

◆ SYSCTL_INT() [1/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semaem  ,
CTLFLAG_RWTUN  ,
&seminfo.  semaem,
,
"Adjust on exit max value  
)

◆ SYSCTL_INT() [2/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semmni  ,
CTLFLAG_RDTUN  ,
&seminfo.  semmni,
,
"Number of semaphore identifiers"   
)

◆ SYSCTL_INT() [3/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semmns  ,
CTLFLAG_RDTUN  ,
&seminfo.  semmns,
,
"Maximum number of semaphores in the system"   
)

◆ SYSCTL_INT() [4/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semmnu  ,
CTLFLAG_RDTUN  ,
&seminfo.  semmnu,
,
"Maximum number of undo structures in the system"   
)

◆ SYSCTL_INT() [5/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semmsl  ,
CTLFLAG_RWTUN  ,
&seminfo.  semmsl,
,
"Max semaphores per id"   
)

◆ SYSCTL_INT() [6/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semopm  ,
CTLFLAG_RDTUN  ,
&seminfo.  semopm,
,
"Max operations per semop call"   
)

◆ SYSCTL_INT() [7/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semume  ,
CTLFLAG_RDTUN  ,
&seminfo.  semume,
,
"Max undo entries per process"   
)

◆ SYSCTL_INT() [8/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semusz  ,
CTLFLAG_RD  ,
&seminfo.  semusz,
,
"Size in bytes of undo structure"   
)

◆ SYSCTL_INT() [9/9]

SYSCTL_INT ( _kern_ipc  ,
OID_AUTO  ,
semvmx  ,
CTLFLAG_RWTUN  ,
&seminfo.  semvmx,
,
"Semaphore maximum value  
)

◆ SYSCTL_JAIL_PARAM_SYS_NODE()

SYSCTL_JAIL_PARAM_SYS_NODE ( sysvsem  ,
CTLFLAG_RW  ,
"SYSV semaphores"   
)

◆ SYSCTL_PROC()

SYSCTL_PROC ( _kern_ipc  ,
OID_AUTO  ,
sema  ,
CTLTYPE_OPAQUE|CTLFLAG_RD|  CTLFLAG_MPSAFE,
NULL  ,
,
sysctl_sema  ,
""  ,
"Array of struct semid_kernel for each potential semaphore"   
)

◆ sysctl_sema()

static int sysctl_sema ( SYSCTL_HANDLER_ARGS  )
static

Definition at line 1500 of file sysv_sem.c.

References pr, sem_find_prison(), sem_prison_cansee(), sema, sema_mtx, and seminfo.

Here is the call graph for this function:

◆ sysvsem_modload()

static int sysvsem_modload ( struct module module,
int  cmd,
void *  arg 
)
static

Definition at line 378 of file sysv_sem.c.

References seminit(), and semunload().

Here is the call graph for this function:

Variable Documentation

◆ sem

struct sem* sem
static

◆ sem_mtx

struct mtx sem_mtx
static

Definition at line 116 of file sysv_sem.c.

Referenced by kern_semctl(), sem_prison_cleanup(), sem_remove(), seminit(), semunload(), and sys_semget().

◆ sem_syscalls

struct syscall_helper_data sem_syscalls[]
static
Initial value:
= {
SYSCALL_INIT_HELPER(__semctl),
SYSCALL_INIT_HELPER(semget),
SYSCALL_INIT_HELPER(semop),
SYSCALL_INIT_LAST
}
int semop(struct thread *td, struct semop_args *uap)
int semget(struct thread *td, struct semget_args *uap)
int __semctl(struct thread *td, struct __semctl_args *uap)

Definition at line 236 of file sysv_sem.c.

Referenced by seminit(), and semunload().

◆ sem_undo_mtx

struct mtx sem_undo_mtx
static

Definition at line 117 of file sysv_sem.c.

Referenced by seminit(), and semunload().

◆ sema

◆ sema_mtx

struct mtx* sema_mtx
static

◆ seminfo

struct seminfo seminfo
Initial value:
= {
.semmni = SEMMNI,
.semmns = SEMMNS,
.semmnu = SEMMNU,
.semmsl = SEMMSL,
.semopm = SEMOPM,
.semume = SEMUME,
.semusz = SEMUSZ(SEMUME),
.semvmx = SEMVMX,
.semaem = SEMAEM,
}
#define SEMOPM
Definition: sysv_sem.c:176
#define SEMUME
Definition: sysv_sem.c:165
#define SEMAEM
Definition: sysv_sem.c:180
#define SEMMNI
Definition: sysv_sem.c:159
#define SEMUSZ(x)
Definition: sysv_sem.c:190
#define SEMVMX
Definition: sysv_sem.c:179
#define SEMMNU
Definition: sysv_sem.c:168
#define SEMMSL
Definition: sysv_sem.c:173
#define SEMMNS
Definition: sysv_sem.c:162

Definition at line 201 of file sysv_sem.c.

Referenced by kern_semctl(), sem_prison_cleanup(), sem_remove(), seminit(), semundo_adjust(), semunload(), sys_semget(), sys_semop(), and sysctl_sema().

◆ semtot

int semtot = 0
static

Definition at line 118 of file sysv_sem.c.

Referenced by sem_remove(), semunload(), and sys_semget().

◆ sysvsem_mod

moduledata_t sysvsem_mod
static
Initial value:
= {
"sysvsem",
NULL
}
static int sysvsem_modload(struct module *, int, void *)
Definition: sysv_sem.c:378

Definition at line 398 of file sysv_sem.c.