I went a tiny bit beyond pure textual conversion and moved a bit of code.

OK?

>From d8ace6480e76e948631a40bcb8fa812366b82384 Mon Sep 17 00:00:00 2001
From: Greg Steuck <[email protected]>
Date: Sat, 14 Nov 2020 20:55:14 -0800
Subject: [PATCH 3/3] Convert sysctl_sysvsem to sysctl_bounded_args

Used sysctl_int_bounded in many places to shrink code.
Extracted a new function to make the case tidy.
Removed some superflous fluff.
---
 sys/kern/sysv_sem.c | 127 ++++++++++++++++----------------------------
 1 file changed, 47 insertions(+), 80 deletions(-)

diff --git sys/kern/sysv_sem.c sys/kern/sysv_sem.c
index 8425888ccea..feddabe9550 100644
--- sys/kern/sysv_sem.c
+++ sys/kern/sysv_sem.c
@@ -838,6 +838,35 @@ semexit(struct process *pr)
        semutot--;
 }
 
+/* Expand semsegs and semseqs arrays */
+void
+sema_reallocate(int val)
+{
+       struct semid_ds **sema_new;
+       unsigned short *newseqs;
+       sema_new = mallocarray(val, sizeof(struct semid_ds *),
+           M_SEM, M_WAITOK|M_ZERO);
+       memcpy(sema_new, sema,
+           seminfo.semmni * sizeof(struct semid_ds *));
+       newseqs = mallocarray(val, sizeof(unsigned short), M_SEM,
+           M_WAITOK|M_ZERO);
+       memcpy(newseqs, semseqs,
+           seminfo.semmni * sizeof(unsigned short));
+       free(sema, M_SEM, seminfo.semmni * sizeof(struct semid_ds *));
+       free(semseqs, M_SEM, seminfo.semmni * sizeof(unsigned short));
+       sema = sema_new;
+       semseqs = newseqs;
+       seminfo.semmni = val;
+}
+
+const struct sysctl_bounded_args sysvsem_vars[] = {
+       { KERN_SEMINFO_SEMUME, &seminfo.semume, 1, 0 },
+       { KERN_SEMINFO_SEMUSZ, &seminfo.semusz, 1, 0 },
+       { KERN_SEMINFO_SEMVMX, &seminfo.semvmx, 1, 0 },
+       { KERN_SEMINFO_SEMAEM, &seminfo.semaem, 1, 0 },
+       { KERN_SEMINFO_SEMOPM, &seminfo.semopm, 1, INT_MAX },
+};
+
 /*
  * Userland access to struct seminfo.
  */
@@ -846,97 +875,35 @@ sysctl_sysvsem(int *name, u_int namelen, void *oldp, 
size_t *oldlenp,
        void *newp, size_t newlen)
 {
        int error, val;
-       struct semid_ds **sema_new;
-       unsigned short *newseqs;
 
-       if (namelen != 2) {
-               switch (name[0]) {
-               case KERN_SEMINFO_SEMMNI:
-               case KERN_SEMINFO_SEMMNS:
-               case KERN_SEMINFO_SEMMNU:
-               case KERN_SEMINFO_SEMMSL:
-               case KERN_SEMINFO_SEMOPM:
-               case KERN_SEMINFO_SEMUME:
-               case KERN_SEMINFO_SEMUSZ:
-               case KERN_SEMINFO_SEMVMX:
-               case KERN_SEMINFO_SEMAEM:
-                       break;
-               default:
-                        return (ENOTDIR);       /* overloaded */
-                }
-        }
+       if (namelen != 1)
+                        return (ENOTDIR);       /* leaf-only */
 
        switch (name[0]) {
        case KERN_SEMINFO_SEMMNI:
                val = seminfo.semmni;
-               if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) ||
-                   val == seminfo.semmni)
+               error = sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                   &val, val, 0xffff);
+               /* returns success and skips reallocation if val is unchanged */
+               if (error || val == seminfo.semmni)
                        return (error);
-
-               if (val < seminfo.semmni || val > 0xffff)
-                       return (EINVAL);
-
-               /* Expand semsegs and semseqs arrays */
-               sema_new = mallocarray(val, sizeof(struct semid_ds *),
-                   M_SEM, M_WAITOK|M_ZERO);
-               memcpy(sema_new, sema,
-                   seminfo.semmni * sizeof(struct semid_ds *));
-               newseqs = mallocarray(val, sizeof(unsigned short), M_SEM,
-                   M_WAITOK|M_ZERO);
-               memcpy(newseqs, semseqs,
-                   seminfo.semmni * sizeof(unsigned short));
-               free(sema, M_SEM, seminfo.semmni * sizeof(struct semid_ds *));
-               free(semseqs, M_SEM, seminfo.semmni * sizeof(unsigned short));
-               sema = sema_new;
-               semseqs = newseqs;
-               seminfo.semmni = val;
+               sema_reallocate(val);
                return (0);
        case KERN_SEMINFO_SEMMNS:
-               val = seminfo.semmns;
-               if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) ||
-                   val == seminfo.semmns)
-                       return (error);
-               if (val < seminfo.semmns || val > 0xffff)
-                       return (EINVAL);        /* can't decrease semmns */
-               seminfo.semmns = val;
-               return (0);
+               /* can't decrease semmns or go over 2^16 */
+               return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                   &seminfo.semmns, seminfo.semmns, 0xffff));
        case KERN_SEMINFO_SEMMNU:
-               val = seminfo.semmnu;
-               if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) ||
-                   val == seminfo.semmnu)
-                       return (error);
-               if (val < seminfo.semmnu)
-                       return (EINVAL);        /* can't decrease semmnu */
-               seminfo.semmnu = val;
-               return (0);
+               /* can't decrease semmnu or go over 2^16 */
+               return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                   &seminfo.semmnu, seminfo.semmnu, 0xffff));
        case KERN_SEMINFO_SEMMSL:
-               val = seminfo.semmsl;
-               if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) ||
-                   val == seminfo.semmsl)
-                       return (error);
-               if (val < seminfo.semmsl || val > 0xffff)
-                       return (EINVAL);        /* can't decrease semmsl */
-               seminfo.semmsl = val;
-               return (0);
-       case KERN_SEMINFO_SEMOPM:
-               val = seminfo.semopm;
-               if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) ||
-                   val == seminfo.semopm)
-                       return (error);
-               if (val <= 0)
-                       return (EINVAL);        /* semopm must be >= 1 */
-               seminfo.semopm = val;
-               return (0);
-       case KERN_SEMINFO_SEMUME:
-               return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semume));
-       case KERN_SEMINFO_SEMUSZ:
-               return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semusz));
-       case KERN_SEMINFO_SEMVMX:
-               return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semvmx));
-       case KERN_SEMINFO_SEMAEM:
-               return (sysctl_rdint(oldp, oldlenp, newp, seminfo.semaem));
+               /* can't decrease semmsl or go over 2^16 */
+               return (sysctl_int_bounded(oldp, oldlenp, newp, newlen,
+                   &seminfo.semmsl, seminfo.semmsl, 0xffff));
        default:
-               return (EOPNOTSUPP);
+               return (sysctl_bounded_arr(sysvsem_vars, nitems(sysvsem_vars),
+                   name, namelen, oldp, oldlenp, newp, newlen));
        }
        /* NOTREACHED */
 }
-- 
2.29.2

Reply via email to