| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: uipc_sem.c,v 1.59 2020/05/04 13:58:48 riastradh Exp $ */ | | 1 | /* $NetBSD: uipc_sem.c,v 1.60 2020/12/14 23:12:12 chs Exp $ */ |
2 | | | 2 | |
3 | /*- | | 3 | /*- |
4 | * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc. | | 4 | * Copyright (c) 2011, 2019 The NetBSD Foundation, Inc. |
5 | * All rights reserved. | | 5 | * All rights reserved. |
6 | * | | 6 | * |
7 | * This code is derived from software contributed to The NetBSD Foundation | | 7 | * This code is derived from software contributed to The NetBSD Foundation |
8 | * by Mindaugas Rasiukevicius and Jason R. Thorpe. | | 8 | * by Mindaugas Rasiukevicius and Jason R. Thorpe. |
9 | * | | 9 | * |
10 | * Redistribution and use in source and binary forms, with or without | | 10 | * Redistribution and use in source and binary forms, with or without |
11 | * modification, are permitted provided that the following conditions | | 11 | * modification, are permitted provided that the following conditions |
12 | * are met: | | 12 | * are met: |
13 | * 1. Redistributions of source code must retain the above copyright | | 13 | * 1. Redistributions of source code must retain the above copyright |
14 | * notice, this list of conditions and the following disclaimer. | | 14 | * notice, this list of conditions and the following disclaimer. |
| @@ -50,27 +50,27 @@ | | | @@ -50,27 +50,27 @@ |
50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | | 50 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 51 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | | 52 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | | 53 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | | 54 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
55 | * SUCH DAMAGE. | | 55 | * SUCH DAMAGE. |
56 | */ | | 56 | */ |
57 | | | 57 | |
58 | /* | | 58 | /* |
59 | * Implementation of POSIX semaphore. | | 59 | * Implementation of POSIX semaphore. |
60 | */ | | 60 | */ |
61 | | | 61 | |
62 | #include <sys/cdefs.h> | | 62 | #include <sys/cdefs.h> |
63 | __KERNEL_RCSID(0, "$NetBSD: uipc_sem.c,v 1.59 2020/05/04 13:58:48 riastradh Exp $"); | | 63 | __KERNEL_RCSID(0, "$NetBSD: uipc_sem.c,v 1.60 2020/12/14 23:12:12 chs Exp $"); |
64 | | | 64 | |
65 | #include <sys/param.h> | | 65 | #include <sys/param.h> |
66 | #include <sys/kernel.h> | | 66 | #include <sys/kernel.h> |
67 | | | 67 | |
68 | #include <sys/atomic.h> | | 68 | #include <sys/atomic.h> |
69 | #include <sys/proc.h> | | 69 | #include <sys/proc.h> |
70 | #include <sys/lwp.h> | | 70 | #include <sys/lwp.h> |
71 | #include <sys/ksem.h> | | 71 | #include <sys/ksem.h> |
72 | #include <sys/syscall.h> | | 72 | #include <sys/syscall.h> |
73 | #include <sys/stat.h> | | 73 | #include <sys/stat.h> |
74 | #include <sys/kmem.h> | | 74 | #include <sys/kmem.h> |
75 | #include <sys/fcntl.h> | | 75 | #include <sys/fcntl.h> |
76 | #include <sys/file.h> | | 76 | #include <sys/file.h> |
| @@ -459,66 +459,65 @@ ksem_create(lwp_t *l, const char *name, | | | @@ -459,66 +459,65 @@ ksem_create(lwp_t *l, const char *name, |
459 | return ENAMETOOLONG; | | 459 | return ENAMETOOLONG; |
460 | } | | 460 | } |
461 | /* Name must start with a '/' but not contain one. */ | | 461 | /* Name must start with a '/' but not contain one. */ |
462 | if (*name != '/' || len < 2 || strchr(name + 1, '/') != NULL) { | | 462 | if (*name != '/' || len < 2 || strchr(name + 1, '/') != NULL) { |
463 | return EINVAL; | | 463 | return EINVAL; |
464 | } | | 464 | } |
465 | kname = kmem_alloc(++len, KM_SLEEP); | | 465 | kname = kmem_alloc(++len, KM_SLEEP); |
466 | strlcpy(kname, name, len); | | 466 | strlcpy(kname, name, len); |
467 | } else { | | 467 | } else { |
468 | kname = NULL; | | 468 | kname = NULL; |
469 | len = 0; | | 469 | len = 0; |
470 | } | | 470 | } |
471 | | | 471 | |
472 | chgsemcnt(kauth_cred_getuid(l->l_cred), 1); | | | |
473 | | | | |
474 | ks = kmem_zalloc(sizeof(ksem_t), KM_SLEEP); | | 472 | ks = kmem_zalloc(sizeof(ksem_t), KM_SLEEP); |
475 | mutex_init(&ks->ks_lock, MUTEX_DEFAULT, IPL_NONE); | | 473 | mutex_init(&ks->ks_lock, MUTEX_DEFAULT, IPL_NONE); |
476 | cv_init(&ks->ks_cv, "psem"); | | 474 | cv_init(&ks->ks_cv, "psem"); |
477 | ks->ks_name = kname; | | 475 | ks->ks_name = kname; |
478 | ks->ks_namelen = len; | | 476 | ks->ks_namelen = len; |
479 | ks->ks_mode = mode; | | 477 | ks->ks_mode = mode; |
480 | ks->ks_value = val; | | 478 | ks->ks_value = val; |
481 | ks->ks_ref = 1; | | 479 | ks->ks_ref = 1; |
482 | | | 480 | |
483 | uc = l->l_cred; | | 481 | uc = l->l_cred; |
484 | ks->ks_uid = kauth_cred_geteuid(uc); | | 482 | ks->ks_uid = kauth_cred_geteuid(uc); |
485 | ks->ks_gid = kauth_cred_getegid(uc); | | 483 | ks->ks_gid = kauth_cred_getegid(uc); |
486 | | | 484 | chgsemcnt(ks->ks_uid, 1); |
487 | atomic_inc_uint(&nsems_total); | | 485 | atomic_inc_uint(&nsems_total); |
| | | 486 | |
488 | *ksret = ks; | | 487 | *ksret = ks; |
489 | return 0; | | 488 | return 0; |
490 | } | | 489 | } |
491 | | | 490 | |
492 | static void | | 491 | static void |
493 | ksem_free(ksem_t *ks) | | 492 | ksem_free(ksem_t *ks) |
494 | { | | 493 | { |
495 | | | 494 | |
496 | KASSERT(!cv_has_waiters(&ks->ks_cv)); | | 495 | KASSERT(!cv_has_waiters(&ks->ks_cv)); |
497 | | | 496 | |
| | | 497 | chgsemcnt(ks->ks_uid, -1); |
| | | 498 | atomic_dec_uint(&nsems_total); |
| | | 499 | |
498 | if (ks->ks_pshared_id) { | | 500 | if (ks->ks_pshared_id) { |
499 | KASSERT(ks->ks_pshared_proc == NULL); | | 501 | KASSERT(ks->ks_pshared_proc == NULL); |
500 | ksem_remove_pshared(ks); | | 502 | ksem_remove_pshared(ks); |
501 | } | | 503 | } |
502 | if (ks->ks_name) { | | 504 | if (ks->ks_name) { |
503 | KASSERT(ks->ks_namelen > 0); | | 505 | KASSERT(ks->ks_namelen > 0); |
504 | kmem_free(ks->ks_name, ks->ks_namelen); | | 506 | kmem_free(ks->ks_name, ks->ks_namelen); |
505 | } | | 507 | } |
506 | mutex_destroy(&ks->ks_lock); | | 508 | mutex_destroy(&ks->ks_lock); |
507 | cv_destroy(&ks->ks_cv); | | 509 | cv_destroy(&ks->ks_cv); |
508 | kmem_free(ks, sizeof(ksem_t)); | | 510 | kmem_free(ks, sizeof(ksem_t)); |
509 | | | | |
510 | atomic_dec_uint(&nsems_total); | | | |
511 | chgsemcnt(kauth_cred_getuid(curproc->p_cred), -1); | | | |
512 | } | | 511 | } |
513 | | | 512 | |
514 | #define KSEM_ID_IS_PSHARED(id) \ | | 513 | #define KSEM_ID_IS_PSHARED(id) \ |
515 | (((id) & KSEM_MARKER_MASK) == KSEM_PSHARED_MARKER) | | 514 | (((id) & KSEM_MARKER_MASK) == KSEM_PSHARED_MARKER) |
516 | | | 515 | |
517 | static void | | 516 | static void |
518 | ksem_release(ksem_t *ksem, int fd) | | 517 | ksem_release(ksem_t *ksem, int fd) |
519 | { | | 518 | { |
520 | bool destroy = false; | | 519 | bool destroy = false; |
521 | | | 520 | |
522 | KASSERT(mutex_owned(&ksem->ks_lock)); | | 521 | KASSERT(mutex_owned(&ksem->ks_lock)); |
523 | | | 522 | |
524 | KASSERT(ksem->ks_ref > 0); | | 523 | KASSERT(ksem->ks_ref > 0); |