aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2021-07-23 14:37:11 +0000
committerMark Johnston <markj@FreeBSD.org>2021-07-30 00:32:58 +0000
commitb76e41fca95f189a1bc759f3318c96ff8653ba01 (patch)
treef59121444b4efaf2b2df3facc078858f11ed9b61
parentfe6803c18e814d3fdf901ecec3442f7ad959b6a4 (diff)
downloadsrc-b76e41fca95f189a1bc759f3318c96ff8653ba01.tar.gz
src-b76e41fca95f189a1bc759f3318c96ff8653ba01.zip
Add required sysctl name length checks to various handlers
Reported by: KMSAN Sponsored by: The FreeBSD Foundation (cherry picked from commit 0dcef81de9915e8ce1e3985204bebe7026d96b6f)
-rw-r--r--sys/kern/kern_descrip.c20
-rw-r--r--sys/kern/kern_proc.c16
-rw-r--r--sys/net/rtsock.c5
3 files changed, 39 insertions, 2 deletions
diff --git a/sys/kern/kern_descrip.c b/sys/kern/kern_descrip.c
index 36092c9acd42..c7269e4b33a9 100644
--- a/sys/kern/kern_descrip.c
+++ b/sys/kern/kern_descrip.c
@@ -4092,8 +4092,13 @@ sysctl_kern_proc_nfds(SYSCTL_HANDLER_ARGS)
{
NDSLOTTYPE *map;
struct filedesc *fdp;
+ u_int namelen;
int count, off, minoff;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
if (*(int *)arg1 != 0)
return (EINVAL);
@@ -4482,8 +4487,13 @@ sysctl_kern_proc_filedesc(SYSCTL_HANDLER_ARGS)
struct sbuf sb;
struct proc *p;
ssize_t maxlen;
+ u_int namelen;
int error, error2, *name;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
name = (int *)arg1;
sbuf_new_for_sysctl(&sb, NULL, FILEDESC_SBUF_SIZE, req);
@@ -4561,10 +4571,15 @@ sysctl_kern_proc_ofiledesc(SYSCTL_HANDLER_ARGS)
struct filedesc *fdp;
struct pwddesc *pdp;
struct pwd *pwd;
+ u_int namelen;
int error, i, lastfile, *name;
struct file *fp;
struct proc *p;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
name = (int *)arg1;
error = pget((pid_t)name[0], PGET_CANDEBUG | PGET_NOTWEXIT, &p);
if (error != 0)
@@ -4706,8 +4721,13 @@ sysctl_kern_proc_cwd(SYSCTL_HANDLER_ARGS)
struct sbuf sb;
struct proc *p;
ssize_t maxlen;
+ u_int namelen;
int error, error2, *name;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
name = (int *)arg1;
sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_file), req);
diff --git a/sys/kern/kern_proc.c b/sys/kern/kern_proc.c
index ec732e8db060..2017f824f6ad 100644
--- a/sys/kern/kern_proc.c
+++ b/sys/kern/kern_proc.c
@@ -2297,7 +2297,7 @@ static int
sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
{
vm_map_entry_t entry, tmp_entry;
- unsigned int last_timestamp;
+ unsigned int last_timestamp, namelen;
char *fullpath, *freepath;
struct kinfo_ovmentry *kve;
struct vattr va;
@@ -2308,6 +2308,10 @@ sysctl_kern_proc_ovmmap(SYSCTL_HANDLER_ARGS)
vm_map_t map;
struct vmspace *vm;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
name = (int *)arg1;
error = pget((pid_t)name[0], PGET_WANTREAD, &p);
if (error != 0)
@@ -2678,8 +2682,13 @@ sysctl_kern_proc_vmmap(SYSCTL_HANDLER_ARGS)
{
struct proc *p;
struct sbuf sb;
+ u_int namelen;
int error, error2, *name;
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
+
name = (int *)arg1;
sbuf_new_for_sysctl(&sb, NULL, sizeof(struct kinfo_vmentry), req);
sbuf_clear_flags(&sb, SBUF_INCLUDENUL);
@@ -2705,6 +2714,11 @@ sysctl_kern_proc_kstack(SYSCTL_HANDLER_ARGS)
struct stack *st;
struct sbuf sb;
struct proc *p;
+ u_int namelen;
+
+ namelen = arg2;
+ if (namelen != 1)
+ return (EINVAL);
name = (int *)arg1;
error = pget((pid_t)name[0], PGET_NOTINEXEC | PGET_WANTREAD, &p);
diff --git a/sys/net/rtsock.c b/sys/net/rtsock.c
index 3cb645f42e4c..1f898c739725 100644
--- a/sys/net/rtsock.c
+++ b/sys/net/rtsock.c
@@ -2563,7 +2563,10 @@ sysctl_rtsock(SYSCTL_HANDLER_ARGS)
u_char af;
struct walkarg w;
- name ++;
+ if (namelen < 3)
+ return (EINVAL);
+
+ name++;
namelen--;
if (req->newptr)
return (EPERM);