Mostly mindless application of the pattern established by "Convert sysctl_sysvsem to sysctl_bounded_args".
>From bb0af6eb29a39924131bb87f4e78a27afc1d0e13 Mon Sep 17 00:00:00 2001 From: Greg Steuck <g...@nest.cx> Date: Mon, 16 Nov 2020 22:27:33 -0800 Subject: [PATCH] Convert sysctl_sysvsem to sysctl_int_bounded Performed a minor refactoring and removed a few trailing whitespaces. --- sys/kern/sysv_shm.c | 106 ++++++++++++++++++-------------------------- 1 file changed, 42 insertions(+), 64 deletions(-) diff --git sys/kern/sysv_shm.c sys/kern/sysv_shm.c index 1fd99f5b95d..311c9862353 100644 --- sys/kern/sysv_shm.c +++ sys/kern/sysv_shm.c @@ -252,7 +252,7 @@ sys_shmat(struct proc *p, void *v, register_t *retval) prot |= PROT_WRITE; if (SCARG(uap, shmaddr)) { flags |= UVM_FLAG_FIXED; - if (SCARG(uap, shmflg) & SHM_RND) + if (SCARG(uap, shmflg) & SHM_RND) attach_va = (vaddr_t)SCARG(uap, shmaddr) & ~(SHMLBA-1); else if (((vaddr_t)SCARG(uap, shmaddr) & (SHMLBA-1)) == 0) @@ -393,7 +393,7 @@ shmget_allocate_segment(struct proc *p, struct shmid_ds *shmseg; struct shm_handle *shm_handle; int error = 0; - + if (SCARG(uap, size) < shminfo.shmmin || SCARG(uap, size) > shminfo.shmmax) return (EINVAL); @@ -473,7 +473,7 @@ sys_shmget(struct proc *p, void *v, register_t *retval) segnum = shm_find_segment_by_key(SCARG(uap, key)); if (segnum >= 0) return (shmget_existing(p, uap, mode, segnum, retval)); - if ((SCARG(uap, shmflg) & IPC_CREAT) == 0) + if ((SCARG(uap, shmflg) & IPC_CREAT) == 0) return (ENOENT); } error = shmget_allocate_segment(p, uap, mode, retval); @@ -546,6 +546,28 @@ shminit(void) shm_committed = 0; } +/* Expand shmsegs and shmseqs arrays */ +void +shm_reallocate(int val) +{ + struct shmid_ds **newsegs; + unsigned short *newseqs; + newsegs = mallocarray(val, sizeof(struct shmid_ds *), + M_SHM, M_WAITOK|M_ZERO); + memcpy(newsegs, shmsegs, + shminfo.shmmni * sizeof(struct shmid_ds *)); + free(shmsegs, M_SHM, + shminfo.shmmni * sizeof(struct shmid_ds *)); + shmsegs = newsegs; + newseqs = mallocarray(val, sizeof(unsigned short), M_SHM, + M_WAITOK|M_ZERO); + memcpy(newseqs, shmseqs, + shminfo.shmmni * sizeof(unsigned short)); + free(shmseqs, M_SHM, shminfo.shmmni * sizeof(unsigned short)); + shmseqs = newseqs; + shminfo.shmmni = val; +} + /* * Userland access to struct shminfo. */ @@ -554,26 +576,14 @@ sysctl_sysvshm(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { int error, val; - struct shmid_ds **newsegs; - unsigned short *newseqs; - if (namelen != 2) { - switch (name[0]) { - case KERN_SHMINFO_SHMMAX: - case KERN_SHMINFO_SHMMIN: - case KERN_SHMINFO_SHMMNI: - case KERN_SHMINFO_SHMSEG: - case KERN_SHMINFO_SHMALL: - break; - default: - return (ENOTDIR); /* overloaded */ - } - } + if (namelen != 1) + return (ENOTDIR); /* leaf-only */ switch (name[0]) { case KERN_SHMINFO_SHMMAX: - if ((error = sysctl_int(oldp, oldlenp, newp, newlen, - &shminfo.shmmax)) || newp == NULL) + if ((error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, + &shminfo.shmmax, 0, INT_MAX)) || newp == NULL) return (error); /* If new shmmax > shmall, crank shmall */ @@ -581,57 +591,25 @@ sysctl_sysvshm(int *name, u_int namelen, void *oldp, size_t *oldlenp, shminfo.shmall = atop(round_page(shminfo.shmmax)); return (0); case KERN_SHMINFO_SHMMIN: - val = shminfo.shmmin; - if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || - val == shminfo.shmmin) - return (error); - if (val <= 0) - return (EINVAL); /* shmmin must be >= 1 */ - shminfo.shmmin = val; - return (0); + return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, + &shminfo.shmmin, 1, INT_MAX)); case KERN_SHMINFO_SHMMNI: val = shminfo.shmmni; - if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || - val == shminfo.shmmni) + /* can't decrease shmmni */ + error = sysctl_int_bounded(oldp, oldlenp, newp, newlen, + &val, val, 0xffff); + /* returns success and skips reallocation if val is unchanged */ + if (error || val == shminfo.shmmni) return (error); - - if (val < shminfo.shmmni || val > 0xffff) - return (EINVAL); - - /* Expand shmsegs and shmseqs arrays */ - newsegs = mallocarray(val, sizeof(struct shmid_ds *), - M_SHM, M_WAITOK|M_ZERO); - memcpy(newsegs, shmsegs, - shminfo.shmmni * sizeof(struct shmid_ds *)); - free(shmsegs, M_SHM, - shminfo.shmmni * sizeof(struct shmid_ds *)); - shmsegs = newsegs; - newseqs = mallocarray(val, sizeof(unsigned short), M_SHM, - M_WAITOK|M_ZERO); - memcpy(newseqs, shmseqs, - shminfo.shmmni * sizeof(unsigned short)); - free(shmseqs, M_SHM, shminfo.shmmni * sizeof(unsigned short)); - shmseqs = newseqs; - shminfo.shmmni = val; + shm_reallocate(val); return (0); case KERN_SHMINFO_SHMSEG: - val = shminfo.shmseg; - if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || - val == shminfo.shmseg) - return (error); - if (val <= 0) - return (EINVAL); /* shmseg must be >= 1 */ - shminfo.shmseg = val; - return (0); + return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, + &shminfo.shmseg, 1, INT_MAX)); case KERN_SHMINFO_SHMALL: - val = shminfo.shmall; - if ((error = sysctl_int(oldp, oldlenp, newp, newlen, &val)) || - val == shminfo.shmall) - return (error); - if (val < shminfo.shmall) - return (EINVAL); /* can't decrease shmall */ - shminfo.shmall = val; - return (0); + /* can't decrease shmall */ + return (sysctl_int_bounded(oldp, oldlenp, newp, newlen, + &shminfo.shmall, shminfo.shmall, INT_MAX)); default: return (EOPNOTSUPP); } -- 2.29.2