From d51abd5fe12cb7a345ea94bd70f38be24f655d90 Mon Sep 17 00:00:00 2001
From: Bryan Drewery <bdrewery@FreeBSD.org>
Date: Wed, 26 Sep 2018 18:40:57 +0000
Subject: [PATCH] Handle overflow of uid or gid in arguments for chown

chown incorrectly allows a uid or gid greater than UID_MAX/GID_MAX respectively.
Using such an argument rolls over to accounts such as root, operator, etc.

Approved by:	re (gjb)
Relnotes:	yes
Reviewed by:	cem, kib
Submitted by:	Don Morris <dgmorris@earthlink.net>
Sponsored by:	Dell EMC
Differential Revision:	https://reviews.freebsd.org/D15119
---
 usr.sbin/chown/chown.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/usr.sbin/chown/chown.c b/usr.sbin/chown/chown.c
index e568fe8acc13..8f09b62d10ca 100644
--- a/usr.sbin/chown/chown.c
+++ b/usr.sbin/chown/chown.c
@@ -55,6 +55,7 @@ __FBSDID("$FreeBSD$");
 #include <libgen.h>
 #include <pwd.h>
 #include <signal.h>
+#include <stddef.h>
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -246,16 +247,13 @@ a_uid(const char *s)
 static uid_t
 id(const char *name, const char *type)
 {
-	uid_t val;
+	unsigned long val;
 	char *ep;
 
-	/*
-	 * XXX
-	 * We know that uid_t's and gid_t's are unsigned longs.
-	 */
 	errno = 0;
 	val = strtoul(name, &ep, 10);
-	if (errno || *ep != '\0')
+	_Static_assert(UID_MAX >= GID_MAX, "UID MAX less than GID MAX");
+	if (errno || *ep != '\0' || val > UID_MAX)
 		errx(1, "%s: illegal %s name", name, type);
 	return (val);
 }