1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73#include <linux/compat.h>
74#include <linux/slab.h>
75#include <linux/spinlock.h>
76#include <linux/init.h>
77#include <linux/proc_fs.h>
78#include <linux/time.h>
79#include <linux/security.h>
80#include <linux/syscalls.h>
81#include <linux/audit.h>
82#include <linux/capability.h>
83#include <linux/seq_file.h>
84#include <linux/rwsem.h>
85#include <linux/nsproxy.h>
86#include <linux/ipc_namespace.h>
87#include <linux/sched/wake_q.h>
88#include <linux/nospec.h>
89#include <linux/rhashtable.h>
90
91#include <linux/uaccess.h>
92#include "util.h"
93
94
95struct sem {
96 int semval;
97
98
99
100
101
102
103
104 struct pid *sempid;
105 spinlock_t lock;
106 struct list_head pending_alter;
107
108 struct list_head pending_const;
109
110 time64_t sem_otime;
111} ____cacheline_aligned_in_smp;
112
113
114struct sem_array {
115 struct kern_ipc_perm sem_perm;
116 time64_t sem_ctime;
117 struct list_head pending_alter;
118
119 struct list_head pending_const;
120
121 struct list_head list_id;
122 int sem_nsems;
123 int complex_count;
124 unsigned int use_global_lock;
125
126 struct sem sems[];
127} __randomize_layout;
128
129
130struct sem_queue {
131 struct list_head list;
132 struct task_struct *sleeper;
133 struct sem_undo *undo;
134 struct pid *pid;
135 int status;
136 struct sembuf *sops;
137 struct sembuf *blocking;
138 int nsops;
139 bool alter;
140 bool dupsop;
141};
142
143
144
145
146struct sem_undo {
147 struct list_head list_proc;
148
149
150 struct rcu_head rcu;
151 struct sem_undo_list *ulp;
152 struct list_head list_id;
153
154 int semid;
155 short *semadj;
156
157};
158
159
160
161
162struct sem_undo_list {
163 refcount_t refcnt;
164 spinlock_t lock;
165 struct list_head list_proc;
166};
167
168
169#define sem_ids(ns) ((ns)->ids[IPC_SEM_IDS])
170
171static int newary(struct ipc_namespace *, struct ipc_params *);
172static void freeary(struct ipc_namespace *, struct kern_ipc_perm *);
173#ifdef CONFIG_PROC_FS
174static int sysvipc_sem_proc_show(struct seq_file *s, void *it);
175#endif
176
177#define SEMMSL_FAST 256
178#define SEMOPM_FAST 64
179
180
181
182
183
184
185#define USE_GLOBAL_LOCK_HYSTERESIS 10
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219#define sc_semmsl sem_ctls[0]
220#define sc_semmns sem_ctls[1]
221#define sc_semopm sem_ctls[2]
222#define sc_semmni sem_ctls[3]
223
224void sem_init_ns(struct ipc_namespace *ns)
225{
226 ns->sc_semmsl = SEMMSL;
227 ns->sc_semmns = SEMMNS;
228 ns->sc_semopm = SEMOPM;
229 ns->sc_semmni = SEMMNI;
230 ns->used_sems = 0;
231 ipc_init_ids(&ns->ids[IPC_SEM_IDS]);
232}
233
234#ifdef CONFIG_IPC_NS
235void sem_exit_ns(struct ipc_namespace *ns)
236{
237 free_ipcs(ns, &sem_ids(ns), freeary);
238 idr_destroy(&ns->ids[IPC_SEM_IDS].ipcs_idr);
239 rhashtable_destroy(&ns->ids[IPC_SEM_IDS].key_ht);
240}
241#endif
242
243void __init sem_init(void)
244{
245 sem_init_ns(&init_ipc_ns);
246 ipc_init_proc_interface("sysvipc/sem",
247 " key semid perms nsems uid gid cuid cgid otime ctime\n",
248 IPC_SEM_IDS, sysvipc_sem_proc_show);
249}
250
251
252
253
254
255
256
257
258static void unmerge_queues(struct sem_array *sma)
259{
260 struct sem_queue *q, *tq;
261
262
263 if (sma->complex_count)
264 return;
265
266
267
268
269
270 list_for_each_entry_safe(q, tq, &sma->pending_alter, list) {
271 struct sem *curr;
272 curr = &sma->sems[q->sops[0].sem_num];
273
274 list_add_tail(&q->list, &curr->pending_alter);
275 }
276 INIT_LIST_HEAD(&sma->pending_alter);
277}
278
279
280
281
282
283
284
285
286
287
288static void merge_queues(struct sem_array *sma)
289{
290 int i;
291 for (i = 0; i < sma->sem_nsems; i++) {
292 struct sem *sem = &sma->sems[i];
293
294 list_splice_init(&sem->pending_alter, &sma->pending_alter);
295 }
296}
297
298static void sem_rcu_free(struct rcu_head *head)
299{
300 struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu);
301 struct sem_array *sma = container_of(p, struct sem_array, sem_perm);
302
303 security_sem_free(&sma->sem_perm);
304 kvfree(sma);
305}
306
307
308
309
310
311static void complexmode_enter(struct sem_array *sma)
312{
313 int i;
314 struct sem *sem;
315
316 if (sma->use_global_lock > 0) {
317
318
319
320
321
322 sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS;
323 return;
324 }
325 sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS;
326
327 for (i = 0; i < sma->sem_nsems; i++) {
328 sem = &sma->sems[i];
329 spin_lock(&sem->lock);
330 spin_unlock(&sem->lock);
331 }
332}
333
334
335
336
337
338static void complexmode_tryleave(struct sem_array *sma)
339{
340 if (sma->complex_count) {
341
342
343
344 return;
345 }
346 if (sma->use_global_lock == 1) {
347
348
349
350
351
352
353 smp_store_release(&sma->use_global_lock, 0);
354 } else {
355 sma->use_global_lock--;
356 }
357}
358
359#define SEM_GLOBAL_LOCK (-1)
360
361
362
363
364
365
366
367static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
368 int nsops)
369{
370 struct sem *sem;
371 int idx;
372
373 if (nsops != 1) {
374
375 ipc_lock_object(&sma->sem_perm);
376
377
378 complexmode_enter(sma);
379 return SEM_GLOBAL_LOCK;
380 }
381
382
383
384
385
386
387
388
389 idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
390 sem = &sma->sems[idx];
391
392
393
394
395
396 if (!sma->use_global_lock) {
397
398
399
400
401 spin_lock(&sem->lock);
402
403
404 if (!smp_load_acquire(&sma->use_global_lock)) {
405
406 return sops->sem_num;
407 }
408 spin_unlock(&sem->lock);
409 }
410
411
412 ipc_lock_object(&sma->sem_perm);
413
414 if (sma->use_global_lock == 0) {
415
416
417
418
419
420
421
422
423
424 spin_lock(&sem->lock);
425
426 ipc_unlock_object(&sma->sem_perm);
427 return sops->sem_num;
428 } else {
429
430
431
432
433
434 return SEM_GLOBAL_LOCK;
435 }
436}
437
438static inline void sem_unlock(struct sem_array *sma, int locknum)
439{
440 if (locknum == SEM_GLOBAL_LOCK) {
441 unmerge_queues(sma);
442 complexmode_tryleave(sma);
443 ipc_unlock_object(&sma->sem_perm);
444 } else {
445 struct sem *sem = &sma->sems[locknum];
446 spin_unlock(&sem->lock);
447 }
448}
449
450
451
452
453
454
455
456static inline struct sem_array *sem_obtain_object(struct ipc_namespace *ns, int id)
457{
458 struct kern_ipc_perm *ipcp = ipc_obtain_object_idr(&sem_ids(ns), id);
459
460 if (IS_ERR(ipcp))
461 return ERR_CAST(ipcp);
462
463 return container_of(ipcp, struct sem_array, sem_perm);
464}
465
466static inline struct sem_array *sem_obtain_object_check(struct ipc_namespace *ns,
467 int id)
468{
469 struct kern_ipc_perm *ipcp = ipc_obtain_object_check(&sem_ids(ns), id);
470
471 if (IS_ERR(ipcp))
472 return ERR_CAST(ipcp);
473
474 return container_of(ipcp, struct sem_array, sem_perm);
475}
476
477static inline void sem_lock_and_putref(struct sem_array *sma)
478{
479 sem_lock(sma, NULL, -1);
480 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
481}
482
483static inline void sem_rmid(struct ipc_namespace *ns, struct sem_array *s)
484{
485 ipc_rmid(&sem_ids(ns), &s->sem_perm);
486}
487
488static struct sem_array *sem_alloc(size_t nsems)
489{
490 struct sem_array *sma;
491
492 if (nsems > (INT_MAX - sizeof(*sma)) / sizeof(sma->sems[0]))
493 return NULL;
494
495 sma = kvzalloc(struct_size(sma, sems, nsems), GFP_KERNEL);
496 if (unlikely(!sma))
497 return NULL;
498
499 return sma;
500}
501
502
503
504
505
506
507
508
509static int newary(struct ipc_namespace *ns, struct ipc_params *params)
510{
511 int retval;
512 struct sem_array *sma;
513 key_t key = params->key;
514 int nsems = params->u.nsems;
515 int semflg = params->flg;
516 int i;
517
518 if (!nsems)
519 return -EINVAL;
520 if (ns->used_sems + nsems > ns->sc_semmns)
521 return -ENOSPC;
522
523 sma = sem_alloc(nsems);
524 if (!sma)
525 return -ENOMEM;
526
527 sma->sem_perm.mode = (semflg & S_IRWXUGO);
528 sma->sem_perm.key = key;
529
530 sma->sem_perm.security = NULL;
531 retval = security_sem_alloc(&sma->sem_perm);
532 if (retval) {
533 kvfree(sma);
534 return retval;
535 }
536
537 for (i = 0; i < nsems; i++) {
538 INIT_LIST_HEAD(&sma->sems[i].pending_alter);
539 INIT_LIST_HEAD(&sma->sems[i].pending_const);
540 spin_lock_init(&sma->sems[i].lock);
541 }
542
543 sma->complex_count = 0;
544 sma->use_global_lock = USE_GLOBAL_LOCK_HYSTERESIS;
545 INIT_LIST_HEAD(&sma->pending_alter);
546 INIT_LIST_HEAD(&sma->pending_const);
547 INIT_LIST_HEAD(&sma->list_id);
548 sma->sem_nsems = nsems;
549 sma->sem_ctime = ktime_get_real_seconds();
550
551
552 retval = ipc_addid(&sem_ids(ns), &sma->sem_perm, ns->sc_semmni);
553 if (retval < 0) {
554 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
555 return retval;
556 }
557 ns->used_sems += nsems;
558
559 sem_unlock(sma, -1);
560 rcu_read_unlock();
561
562 return sma->sem_perm.id;
563}
564
565
566
567
568
569static inline int sem_more_checks(struct kern_ipc_perm *ipcp,
570 struct ipc_params *params)
571{
572 struct sem_array *sma;
573
574 sma = container_of(ipcp, struct sem_array, sem_perm);
575 if (params->u.nsems > sma->sem_nsems)
576 return -EINVAL;
577
578 return 0;
579}
580
581long ksys_semget(key_t key, int nsems, int semflg)
582{
583 struct ipc_namespace *ns;
584 static const struct ipc_ops sem_ops = {
585 .getnew = newary,
586 .associate = security_sem_associate,
587 .more_checks = sem_more_checks,
588 };
589 struct ipc_params sem_params;
590
591 ns = current->nsproxy->ipc_ns;
592
593 if (nsems < 0 || nsems > ns->sc_semmsl)
594 return -EINVAL;
595
596 sem_params.key = key;
597 sem_params.flg = semflg;
598 sem_params.u.nsems = nsems;
599
600 return ipcget(ns, &sem_ids(ns), &sem_ops, &sem_params);
601}
602
603SYSCALL_DEFINE3(semget, key_t, key, int, nsems, int, semflg)
604{
605 return ksys_semget(key, nsems, semflg);
606}
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625static int perform_atomic_semop_slow(struct sem_array *sma, struct sem_queue *q)
626{
627 int result, sem_op, nsops;
628 struct pid *pid;
629 struct sembuf *sop;
630 struct sem *curr;
631 struct sembuf *sops;
632 struct sem_undo *un;
633
634 sops = q->sops;
635 nsops = q->nsops;
636 un = q->undo;
637
638 for (sop = sops; sop < sops + nsops; sop++) {
639 int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
640 curr = &sma->sems[idx];
641 sem_op = sop->sem_op;
642 result = curr->semval;
643
644 if (!sem_op && result)
645 goto would_block;
646
647 result += sem_op;
648 if (result < 0)
649 goto would_block;
650 if (result > SEMVMX)
651 goto out_of_range;
652
653 if (sop->sem_flg & SEM_UNDO) {
654 int undo = un->semadj[sop->sem_num] - sem_op;
655
656 if (undo < (-SEMAEM - 1) || undo > SEMAEM)
657 goto out_of_range;
658 un->semadj[sop->sem_num] = undo;
659 }
660
661 curr->semval = result;
662 }
663
664 sop--;
665 pid = q->pid;
666 while (sop >= sops) {
667 ipc_update_pid(&sma->sems[sop->sem_num].sempid, pid);
668 sop--;
669 }
670
671 return 0;
672
673out_of_range:
674 result = -ERANGE;
675 goto undo;
676
677would_block:
678 q->blocking = sop;
679
680 if (sop->sem_flg & IPC_NOWAIT)
681 result = -EAGAIN;
682 else
683 result = 1;
684
685undo:
686 sop--;
687 while (sop >= sops) {
688 sem_op = sop->sem_op;
689 sma->sems[sop->sem_num].semval -= sem_op;
690 if (sop->sem_flg & SEM_UNDO)
691 un->semadj[sop->sem_num] += sem_op;
692 sop--;
693 }
694
695 return result;
696}
697
698static int perform_atomic_semop(struct sem_array *sma, struct sem_queue *q)
699{
700 int result, sem_op, nsops;
701 struct sembuf *sop;
702 struct sem *curr;
703 struct sembuf *sops;
704 struct sem_undo *un;
705
706 sops = q->sops;
707 nsops = q->nsops;
708 un = q->undo;
709
710 if (unlikely(q->dupsop))
711 return perform_atomic_semop_slow(sma, q);
712
713
714
715
716
717
718
719 for (sop = sops; sop < sops + nsops; sop++) {
720 int idx = array_index_nospec(sop->sem_num, sma->sem_nsems);
721
722 curr = &sma->sems[idx];
723 sem_op = sop->sem_op;
724 result = curr->semval;
725
726 if (!sem_op && result)
727 goto would_block;
728
729 result += sem_op;
730 if (result < 0)
731 goto would_block;
732
733 if (result > SEMVMX)
734 return -ERANGE;
735
736 if (sop->sem_flg & SEM_UNDO) {
737 int undo = un->semadj[sop->sem_num] - sem_op;
738
739
740 if (undo < (-SEMAEM - 1) || undo > SEMAEM)
741 return -ERANGE;
742 }
743 }
744
745 for (sop = sops; sop < sops + nsops; sop++) {
746 curr = &sma->sems[sop->sem_num];
747 sem_op = sop->sem_op;
748 result = curr->semval;
749
750 if (sop->sem_flg & SEM_UNDO) {
751 int undo = un->semadj[sop->sem_num] - sem_op;
752
753 un->semadj[sop->sem_num] = undo;
754 }
755 curr->semval += sem_op;
756 ipc_update_pid(&curr->sempid, q->pid);
757 }
758
759 return 0;
760
761would_block:
762 q->blocking = sop;
763 return sop->sem_flg & IPC_NOWAIT ? -EAGAIN : 1;
764}
765
766static inline void wake_up_sem_queue_prepare(struct sem_queue *q, int error,
767 struct wake_q_head *wake_q)
768{
769 wake_q_add(wake_q, q->sleeper);
770
771
772
773
774
775
776
777 WRITE_ONCE(q->status, error);
778}
779
780static void unlink_queue(struct sem_array *sma, struct sem_queue *q)
781{
782 list_del(&q->list);
783 if (q->nsops > 1)
784 sma->complex_count--;
785}
786
787
788
789
790
791
792
793
794
795
796
797static inline int check_restart(struct sem_array *sma, struct sem_queue *q)
798{
799
800 if (!list_empty(&sma->pending_alter))
801 return 1;
802
803
804 if (q->nsops > 1)
805 return 1;
806
807
808
809
810
811
812
813
814
815
816
817
818 return 0;
819}
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835static int wake_const_ops(struct sem_array *sma, int semnum,
836 struct wake_q_head *wake_q)
837{
838 struct sem_queue *q, *tmp;
839 struct list_head *pending_list;
840 int semop_completed = 0;
841
842 if (semnum == -1)
843 pending_list = &sma->pending_const;
844 else
845 pending_list = &sma->sems[semnum].pending_const;
846
847 list_for_each_entry_safe(q, tmp, pending_list, list) {
848 int error = perform_atomic_semop(sma, q);
849
850 if (error > 0)
851 continue;
852
853 unlink_queue(sma, q);
854
855 wake_up_sem_queue_prepare(q, error, wake_q);
856 if (error == 0)
857 semop_completed = 1;
858 }
859
860 return semop_completed;
861}
862
863
864
865
866
867
868
869
870
871
872
873
874static int do_smart_wakeup_zero(struct sem_array *sma, struct sembuf *sops,
875 int nsops, struct wake_q_head *wake_q)
876{
877 int i;
878 int semop_completed = 0;
879 int got_zero = 0;
880
881
882 if (sops) {
883 for (i = 0; i < nsops; i++) {
884 int num = sops[i].sem_num;
885
886 if (sma->sems[num].semval == 0) {
887 got_zero = 1;
888 semop_completed |= wake_const_ops(sma, num, wake_q);
889 }
890 }
891 } else {
892
893
894
895
896 for (i = 0; i < sma->sem_nsems; i++) {
897 if (sma->sems[i].semval == 0) {
898 got_zero = 1;
899 semop_completed |= wake_const_ops(sma, i, wake_q);
900 }
901 }
902 }
903
904
905
906
907 if (got_zero)
908 semop_completed |= wake_const_ops(sma, -1, wake_q);
909
910 return semop_completed;
911}
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930static int update_queue(struct sem_array *sma, int semnum, struct wake_q_head *wake_q)
931{
932 struct sem_queue *q, *tmp;
933 struct list_head *pending_list;
934 int semop_completed = 0;
935
936 if (semnum == -1)
937 pending_list = &sma->pending_alter;
938 else
939 pending_list = &sma->sems[semnum].pending_alter;
940
941again:
942 list_for_each_entry_safe(q, tmp, pending_list, list) {
943 int error, restart;
944
945
946
947
948
949
950
951
952 if (semnum != -1 && sma->sems[semnum].semval == 0)
953 break;
954
955 error = perform_atomic_semop(sma, q);
956
957
958 if (error > 0)
959 continue;
960
961 unlink_queue(sma, q);
962
963 if (error) {
964 restart = 0;
965 } else {
966 semop_completed = 1;
967 do_smart_wakeup_zero(sma, q->sops, q->nsops, wake_q);
968 restart = check_restart(sma, q);
969 }
970
971 wake_up_sem_queue_prepare(q, error, wake_q);
972 if (restart)
973 goto again;
974 }
975 return semop_completed;
976}
977
978
979
980
981
982
983
984
985
986static void set_semotime(struct sem_array *sma, struct sembuf *sops)
987{
988 if (sops == NULL) {
989 sma->sems[0].sem_otime = ktime_get_real_seconds();
990 } else {
991 sma->sems[sops[0].sem_num].sem_otime =
992 ktime_get_real_seconds();
993 }
994}
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010static void do_smart_update(struct sem_array *sma, struct sembuf *sops, int nsops,
1011 int otime, struct wake_q_head *wake_q)
1012{
1013 int i;
1014
1015 otime |= do_smart_wakeup_zero(sma, sops, nsops, wake_q);
1016
1017 if (!list_empty(&sma->pending_alter)) {
1018
1019 otime |= update_queue(sma, -1, wake_q);
1020 } else {
1021 if (!sops) {
1022
1023
1024
1025
1026 for (i = 0; i < sma->sem_nsems; i++)
1027 otime |= update_queue(sma, i, wake_q);
1028 } else {
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038 for (i = 0; i < nsops; i++) {
1039 if (sops[i].sem_op > 0) {
1040 otime |= update_queue(sma,
1041 sops[i].sem_num, wake_q);
1042 }
1043 }
1044 }
1045 }
1046 if (otime)
1047 set_semotime(sma, sops);
1048}
1049
1050
1051
1052
1053static int check_qop(struct sem_array *sma, int semnum, struct sem_queue *q,
1054 bool count_zero)
1055{
1056 struct sembuf *sop = q->blocking;
1057
1058
1059
1060
1061
1062
1063
1064
1065 pr_info_once("semctl(GETNCNT/GETZCNT) is since 3.16 Single Unix Specification compliant.\n"
1066 "The task %s (%d) triggered the difference, watch for misbehavior.\n",
1067 current->comm, task_pid_nr(current));
1068
1069 if (sop->sem_num != semnum)
1070 return 0;
1071
1072 if (count_zero && sop->sem_op == 0)
1073 return 1;
1074 if (!count_zero && sop->sem_op < 0)
1075 return 1;
1076
1077 return 0;
1078}
1079
1080
1081
1082
1083
1084
1085
1086
1087static int count_semcnt(struct sem_array *sma, ushort semnum,
1088 bool count_zero)
1089{
1090 struct list_head *l;
1091 struct sem_queue *q;
1092 int semcnt;
1093
1094 semcnt = 0;
1095
1096 if (count_zero)
1097 l = &sma->sems[semnum].pending_const;
1098 else
1099 l = &sma->sems[semnum].pending_alter;
1100
1101 list_for_each_entry(q, l, list) {
1102
1103
1104
1105 semcnt++;
1106 }
1107
1108
1109 list_for_each_entry(q, &sma->pending_alter, list) {
1110 semcnt += check_qop(sma, semnum, q, count_zero);
1111 }
1112 if (count_zero) {
1113 list_for_each_entry(q, &sma->pending_const, list) {
1114 semcnt += check_qop(sma, semnum, q, count_zero);
1115 }
1116 }
1117 return semcnt;
1118}
1119
1120
1121
1122
1123
1124static void freeary(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp)
1125{
1126 struct sem_undo *un, *tu;
1127 struct sem_queue *q, *tq;
1128 struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm);
1129 int i;
1130 DEFINE_WAKE_Q(wake_q);
1131
1132
1133 ipc_assert_locked_object(&sma->sem_perm);
1134 list_for_each_entry_safe(un, tu, &sma->list_id, list_id) {
1135 list_del(&un->list_id);
1136 spin_lock(&un->ulp->lock);
1137 un->semid = -1;
1138 list_del_rcu(&un->list_proc);
1139 spin_unlock(&un->ulp->lock);
1140 kfree_rcu(un, rcu);
1141 }
1142
1143
1144 list_for_each_entry_safe(q, tq, &sma->pending_const, list) {
1145 unlink_queue(sma, q);
1146 wake_up_sem_queue_prepare(q, -EIDRM, &wake_q);
1147 }
1148
1149 list_for_each_entry_safe(q, tq, &sma->pending_alter, list) {
1150 unlink_queue(sma, q);
1151 wake_up_sem_queue_prepare(q, -EIDRM, &wake_q);
1152 }
1153 for (i = 0; i < sma->sem_nsems; i++) {
1154 struct sem *sem = &sma->sems[i];
1155 list_for_each_entry_safe(q, tq, &sem->pending_const, list) {
1156 unlink_queue(sma, q);
1157 wake_up_sem_queue_prepare(q, -EIDRM, &wake_q);
1158 }
1159 list_for_each_entry_safe(q, tq, &sem->pending_alter, list) {
1160 unlink_queue(sma, q);
1161 wake_up_sem_queue_prepare(q, -EIDRM, &wake_q);
1162 }
1163 ipc_update_pid(&sem->sempid, NULL);
1164 }
1165
1166
1167 sem_rmid(ns, sma);
1168 sem_unlock(sma, -1);
1169 rcu_read_unlock();
1170
1171 wake_up_q(&wake_q);
1172 ns->used_sems -= sma->sem_nsems;
1173 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1174}
1175
1176static unsigned long copy_semid_to_user(void __user *buf, struct semid64_ds *in, int version)
1177{
1178 switch (version) {
1179 case IPC_64:
1180 return copy_to_user(buf, in, sizeof(*in));
1181 case IPC_OLD:
1182 {
1183 struct semid_ds out;
1184
1185 memset(&out, 0, sizeof(out));
1186
1187 ipc64_perm_to_ipc_perm(&in->sem_perm, &out.sem_perm);
1188
1189 out.sem_otime = in->sem_otime;
1190 out.sem_ctime = in->sem_ctime;
1191 out.sem_nsems = in->sem_nsems;
1192
1193 return copy_to_user(buf, &out, sizeof(out));
1194 }
1195 default:
1196 return -EINVAL;
1197 }
1198}
1199
1200static time64_t get_semotime(struct sem_array *sma)
1201{
1202 int i;
1203 time64_t res;
1204
1205 res = sma->sems[0].sem_otime;
1206 for (i = 1; i < sma->sem_nsems; i++) {
1207 time64_t to = sma->sems[i].sem_otime;
1208
1209 if (to > res)
1210 res = to;
1211 }
1212 return res;
1213}
1214
1215static int semctl_stat(struct ipc_namespace *ns, int semid,
1216 int cmd, struct semid64_ds *semid64)
1217{
1218 struct sem_array *sma;
1219 time64_t semotime;
1220 int err;
1221
1222 memset(semid64, 0, sizeof(*semid64));
1223
1224 rcu_read_lock();
1225 if (cmd == SEM_STAT || cmd == SEM_STAT_ANY) {
1226 sma = sem_obtain_object(ns, semid);
1227 if (IS_ERR(sma)) {
1228 err = PTR_ERR(sma);
1229 goto out_unlock;
1230 }
1231 } else {
1232 sma = sem_obtain_object_check(ns, semid);
1233 if (IS_ERR(sma)) {
1234 err = PTR_ERR(sma);
1235 goto out_unlock;
1236 }
1237 }
1238
1239
1240 if (cmd == SEM_STAT_ANY)
1241 audit_ipc_obj(&sma->sem_perm);
1242 else {
1243 err = -EACCES;
1244 if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
1245 goto out_unlock;
1246 }
1247
1248 err = security_sem_semctl(&sma->sem_perm, cmd);
1249 if (err)
1250 goto out_unlock;
1251
1252 ipc_lock_object(&sma->sem_perm);
1253
1254 if (!ipc_valid_object(&sma->sem_perm)) {
1255 ipc_unlock_object(&sma->sem_perm);
1256 err = -EIDRM;
1257 goto out_unlock;
1258 }
1259
1260 kernel_to_ipc64_perm(&sma->sem_perm, &semid64->sem_perm);
1261 semotime = get_semotime(sma);
1262 semid64->sem_otime = semotime;
1263 semid64->sem_ctime = sma->sem_ctime;
1264#ifndef CONFIG_64BIT
1265 semid64->sem_otime_high = semotime >> 32;
1266 semid64->sem_ctime_high = sma->sem_ctime >> 32;
1267#endif
1268 semid64->sem_nsems = sma->sem_nsems;
1269
1270 if (cmd == IPC_STAT) {
1271
1272
1273
1274
1275 err = 0;
1276 } else {
1277
1278
1279
1280
1281 err = sma->sem_perm.id;
1282 }
1283 ipc_unlock_object(&sma->sem_perm);
1284out_unlock:
1285 rcu_read_unlock();
1286 return err;
1287}
1288
1289static int semctl_info(struct ipc_namespace *ns, int semid,
1290 int cmd, void __user *p)
1291{
1292 struct seminfo seminfo;
1293 int max_idx;
1294 int err;
1295
1296 err = security_sem_semctl(NULL, cmd);
1297 if (err)
1298 return err;
1299
1300 memset(&seminfo, 0, sizeof(seminfo));
1301 seminfo.semmni = ns->sc_semmni;
1302 seminfo.semmns = ns->sc_semmns;
1303 seminfo.semmsl = ns->sc_semmsl;
1304 seminfo.semopm = ns->sc_semopm;
1305 seminfo.semvmx = SEMVMX;
1306 seminfo.semmnu = SEMMNU;
1307 seminfo.semmap = SEMMAP;
1308 seminfo.semume = SEMUME;
1309 down_read(&sem_ids(ns).rwsem);
1310 if (cmd == SEM_INFO) {
1311 seminfo.semusz = sem_ids(ns).in_use;
1312 seminfo.semaem = ns->used_sems;
1313 } else {
1314 seminfo.semusz = SEMUSZ;
1315 seminfo.semaem = SEMAEM;
1316 }
1317 max_idx = ipc_get_maxidx(&sem_ids(ns));
1318 up_read(&sem_ids(ns).rwsem);
1319 if (copy_to_user(p, &seminfo, sizeof(struct seminfo)))
1320 return -EFAULT;
1321 return (max_idx < 0) ? 0 : max_idx;
1322}
1323
1324static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
1325 int val)
1326{
1327 struct sem_undo *un;
1328 struct sem_array *sma;
1329 struct sem *curr;
1330 int err;
1331 DEFINE_WAKE_Q(wake_q);
1332
1333 if (val > SEMVMX || val < 0)
1334 return -ERANGE;
1335
1336 rcu_read_lock();
1337 sma = sem_obtain_object_check(ns, semid);
1338 if (IS_ERR(sma)) {
1339 rcu_read_unlock();
1340 return PTR_ERR(sma);
1341 }
1342
1343 if (semnum < 0 || semnum >= sma->sem_nsems) {
1344 rcu_read_unlock();
1345 return -EINVAL;
1346 }
1347
1348
1349 if (ipcperms(ns, &sma->sem_perm, S_IWUGO)) {
1350 rcu_read_unlock();
1351 return -EACCES;
1352 }
1353
1354 err = security_sem_semctl(&sma->sem_perm, SETVAL);
1355 if (err) {
1356 rcu_read_unlock();
1357 return -EACCES;
1358 }
1359
1360 sem_lock(sma, NULL, -1);
1361
1362 if (!ipc_valid_object(&sma->sem_perm)) {
1363 sem_unlock(sma, -1);
1364 rcu_read_unlock();
1365 return -EIDRM;
1366 }
1367
1368 semnum = array_index_nospec(semnum, sma->sem_nsems);
1369 curr = &sma->sems[semnum];
1370
1371 ipc_assert_locked_object(&sma->sem_perm);
1372 list_for_each_entry(un, &sma->list_id, list_id)
1373 un->semadj[semnum] = 0;
1374
1375 curr->semval = val;
1376 ipc_update_pid(&curr->sempid, task_tgid(current));
1377 sma->sem_ctime = ktime_get_real_seconds();
1378
1379 do_smart_update(sma, NULL, 0, 0, &wake_q);
1380 sem_unlock(sma, -1);
1381 rcu_read_unlock();
1382 wake_up_q(&wake_q);
1383 return 0;
1384}
1385
1386static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
1387 int cmd, void __user *p)
1388{
1389 struct sem_array *sma;
1390 struct sem *curr;
1391 int err, nsems;
1392 ushort fast_sem_io[SEMMSL_FAST];
1393 ushort *sem_io = fast_sem_io;
1394 DEFINE_WAKE_Q(wake_q);
1395
1396 rcu_read_lock();
1397 sma = sem_obtain_object_check(ns, semid);
1398 if (IS_ERR(sma)) {
1399 rcu_read_unlock();
1400 return PTR_ERR(sma);
1401 }
1402
1403 nsems = sma->sem_nsems;
1404
1405 err = -EACCES;
1406 if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO))
1407 goto out_rcu_wakeup;
1408
1409 err = security_sem_semctl(&sma->sem_perm, cmd);
1410 if (err)
1411 goto out_rcu_wakeup;
1412
1413 err = -EACCES;
1414 switch (cmd) {
1415 case GETALL:
1416 {
1417 ushort __user *array = p;
1418 int i;
1419
1420 sem_lock(sma, NULL, -1);
1421 if (!ipc_valid_object(&sma->sem_perm)) {
1422 err = -EIDRM;
1423 goto out_unlock;
1424 }
1425 if (nsems > SEMMSL_FAST) {
1426 if (!ipc_rcu_getref(&sma->sem_perm)) {
1427 err = -EIDRM;
1428 goto out_unlock;
1429 }
1430 sem_unlock(sma, -1);
1431 rcu_read_unlock();
1432 sem_io = kvmalloc_array(nsems, sizeof(ushort),
1433 GFP_KERNEL);
1434 if (sem_io == NULL) {
1435 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1436 return -ENOMEM;
1437 }
1438
1439 rcu_read_lock();
1440 sem_lock_and_putref(sma);
1441 if (!ipc_valid_object(&sma->sem_perm)) {
1442 err = -EIDRM;
1443 goto out_unlock;
1444 }
1445 }
1446 for (i = 0; i < sma->sem_nsems; i++)
1447 sem_io[i] = sma->sems[i].semval;
1448 sem_unlock(sma, -1);
1449 rcu_read_unlock();
1450 err = 0;
1451 if (copy_to_user(array, sem_io, nsems*sizeof(ushort)))
1452 err = -EFAULT;
1453 goto out_free;
1454 }
1455 case SETALL:
1456 {
1457 int i;
1458 struct sem_undo *un;
1459
1460 if (!ipc_rcu_getref(&sma->sem_perm)) {
1461 err = -EIDRM;
1462 goto out_rcu_wakeup;
1463 }
1464 rcu_read_unlock();
1465
1466 if (nsems > SEMMSL_FAST) {
1467 sem_io = kvmalloc_array(nsems, sizeof(ushort),
1468 GFP_KERNEL);
1469 if (sem_io == NULL) {
1470 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1471 return -ENOMEM;
1472 }
1473 }
1474
1475 if (copy_from_user(sem_io, p, nsems*sizeof(ushort))) {
1476 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1477 err = -EFAULT;
1478 goto out_free;
1479 }
1480
1481 for (i = 0; i < nsems; i++) {
1482 if (sem_io[i] > SEMVMX) {
1483 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1484 err = -ERANGE;
1485 goto out_free;
1486 }
1487 }
1488 rcu_read_lock();
1489 sem_lock_and_putref(sma);
1490 if (!ipc_valid_object(&sma->sem_perm)) {
1491 err = -EIDRM;
1492 goto out_unlock;
1493 }
1494
1495 for (i = 0; i < nsems; i++) {
1496 sma->sems[i].semval = sem_io[i];
1497 ipc_update_pid(&sma->sems[i].sempid, task_tgid(current));
1498 }
1499
1500 ipc_assert_locked_object(&sma->sem_perm);
1501 list_for_each_entry(un, &sma->list_id, list_id) {
1502 for (i = 0; i < nsems; i++)
1503 un->semadj[i] = 0;
1504 }
1505 sma->sem_ctime = ktime_get_real_seconds();
1506
1507 do_smart_update(sma, NULL, 0, 0, &wake_q);
1508 err = 0;
1509 goto out_unlock;
1510 }
1511
1512 }
1513 err = -EINVAL;
1514 if (semnum < 0 || semnum >= nsems)
1515 goto out_rcu_wakeup;
1516
1517 sem_lock(sma, NULL, -1);
1518 if (!ipc_valid_object(&sma->sem_perm)) {
1519 err = -EIDRM;
1520 goto out_unlock;
1521 }
1522
1523 semnum = array_index_nospec(semnum, nsems);
1524 curr = &sma->sems[semnum];
1525
1526 switch (cmd) {
1527 case GETVAL:
1528 err = curr->semval;
1529 goto out_unlock;
1530 case GETPID:
1531 err = pid_vnr(curr->sempid);
1532 goto out_unlock;
1533 case GETNCNT:
1534 err = count_semcnt(sma, semnum, 0);
1535 goto out_unlock;
1536 case GETZCNT:
1537 err = count_semcnt(sma, semnum, 1);
1538 goto out_unlock;
1539 }
1540
1541out_unlock:
1542 sem_unlock(sma, -1);
1543out_rcu_wakeup:
1544 rcu_read_unlock();
1545 wake_up_q(&wake_q);
1546out_free:
1547 if (sem_io != fast_sem_io)
1548 kvfree(sem_io);
1549 return err;
1550}
1551
1552static inline unsigned long
1553copy_semid_from_user(struct semid64_ds *out, void __user *buf, int version)
1554{
1555 switch (version) {
1556 case IPC_64:
1557 if (copy_from_user(out, buf, sizeof(*out)))
1558 return -EFAULT;
1559 return 0;
1560 case IPC_OLD:
1561 {
1562 struct semid_ds tbuf_old;
1563
1564 if (copy_from_user(&tbuf_old, buf, sizeof(tbuf_old)))
1565 return -EFAULT;
1566
1567 out->sem_perm.uid = tbuf_old.sem_perm.uid;
1568 out->sem_perm.gid = tbuf_old.sem_perm.gid;
1569 out->sem_perm.mode = tbuf_old.sem_perm.mode;
1570
1571 return 0;
1572 }
1573 default:
1574 return -EINVAL;
1575 }
1576}
1577
1578
1579
1580
1581
1582
1583static int semctl_down(struct ipc_namespace *ns, int semid,
1584 int cmd, struct semid64_ds *semid64)
1585{
1586 struct sem_array *sma;
1587 int err;
1588 struct kern_ipc_perm *ipcp;
1589
1590 down_write(&sem_ids(ns).rwsem);
1591 rcu_read_lock();
1592
1593 ipcp = ipcctl_obtain_check(ns, &sem_ids(ns), semid, cmd,
1594 &semid64->sem_perm, 0);
1595 if (IS_ERR(ipcp)) {
1596 err = PTR_ERR(ipcp);
1597 goto out_unlock1;
1598 }
1599
1600 sma = container_of(ipcp, struct sem_array, sem_perm);
1601
1602 err = security_sem_semctl(&sma->sem_perm, cmd);
1603 if (err)
1604 goto out_unlock1;
1605
1606 switch (cmd) {
1607 case IPC_RMID:
1608 sem_lock(sma, NULL, -1);
1609
1610 freeary(ns, ipcp);
1611 goto out_up;
1612 case IPC_SET:
1613 sem_lock(sma, NULL, -1);
1614 err = ipc_update_perm(&semid64->sem_perm, ipcp);
1615 if (err)
1616 goto out_unlock0;
1617 sma->sem_ctime = ktime_get_real_seconds();
1618 break;
1619 default:
1620 err = -EINVAL;
1621 goto out_unlock1;
1622 }
1623
1624out_unlock0:
1625 sem_unlock(sma, -1);
1626out_unlock1:
1627 rcu_read_unlock();
1628out_up:
1629 up_write(&sem_ids(ns).rwsem);
1630 return err;
1631}
1632
1633static long ksys_semctl(int semid, int semnum, int cmd, unsigned long arg, int version)
1634{
1635 struct ipc_namespace *ns;
1636 void __user *p = (void __user *)arg;
1637 struct semid64_ds semid64;
1638 int err;
1639
1640 if (semid < 0)
1641 return -EINVAL;
1642
1643 ns = current->nsproxy->ipc_ns;
1644
1645 switch (cmd) {
1646 case IPC_INFO:
1647 case SEM_INFO:
1648 return semctl_info(ns, semid, cmd, p);
1649 case IPC_STAT:
1650 case SEM_STAT:
1651 case SEM_STAT_ANY:
1652 err = semctl_stat(ns, semid, cmd, &semid64);
1653 if (err < 0)
1654 return err;
1655 if (copy_semid_to_user(p, &semid64, version))
1656 err = -EFAULT;
1657 return err;
1658 case GETALL:
1659 case GETVAL:
1660 case GETPID:
1661 case GETNCNT:
1662 case GETZCNT:
1663 case SETALL:
1664 return semctl_main(ns, semid, semnum, cmd, p);
1665 case SETVAL: {
1666 int val;
1667#if defined(CONFIG_64BIT) && defined(__BIG_ENDIAN)
1668
1669 val = arg >> 32;
1670#else
1671
1672 val = arg;
1673#endif
1674 return semctl_setval(ns, semid, semnum, val);
1675 }
1676 case IPC_SET:
1677 if (copy_semid_from_user(&semid64, p, version))
1678 return -EFAULT;
1679
1680 case IPC_RMID:
1681 return semctl_down(ns, semid, cmd, &semid64);
1682 default:
1683 return -EINVAL;
1684 }
1685}
1686
1687SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
1688{
1689 return ksys_semctl(semid, semnum, cmd, arg, IPC_64);
1690}
1691
1692#ifdef CONFIG_ARCH_WANT_IPC_PARSE_VERSION
1693long ksys_old_semctl(int semid, int semnum, int cmd, unsigned long arg)
1694{
1695 int version = ipc_parse_version(&cmd);
1696
1697 return ksys_semctl(semid, semnum, cmd, arg, version);
1698}
1699
1700SYSCALL_DEFINE4(old_semctl, int, semid, int, semnum, int, cmd, unsigned long, arg)
1701{
1702 return ksys_old_semctl(semid, semnum, cmd, arg);
1703}
1704#endif
1705
1706#ifdef CONFIG_COMPAT
1707
1708struct compat_semid_ds {
1709 struct compat_ipc_perm sem_perm;
1710 old_time32_t sem_otime;
1711 old_time32_t sem_ctime;
1712 compat_uptr_t sem_base;
1713 compat_uptr_t sem_pending;
1714 compat_uptr_t sem_pending_last;
1715 compat_uptr_t undo;
1716 unsigned short sem_nsems;
1717};
1718
1719static int copy_compat_semid_from_user(struct semid64_ds *out, void __user *buf,
1720 int version)
1721{
1722 memset(out, 0, sizeof(*out));
1723 if (version == IPC_64) {
1724 struct compat_semid64_ds __user *p = buf;
1725 return get_compat_ipc64_perm(&out->sem_perm, &p->sem_perm);
1726 } else {
1727 struct compat_semid_ds __user *p = buf;
1728 return get_compat_ipc_perm(&out->sem_perm, &p->sem_perm);
1729 }
1730}
1731
1732static int copy_compat_semid_to_user(void __user *buf, struct semid64_ds *in,
1733 int version)
1734{
1735 if (version == IPC_64) {
1736 struct compat_semid64_ds v;
1737 memset(&v, 0, sizeof(v));
1738 to_compat_ipc64_perm(&v.sem_perm, &in->sem_perm);
1739 v.sem_otime = lower_32_bits(in->sem_otime);
1740 v.sem_otime_high = upper_32_bits(in->sem_otime);
1741 v.sem_ctime = lower_32_bits(in->sem_ctime);
1742 v.sem_ctime_high = upper_32_bits(in->sem_ctime);
1743 v.sem_nsems = in->sem_nsems;
1744 return copy_to_user(buf, &v, sizeof(v));
1745 } else {
1746 struct compat_semid_ds v;
1747 memset(&v, 0, sizeof(v));
1748 to_compat_ipc_perm(&v.sem_perm, &in->sem_perm);
1749 v.sem_otime = in->sem_otime;
1750 v.sem_ctime = in->sem_ctime;
1751 v.sem_nsems = in->sem_nsems;
1752 return copy_to_user(buf, &v, sizeof(v));
1753 }
1754}
1755
1756static long compat_ksys_semctl(int semid, int semnum, int cmd, int arg, int version)
1757{
1758 void __user *p = compat_ptr(arg);
1759 struct ipc_namespace *ns;
1760 struct semid64_ds semid64;
1761 int err;
1762
1763 ns = current->nsproxy->ipc_ns;
1764
1765 if (semid < 0)
1766 return -EINVAL;
1767
1768 switch (cmd & (~IPC_64)) {
1769 case IPC_INFO:
1770 case SEM_INFO:
1771 return semctl_info(ns, semid, cmd, p);
1772 case IPC_STAT:
1773 case SEM_STAT:
1774 case SEM_STAT_ANY:
1775 err = semctl_stat(ns, semid, cmd, &semid64);
1776 if (err < 0)
1777 return err;
1778 if (copy_compat_semid_to_user(p, &semid64, version))
1779 err = -EFAULT;
1780 return err;
1781 case GETVAL:
1782 case GETPID:
1783 case GETNCNT:
1784 case GETZCNT:
1785 case GETALL:
1786 case SETALL:
1787 return semctl_main(ns, semid, semnum, cmd, p);
1788 case SETVAL:
1789 return semctl_setval(ns, semid, semnum, arg);
1790 case IPC_SET:
1791 if (copy_compat_semid_from_user(&semid64, p, version))
1792 return -EFAULT;
1793
1794 case IPC_RMID:
1795 return semctl_down(ns, semid, cmd, &semid64);
1796 default:
1797 return -EINVAL;
1798 }
1799}
1800
1801COMPAT_SYSCALL_DEFINE4(semctl, int, semid, int, semnum, int, cmd, int, arg)
1802{
1803 return compat_ksys_semctl(semid, semnum, cmd, arg, IPC_64);
1804}
1805
1806#ifdef CONFIG_ARCH_WANT_COMPAT_IPC_PARSE_VERSION
1807long compat_ksys_old_semctl(int semid, int semnum, int cmd, int arg)
1808{
1809 int version = compat_ipc_parse_version(&cmd);
1810
1811 return compat_ksys_semctl(semid, semnum, cmd, arg, version);
1812}
1813
1814COMPAT_SYSCALL_DEFINE4(old_semctl, int, semid, int, semnum, int, cmd, int, arg)
1815{
1816 return compat_ksys_old_semctl(semid, semnum, cmd, arg);
1817}
1818#endif
1819#endif
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832static inline int get_undo_list(struct sem_undo_list **undo_listp)
1833{
1834 struct sem_undo_list *undo_list;
1835
1836 undo_list = current->sysvsem.undo_list;
1837 if (!undo_list) {
1838 undo_list = kzalloc(sizeof(*undo_list), GFP_KERNEL);
1839 if (undo_list == NULL)
1840 return -ENOMEM;
1841 spin_lock_init(&undo_list->lock);
1842 refcount_set(&undo_list->refcnt, 1);
1843 INIT_LIST_HEAD(&undo_list->list_proc);
1844
1845 current->sysvsem.undo_list = undo_list;
1846 }
1847 *undo_listp = undo_list;
1848 return 0;
1849}
1850
1851static struct sem_undo *__lookup_undo(struct sem_undo_list *ulp, int semid)
1852{
1853 struct sem_undo *un;
1854
1855 list_for_each_entry_rcu(un, &ulp->list_proc, list_proc) {
1856 if (un->semid == semid)
1857 return un;
1858 }
1859 return NULL;
1860}
1861
1862static struct sem_undo *lookup_undo(struct sem_undo_list *ulp, int semid)
1863{
1864 struct sem_undo *un;
1865
1866 assert_spin_locked(&ulp->lock);
1867
1868 un = __lookup_undo(ulp, semid);
1869 if (un) {
1870 list_del_rcu(&un->list_proc);
1871 list_add_rcu(&un->list_proc, &ulp->list_proc);
1872 }
1873 return un;
1874}
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887static struct sem_undo *find_alloc_undo(struct ipc_namespace *ns, int semid)
1888{
1889 struct sem_array *sma;
1890 struct sem_undo_list *ulp;
1891 struct sem_undo *un, *new;
1892 int nsems, error;
1893
1894 error = get_undo_list(&ulp);
1895 if (error)
1896 return ERR_PTR(error);
1897
1898 rcu_read_lock();
1899 spin_lock(&ulp->lock);
1900 un = lookup_undo(ulp, semid);
1901 spin_unlock(&ulp->lock);
1902 if (likely(un != NULL))
1903 goto out;
1904
1905
1906
1907 sma = sem_obtain_object_check(ns, semid);
1908 if (IS_ERR(sma)) {
1909 rcu_read_unlock();
1910 return ERR_CAST(sma);
1911 }
1912
1913 nsems = sma->sem_nsems;
1914 if (!ipc_rcu_getref(&sma->sem_perm)) {
1915 rcu_read_unlock();
1916 un = ERR_PTR(-EIDRM);
1917 goto out;
1918 }
1919 rcu_read_unlock();
1920
1921
1922 new = kzalloc(sizeof(struct sem_undo) + sizeof(short)*nsems, GFP_KERNEL);
1923 if (!new) {
1924 ipc_rcu_putref(&sma->sem_perm, sem_rcu_free);
1925 return ERR_PTR(-ENOMEM);
1926 }
1927
1928
1929 rcu_read_lock();
1930 sem_lock_and_putref(sma);
1931 if (!ipc_valid_object(&sma->sem_perm)) {
1932 sem_unlock(sma, -1);
1933 rcu_read_unlock();
1934 kfree(new);
1935 un = ERR_PTR(-EIDRM);
1936 goto out;
1937 }
1938 spin_lock(&ulp->lock);
1939
1940
1941
1942
1943 un = lookup_undo(ulp, semid);
1944 if (un) {
1945 kfree(new);
1946 goto success;
1947 }
1948
1949 new->semadj = (short *) &new[1];
1950 new->ulp = ulp;
1951 new->semid = semid;
1952 assert_spin_locked(&ulp->lock);
1953 list_add_rcu(&new->list_proc, &ulp->list_proc);
1954 ipc_assert_locked_object(&sma->sem_perm);
1955 list_add(&new->list_id, &sma->list_id);
1956 un = new;
1957
1958success:
1959 spin_unlock(&ulp->lock);
1960 sem_unlock(sma, -1);
1961out:
1962 return un;
1963}
1964
1965static long do_semtimedop(int semid, struct sembuf __user *tsops,
1966 unsigned nsops, const struct timespec64 *timeout)
1967{
1968 int error = -EINVAL;
1969 struct sem_array *sma;
1970 struct sembuf fast_sops[SEMOPM_FAST];
1971 struct sembuf *sops = fast_sops, *sop;
1972 struct sem_undo *un;
1973 int max, locknum;
1974 bool undos = false, alter = false, dupsop = false;
1975 struct sem_queue queue;
1976 unsigned long dup = 0, jiffies_left = 0;
1977 struct ipc_namespace *ns;
1978
1979 ns = current->nsproxy->ipc_ns;
1980
1981 if (nsops < 1 || semid < 0)
1982 return -EINVAL;
1983 if (nsops > ns->sc_semopm)
1984 return -E2BIG;
1985 if (nsops > SEMOPM_FAST) {
1986 sops = kvmalloc_array(nsops, sizeof(*sops), GFP_KERNEL);
1987 if (sops == NULL)
1988 return -ENOMEM;
1989 }
1990
1991 if (copy_from_user(sops, tsops, nsops * sizeof(*tsops))) {
1992 error = -EFAULT;
1993 goto out_free;
1994 }
1995
1996 if (timeout) {
1997 if (timeout->tv_sec < 0 || timeout->tv_nsec < 0 ||
1998 timeout->tv_nsec >= 1000000000L) {
1999 error = -EINVAL;
2000 goto out_free;
2001 }
2002 jiffies_left = timespec64_to_jiffies(timeout);
2003 }
2004
2005 max = 0;
2006 for (sop = sops; sop < sops + nsops; sop++) {
2007 unsigned long mask = 1ULL << ((sop->sem_num) % BITS_PER_LONG);
2008
2009 if (sop->sem_num >= max)
2010 max = sop->sem_num;
2011 if (sop->sem_flg & SEM_UNDO)
2012 undos = true;
2013 if (dup & mask) {
2014
2015
2016
2017
2018
2019
2020 dupsop = true;
2021 }
2022 if (sop->sem_op != 0) {
2023 alter = true;
2024 dup |= mask;
2025 }
2026 }
2027
2028 if (undos) {
2029
2030 un = find_alloc_undo(ns, semid);
2031 if (IS_ERR(un)) {
2032 error = PTR_ERR(un);
2033 goto out_free;
2034 }
2035 } else {
2036 un = NULL;
2037 rcu_read_lock();
2038 }
2039
2040 sma = sem_obtain_object_check(ns, semid);
2041 if (IS_ERR(sma)) {
2042 rcu_read_unlock();
2043 error = PTR_ERR(sma);
2044 goto out_free;
2045 }
2046
2047 error = -EFBIG;
2048 if (max >= sma->sem_nsems) {
2049 rcu_read_unlock();
2050 goto out_free;
2051 }
2052
2053 error = -EACCES;
2054 if (ipcperms(ns, &sma->sem_perm, alter ? S_IWUGO : S_IRUGO)) {
2055 rcu_read_unlock();
2056 goto out_free;
2057 }
2058
2059 error = security_sem_semop(&sma->sem_perm, sops, nsops, alter);
2060 if (error) {
2061 rcu_read_unlock();
2062 goto out_free;
2063 }
2064
2065 error = -EIDRM;
2066 locknum = sem_lock(sma, sops, nsops);
2067
2068
2069
2070
2071
2072
2073
2074
2075 if (!ipc_valid_object(&sma->sem_perm))
2076 goto out_unlock_free;
2077
2078
2079
2080
2081
2082
2083
2084 if (un && un->semid == -1)
2085 goto out_unlock_free;
2086
2087 queue.sops = sops;
2088 queue.nsops = nsops;
2089 queue.undo = un;
2090 queue.pid = task_tgid(current);
2091 queue.alter = alter;
2092 queue.dupsop = dupsop;
2093
2094 error = perform_atomic_semop(sma, &queue);
2095 if (error == 0) {
2096 DEFINE_WAKE_Q(wake_q);
2097
2098
2099
2100
2101
2102 if (alter)
2103 do_smart_update(sma, sops, nsops, 1, &wake_q);
2104 else
2105 set_semotime(sma, sops);
2106
2107 sem_unlock(sma, locknum);
2108 rcu_read_unlock();
2109 wake_up_q(&wake_q);
2110
2111 goto out_free;
2112 }
2113 if (error < 0)
2114 goto out_unlock_free;
2115
2116
2117
2118
2119
2120 if (nsops == 1) {
2121 struct sem *curr;
2122 int idx = array_index_nospec(sops->sem_num, sma->sem_nsems);
2123 curr = &sma->sems[idx];
2124
2125 if (alter) {
2126 if (sma->complex_count) {
2127 list_add_tail(&queue.list,
2128 &sma->pending_alter);
2129 } else {
2130
2131 list_add_tail(&queue.list,
2132 &curr->pending_alter);
2133 }
2134 } else {
2135 list_add_tail(&queue.list, &curr->pending_const);
2136 }
2137 } else {
2138 if (!sma->complex_count)
2139 merge_queues(sma);
2140
2141 if (alter)
2142 list_add_tail(&queue.list, &sma->pending_alter);
2143 else
2144 list_add_tail(&queue.list, &sma->pending_const);
2145
2146 sma->complex_count++;
2147 }
2148
2149 do {
2150 WRITE_ONCE(queue.status, -EINTR);
2151 queue.sleeper = current;
2152
2153 __set_current_state(TASK_INTERRUPTIBLE);
2154 sem_unlock(sma, locknum);
2155 rcu_read_unlock();
2156
2157 if (timeout)
2158 jiffies_left = schedule_timeout(jiffies_left);
2159 else
2160 schedule();
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173 error = READ_ONCE(queue.status);
2174 if (error != -EINTR) {
2175
2176
2177
2178
2179
2180
2181 smp_mb();
2182 goto out_free;
2183 }
2184
2185 rcu_read_lock();
2186 locknum = sem_lock(sma, sops, nsops);
2187
2188 if (!ipc_valid_object(&sma->sem_perm))
2189 goto out_unlock_free;
2190
2191 error = READ_ONCE(queue.status);
2192
2193
2194
2195
2196
2197 if (error != -EINTR)
2198 goto out_unlock_free;
2199
2200
2201
2202
2203 if (timeout && jiffies_left == 0)
2204 error = -EAGAIN;
2205 } while (error == -EINTR && !signal_pending(current));
2206
2207 unlink_queue(sma, &queue);
2208
2209out_unlock_free:
2210 sem_unlock(sma, locknum);
2211 rcu_read_unlock();
2212out_free:
2213 if (sops != fast_sops)
2214 kvfree(sops);
2215 return error;
2216}
2217
2218long ksys_semtimedop(int semid, struct sembuf __user *tsops,
2219 unsigned int nsops, const struct __kernel_timespec __user *timeout)
2220{
2221 if (timeout) {
2222 struct timespec64 ts;
2223 if (get_timespec64(&ts, timeout))
2224 return -EFAULT;
2225 return do_semtimedop(semid, tsops, nsops, &ts);
2226 }
2227 return do_semtimedop(semid, tsops, nsops, NULL);
2228}
2229
2230SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
2231 unsigned int, nsops, const struct __kernel_timespec __user *, timeout)
2232{
2233 return ksys_semtimedop(semid, tsops, nsops, timeout);
2234}
2235
2236#ifdef CONFIG_COMPAT_32BIT_TIME
2237long compat_ksys_semtimedop(int semid, struct sembuf __user *tsems,
2238 unsigned int nsops,
2239 const struct old_timespec32 __user *timeout)
2240{
2241 if (timeout) {
2242 struct timespec64 ts;
2243 if (get_old_timespec32(&ts, timeout))
2244 return -EFAULT;
2245 return do_semtimedop(semid, tsems, nsops, &ts);
2246 }
2247 return do_semtimedop(semid, tsems, nsops, NULL);
2248}
2249
2250SYSCALL_DEFINE4(semtimedop_time32, int, semid, struct sembuf __user *, tsems,
2251 unsigned int, nsops,
2252 const struct old_timespec32 __user *, timeout)
2253{
2254 return compat_ksys_semtimedop(semid, tsems, nsops, timeout);
2255}
2256#endif
2257
2258SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
2259 unsigned, nsops)
2260{
2261 return do_semtimedop(semid, tsops, nsops, NULL);
2262}
2263
2264
2265
2266
2267
2268int copy_semundo(unsigned long clone_flags, struct task_struct *tsk)
2269{
2270 struct sem_undo_list *undo_list;
2271 int error;
2272
2273 if (clone_flags & CLONE_SYSVSEM) {
2274 error = get_undo_list(&undo_list);
2275 if (error)
2276 return error;
2277 refcount_inc(&undo_list->refcnt);
2278 tsk->sysvsem.undo_list = undo_list;
2279 } else
2280 tsk->sysvsem.undo_list = NULL;
2281
2282 return 0;
2283}
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297void exit_sem(struct task_struct *tsk)
2298{
2299 struct sem_undo_list *ulp;
2300
2301 ulp = tsk->sysvsem.undo_list;
2302 if (!ulp)
2303 return;
2304 tsk->sysvsem.undo_list = NULL;
2305
2306 if (!refcount_dec_and_test(&ulp->refcnt))
2307 return;
2308
2309 for (;;) {
2310 struct sem_array *sma;
2311 struct sem_undo *un;
2312 int semid, i;
2313 DEFINE_WAKE_Q(wake_q);
2314
2315 cond_resched();
2316
2317 rcu_read_lock();
2318 un = list_entry_rcu(ulp->list_proc.next,
2319 struct sem_undo, list_proc);
2320 if (&un->list_proc == &ulp->list_proc) {
2321
2322
2323
2324
2325
2326
2327 spin_lock(&ulp->lock);
2328 spin_unlock(&ulp->lock);
2329 rcu_read_unlock();
2330 break;
2331 }
2332 spin_lock(&ulp->lock);
2333 semid = un->semid;
2334 spin_unlock(&ulp->lock);
2335
2336
2337 if (semid == -1) {
2338 rcu_read_unlock();
2339 continue;
2340 }
2341
2342 sma = sem_obtain_object_check(tsk->nsproxy->ipc_ns, semid);
2343
2344 if (IS_ERR(sma)) {
2345 rcu_read_unlock();
2346 continue;
2347 }
2348
2349 sem_lock(sma, NULL, -1);
2350
2351 if (!ipc_valid_object(&sma->sem_perm)) {
2352 sem_unlock(sma, -1);
2353 rcu_read_unlock();
2354 continue;
2355 }
2356 un = __lookup_undo(ulp, semid);
2357 if (un == NULL) {
2358
2359
2360
2361 sem_unlock(sma, -1);
2362 rcu_read_unlock();
2363 continue;
2364 }
2365
2366
2367 ipc_assert_locked_object(&sma->sem_perm);
2368 list_del(&un->list_id);
2369
2370
2371
2372
2373
2374 list_del_rcu(&un->list_proc);
2375
2376
2377 for (i = 0; i < sma->sem_nsems; i++) {
2378 struct sem *semaphore = &sma->sems[i];
2379 if (un->semadj[i]) {
2380 semaphore->semval += un->semadj[i];
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394 if (semaphore->semval < 0)
2395 semaphore->semval = 0;
2396 if (semaphore->semval > SEMVMX)
2397 semaphore->semval = SEMVMX;
2398 ipc_update_pid(&semaphore->sempid, task_tgid(current));
2399 }
2400 }
2401
2402 do_smart_update(sma, NULL, 0, 1, &wake_q);
2403 sem_unlock(sma, -1);
2404 rcu_read_unlock();
2405 wake_up_q(&wake_q);
2406
2407 kfree_rcu(un, rcu);
2408 }
2409 kfree(ulp);
2410}
2411
2412#ifdef CONFIG_PROC_FS
2413static int sysvipc_sem_proc_show(struct seq_file *s, void *it)
2414{
2415 struct user_namespace *user_ns = seq_user_ns(s);
2416 struct kern_ipc_perm *ipcp = it;
2417 struct sem_array *sma = container_of(ipcp, struct sem_array, sem_perm);
2418 time64_t sem_otime;
2419
2420
2421
2422
2423
2424
2425
2426 complexmode_enter(sma);
2427
2428 sem_otime = get_semotime(sma);
2429
2430 seq_printf(s,
2431 "%10d %10d %4o %10u %5u %5u %5u %5u %10llu %10llu\n",
2432 sma->sem_perm.key,
2433 sma->sem_perm.id,
2434 sma->sem_perm.mode,
2435 sma->sem_nsems,
2436 from_kuid_munged(user_ns, sma->sem_perm.uid),
2437 from_kgid_munged(user_ns, sma->sem_perm.gid),
2438 from_kuid_munged(user_ns, sma->sem_perm.cuid),
2439 from_kgid_munged(user_ns, sma->sem_perm.cgid),
2440 sem_otime,
2441 sma->sem_ctime);
2442
2443 complexmode_tryleave(sma);
2444
2445 return 0;
2446}
2447#endif
2448