Lines Matching +full:path +full:- +full:map

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
5 * Copyright (c) 2003-2005 SPARTA, Inc.
6 * Copyright (c) 2005, 2016-2017 Robert N. M. Watson
11 * Associates, Inc. under DARPA/SPAWAR contract N66001-01-C-8035 ("CBOSS"),
16 * contract FA8650-15-C-7558 ("CADETS"), as part of the DARPA Transparent
80 * - Resource limits?
81 * - Replace global sem_lock with mtx_pool locks?
82 * - Add a MAC check_create() hook for creating new named semaphores.
122 static int ksem_create(struct thread *td, const char *path,
129 static void ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks);
130 static struct ksem *ksem_lookup(char *path, Fnv32_t fnv);
133 static int ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred);
170 ks = fp->f_data; in ksem_stat()
173 error = mac_posixsem_check_stat(active_cred, fp->f_cred, ks); in ksem_stat()
185 sb->st_atim = ks->ks_atime; in ksem_stat()
186 sb->st_ctim = ks->ks_ctime; in ksem_stat()
187 sb->st_mtim = ks->ks_mtime; in ksem_stat()
188 sb->st_birthtim = ks->ks_birthtime; in ksem_stat()
189 sb->st_uid = ks->ks_uid; in ksem_stat()
190 sb->st_gid = ks->ks_gid; in ksem_stat()
191 sb->st_mode = S_IFREG | ks->ks_mode; /* XXX */ in ksem_stat()
205 ks = fp->f_data; in ksem_chmod()
212 error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid, VADMIN, in ksem_chmod()
216 ks->ks_mode = mode & ACCESSPERMS; in ksem_chmod()
230 ks = fp->f_data; in ksem_chown()
237 if (uid == (uid_t)-1) in ksem_chown()
238 uid = ks->ks_uid; in ksem_chown()
239 if (gid == (gid_t)-1) in ksem_chown()
240 gid = ks->ks_gid; in ksem_chown()
241 if (((uid != ks->ks_uid && uid != active_cred->cr_uid) || in ksem_chown()
242 (gid != ks->ks_gid && !groupmember(gid, active_cred))) && in ksem_chown()
245 ks->ks_uid = uid; in ksem_chown()
246 ks->ks_gid = gid; in ksem_chown()
257 ks = fp->f_data; in ksem_closef()
258 fp->f_data = NULL; in ksem_closef()
267 const char *path, *pr_path; in ksem_fill_kinfo() local
271 kif->kf_type = KF_TYPE_SEM; in ksem_fill_kinfo()
272 ks = fp->f_data; in ksem_fill_kinfo()
274 kif->kf_un.kf_sem.kf_sem_value = ks->ks_value; in ksem_fill_kinfo()
275 kif->kf_un.kf_sem.kf_sem_mode = S_IFREG | ks->ks_mode; /* XXX */ in ksem_fill_kinfo()
277 if (ks->ks_path != NULL) { in ksem_fill_kinfo()
279 if (ks->ks_path != NULL) { in ksem_fill_kinfo()
280 path = ks->ks_path; in ksem_fill_kinfo()
281 pr_path = curthread->td_ucred->cr_prison->pr_path; in ksem_fill_kinfo()
283 /* Return the jail-rooted pathname. */ in ksem_fill_kinfo()
285 if (strncmp(path, pr_path, pr_pathlen) == 0 && in ksem_fill_kinfo()
286 path[pr_pathlen] == '/') in ksem_fill_kinfo()
287 path += pr_pathlen; in ksem_fill_kinfo()
289 strlcpy(kif->kf_path, path, sizeof(kif->kf_path)); in ksem_fill_kinfo()
313 ks->ks_uid = ucred->cr_uid; in ksem_alloc()
314 ks->ks_gid = ucred->cr_gid; in ksem_alloc()
315 ks->ks_mode = mode; in ksem_alloc()
316 ks->ks_value = value; in ksem_alloc()
317 cv_init(&ks->ks_cv, "ksem"); in ksem_alloc()
318 vfs_timestamp(&ks->ks_birthtime); in ksem_alloc()
319 ks->ks_atime = ks->ks_mtime = ks->ks_ctime = ks->ks_birthtime; in ksem_alloc()
320 refcount_init(&ks->ks_ref, 1); in ksem_alloc()
333 refcount_acquire(&ks->ks_ref); in ksem_hold()
341 if (refcount_release(&ks->ks_ref)) { in ksem_drop()
345 cv_destroy(&ks->ks_cv); in ksem_drop()
348 nsems--; in ksem_drop()
362 error = vaccess(VREG, ks->ks_mode, ks->ks_uid, ks->ks_gid, in ksem_access()
370 * Dictionary management. We maintain an in-kernel dictionary to map
371 * paths to semaphore objects. We use the FNV hash on the path to
375 ksem_lookup(char *path, Fnv32_t fnv) in ksem_lookup() argument
377 struct ksem_mapping *map; in ksem_lookup() local
379 LIST_FOREACH(map, KSEM_HASH(fnv), km_link) { in ksem_lookup()
380 if (map->km_fnv != fnv) in ksem_lookup()
382 if (strcmp(map->km_path, path) == 0) in ksem_lookup()
383 return (map->km_ksem); in ksem_lookup()
390 ksem_insert(char *path, Fnv32_t fnv, struct ksem *ks) in ksem_insert() argument
392 struct ksem_mapping *map; in ksem_insert() local
394 map = malloc(sizeof(struct ksem_mapping), M_KSEM, M_WAITOK); in ksem_insert()
395 map->km_path = path; in ksem_insert()
396 map->km_fnv = fnv; in ksem_insert()
397 map->km_ksem = ksem_hold(ks); in ksem_insert()
398 ks->ks_path = path; in ksem_insert()
399 LIST_INSERT_HEAD(KSEM_HASH(fnv), map, km_link); in ksem_insert()
403 ksem_remove(char *path, Fnv32_t fnv, struct ucred *ucred) in ksem_remove() argument
405 struct ksem_mapping *map; in ksem_remove() local
408 LIST_FOREACH(map, KSEM_HASH(fnv), km_link) { in ksem_remove()
409 if (map->km_fnv != fnv) in ksem_remove()
411 if (strcmp(map->km_path, path) == 0) { in ksem_remove()
413 error = mac_posixsem_check_unlink(ucred, map->km_ksem); in ksem_remove()
417 error = ksem_access(map->km_ksem, ucred); in ksem_remove()
420 map->km_ksem->ks_path = NULL; in ksem_remove()
421 LIST_REMOVE(map, km_link); in ksem_remove()
422 ksem_drop(map->km_ksem); in ksem_remove()
423 free(map->km_path, M_KSEM); in ksem_remove()
424 free(map, M_KSEM); in ksem_remove()
469 char *path; in ksem_create() local
482 pdp = td->td_proc->p_pd; in ksem_create()
483 mode = (mode & ~pdp->pd_cmask) & ACCESSPERMS; in ksem_create()
505 ks = ksem_alloc(td->td_ucred, mode, value); in ksem_create()
509 ks->ks_flags |= KS_ANONYMOUS; in ksem_create()
511 path = malloc(MAXPATHLEN, M_KSEM, M_WAITOK); in ksem_create()
512 pr_path = td->td_ucred->cr_prison->pr_path; in ksem_create()
516 : strlcpy(path, pr_path, MAXPATHLEN); in ksem_create()
517 error = copyinstr(name, path + pr_pathlen, in ksem_create()
518 MAXPATHLEN - pr_pathlen, NULL); in ksem_create()
521 if (error == 0 && path[pr_pathlen] != '/') in ksem_create()
526 free(path, M_KSEM); in ksem_create()
530 AUDIT_ARG_UPATH1_CANON(path); in ksem_create()
531 fnv = fnv_32_str(path, FNV1_32_INIT); in ksem_create()
533 ks = ksem_lookup(path, fnv); in ksem_create()
537 ks = ksem_alloc(td->td_ucred, mode, value); in ksem_create()
541 ksem_insert(path, fnv, ks); in ksem_create()
542 path = NULL; in ksem_create()
556 error = mac_posixsem_check_open(td->td_ucred, in ksem_create()
560 error = ksem_access(ks, td->td_ucred); in ksem_create()
570 if (path) in ksem_create()
571 free(path, M_KSEM); in ksem_create()
600 if (fp->f_type != DTYPE_SEM) { in ksem_get()
604 ks = fp->f_data; in ksem_get()
605 if (ks->ks_flags & KS_DEAD) { in ksem_get()
624 return (ksem_create(td, NULL, uap->idp, S_IRWXU | S_IRWXG, uap->value, in sys_ksem_init()
641 DP((">>> ksem_open start, pid=%d\n", (int)td->td_proc->p_pid)); in sys_ksem_open()
643 if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0) in sys_ksem_open()
645 return (ksem_create(td, uap->name, uap->idp, uap->mode, uap->value, in sys_ksem_open()
646 uap->oflag, 0)); in sys_ksem_open()
657 char *path; in sys_ksem_unlink() local
663 path = malloc(MAXPATHLEN, M_TEMP, M_WAITOK); in sys_ksem_unlink()
664 pr_path = td->td_ucred->cr_prison->pr_path; in sys_ksem_unlink()
666 : strlcpy(path, pr_path, MAXPATHLEN); in sys_ksem_unlink()
667 error = copyinstr(uap->name, path + pr_pathlen, MAXPATHLEN - pr_pathlen, in sys_ksem_unlink()
670 free(path, M_TEMP); in sys_ksem_unlink()
674 AUDIT_ARG_UPATH1_CANON(path); in sys_ksem_unlink()
675 fnv = fnv_32_str(path, FNV1_32_INIT); in sys_ksem_unlink()
677 error = ksem_remove(path, fnv, td->td_ucred); in sys_ksem_unlink()
679 free(path, M_TEMP); in sys_ksem_unlink()
697 AUDIT_ARG_FD(uap->id); in sys_ksem_close()
698 error = ksem_get(td, uap->id, &cap_no_rights, &fp); in sys_ksem_close()
701 ks = fp->f_data; in sys_ksem_close()
702 if (ks->ks_flags & KS_ANONYMOUS) { in sys_ksem_close()
706 error = kern_close(td, uap->id); in sys_ksem_close()
724 AUDIT_ARG_FD(uap->id); in sys_ksem_post()
725 error = ksem_get(td, uap->id, in sys_ksem_post()
729 ks = fp->f_data; in sys_ksem_post()
733 error = mac_posixsem_check_post(td->td_ucred, fp->f_cred, ks); in sys_ksem_post()
737 if (ks->ks_value == SEM_VALUE_MAX) { in sys_ksem_post()
741 ++ks->ks_value; in sys_ksem_post()
742 if (ks->ks_waiters > 0) in sys_ksem_post()
743 cv_signal(&ks->ks_cv); in sys_ksem_post()
745 vfs_timestamp(&ks->ks_ctime); in sys_ksem_post()
761 return (kern_sem_wait(td, uap->id, 0, NULL)); in sys_ksem_wait()
780 if (uap->abstime == NULL) in sys_ksem_timedwait()
783 error = copyin(uap->abstime, &abstime, sizeof(abstime)); in sys_ksem_timedwait()
790 return (kern_sem_wait(td, uap->id, 0, ts)); in sys_ksem_timedwait()
802 return (kern_sem_wait(td, uap->id, 1, NULL)); in sys_ksem_trywait()
816 DP((">>> kern_sem_wait entered! pid=%d\n", (int)td->td_proc->p_pid)); in kern_sem_wait()
822 ks = fp->f_data; in kern_sem_wait()
825 (int)td->td_proc->p_pid)); in kern_sem_wait()
827 error = mac_posixsem_check_wait(td->td_ucred, fp->f_cred, ks); in kern_sem_wait()
833 DP(("kern_sem_wait value = %d, tryflag %d\n", ks->ks_value, tryflag)); in kern_sem_wait()
834 vfs_timestamp(&ks->ks_atime); in kern_sem_wait()
835 while (ks->ks_value == 0) { in kern_sem_wait()
836 ks->ks_waiters++; in kern_sem_wait()
840 error = cv_wait_sig(&ks->ks_cv, &sem_lock); in kern_sem_wait()
851 error = cv_timedwait_sig(&ks->ks_cv, in kern_sem_wait()
857 ks->ks_waiters--; in kern_sem_wait()
861 ks->ks_value--; in kern_sem_wait()
862 DP(("kern_sem_wait value post-decrement = %d\n", ks->ks_value)); in kern_sem_wait()
868 (int)td->td_proc->p_pid, error)); in kern_sem_wait()
886 AUDIT_ARG_FD(uap->id); in sys_ksem_getvalue()
887 error = ksem_get(td, uap->id, in sys_ksem_getvalue()
891 ks = fp->f_data; in sys_ksem_getvalue()
895 error = mac_posixsem_check_getvalue(td->td_ucred, fp->f_cred, ks); in sys_ksem_getvalue()
902 val = ks->ks_value; in sys_ksem_getvalue()
903 vfs_timestamp(&ks->ks_atime); in sys_ksem_getvalue()
906 error = copyout(&val, uap->val, sizeof(val)); in sys_ksem_getvalue()
923 AUDIT_ARG_FD(uap->id); in sys_ksem_destroy()
924 error = ksem_get(td, uap->id, &cap_no_rights, &fp); in sys_ksem_destroy()
927 ks = fp->f_data; in sys_ksem_destroy()
928 if (!(ks->ks_flags & KS_ANONYMOUS)) { in sys_ksem_destroy()
933 if (ks->ks_waiters != 0) { in sys_ksem_destroy()
938 ks->ks_flags |= KS_DEAD; in sys_ksem_destroy()
941 error = kern_close(td, uap->id); in sys_ksem_destroy()
972 return (ksem_create(td, NULL, (semid_t *)uap->idp, S_IRWXU | S_IRWXG, uap->value, in freebsd32_ksem_init()
980 if ((uap->oflag & ~(O_CREAT | O_EXCL)) != 0) in freebsd32_ksem_open()
982 return (ksem_create(td, uap->name, (semid_t *)uap->idp, uap->mode, uap->value, in freebsd32_ksem_open()
983 uap->oflag, 1)); in freebsd32_ksem_open()
997 if (uap->abstime == NULL) in freebsd32_ksem_timedwait()
1000 error = copyin(uap->abstime, &abstime32, sizeof(abstime32)); in freebsd32_ksem_timedwait()
1009 return (kern_sem_wait(td, uap->id, 0, ts)); in freebsd32_ksem_timedwait()