[PATCH nft 2/2] meta: relax restriction on UID/GID parsing

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



nft is currently rejecting unknown UID/GID if they don't exist in the
system, relax this as Bjørnar Ness considers this is a valid scenario.
Now this only reports an error if you pass an unknown user (expressed as
string or if the UID/GID goes above 32 bits).

Reported-by: Bjørnar Ness <bjornar.ness@xxxxxxxxx>
Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx>
---
 src/meta.c |   54 ++++++++++++++++++++++++++++++++++--------------------
 1 file changed, 34 insertions(+), 20 deletions(-)

diff --git a/src/meta.c b/src/meta.c
index 80c2638..32f3012 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -197,11 +197,14 @@ static void uid_type_print(const struct expr *expr)
 	struct passwd *pw;
 
 	if (numeric_output < NUMERIC_ALL) {
-		pw = getpwuid(mpz_get_uint32(expr->value));
-		if (pw != NULL) {
+		uint32_t uid = mpz_get_uint32(expr->value);
+
+		pw = getpwuid(uid);
+		if (pw != NULL)
 			printf("%s", pw->pw_name);
-			return;
-		}
+		else
+			printf("%d", uid);
+		return;
 	}
 	expr_basetype(expr)->print(expr);
 }
@@ -210,19 +213,23 @@ static struct error_record *uid_type_parse(const struct expr *sym,
 					   struct expr **res)
 {
 	struct passwd *pw;
+	uint64_t uid;
+	char *endptr = NULL;
 
 	pw = getpwnam(sym->identifier);
-	if (pw == NULL) {
-		/* Try harder, lookup based on UID */
-		pw = getpwuid(atol(sym->identifier));
-		if (pw == NULL)
+	if (pw != NULL)
+		uid = pw->pw_uid;
+	else {
+		uid = strtoull(sym->identifier, &endptr, 10);
+		if (uid > UINT32_MAX)
+			return error(&sym->location, "Value too large");
+		else if (*endptr)
 			return error(&sym->location, "User does not exist");
 	}
 
 	*res = constant_expr_alloc(&sym->location, sym->dtype,
 				   BYTEORDER_HOST_ENDIAN,
-				   sizeof(pw->pw_uid) * BITS_PER_BYTE,
-				   &pw->pw_uid);
+				   sizeof(pw->pw_uid) * BITS_PER_BYTE, &uid);
 	return NULL;
 }
 
@@ -242,11 +249,14 @@ static void gid_type_print(const struct expr *expr)
 	struct group *gr;
 
 	if (numeric_output < NUMERIC_ALL) {
-		gr = getgrgid(mpz_get_uint32(expr->value));
-		if (gr != NULL) {
+		uint32_t gid = mpz_get_uint32(expr->value);
+
+		gr = getgrgid(gid);
+		if (gr != NULL)
 			printf("%s", gr->gr_name);
-			return;
-		}
+		else
+			printf("%u", gid);
+		return;
 	}
 	expr_basetype(expr)->print(expr);
 }
@@ -255,19 +265,23 @@ static struct error_record *gid_type_parse(const struct expr *sym,
 					   struct expr **res)
 {
 	struct group *gr;
+	uint64_t gid;
+	char *endptr = NULL;
 
 	gr = getgrnam(sym->identifier);
-	if (gr == NULL) {
-		/* Try harder, lookup based on GID */
-		gr = getgrgid(atol(sym->identifier));
-		if (gr == NULL)
+	if (gr != NULL)
+		gid = gr->gr_gid;
+	else {
+		gid = strtoull(sym->identifier, &endptr, 0);
+		if (gid > UINT32_MAX)
+			return error(&sym->location, "Value too large");
+		else if (*endptr)
 			return error(&sym->location, "Group does not exist");
 	}
 
 	*res = constant_expr_alloc(&sym->location, sym->dtype,
 				   BYTEORDER_HOST_ENDIAN,
-				   sizeof(gr->gr_gid) * BITS_PER_BYTE,
-				   &gr->gr_gid);
+				   sizeof(gr->gr_gid) * BITS_PER_BYTE, &gid);
 	return NULL;
 }
 
-- 
1.7.10.4

--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Index of Archives]     [Netfitler Users]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux