DragonFlyBSD Kernel Audit
DF-0046 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/sysv_sem.c b/sys/kern/sysv_sem.c
--- a/sys/kern/sysv_sem.c
+++ b/sys/kern/sysv_sem.c
@@ -527,6 +527,10 @@
 		 * modify any semptr content without acquiring its token.
 		 */
 		semptr = &semaptr->ds.sem_base[semnum];
+		if (real_arg.val < 0 || real_arg.val > seminfo.semvmx) {
+			eval = ERANGE;
+			break;
+		}
 		semptr->semval = real_arg.val;
 		semundo_clear(semid, semnum);
 		if (semptr->semzcnt || semptr->semncnt)
@@ -846,6 +850,12 @@
 					break;
 				}
 			} else {
+				if ((int)semptr->semval + sopptr->sem_op >
+				    seminfo.semvmx) {
+					eval = ERANGE;
+					lwkt_relpooltoken(semptr);
+					goto done;
+				}
 				semptr->semval += sopptr->sem_op;
 				if (sopptr->sem_flg & SEM_UNDO)
 					do_undos = 1;
@@ -1136,7 +1146,11 @@
 				else
 					semptr->semval += adjval;
 			} else {
-				semptr->semval += adjval;
+				if ((int)semptr->semval + adjval >
+				    seminfo.semvmx)
+					semptr->semval = seminfo.semvmx;
+				else
+					semptr->semval += adjval;
 			}
 			wakeup(semptr);
 		}