[master] 3dd4d72df std.ip: Always provide some form of fallback

Dridi Boukelmoune dridi.boukelmoune at gmail.com
Mon Nov 29 14:47:06 UTC 2021


commit 3dd4d72df82be40782374195225c79f6cb9424d9
Author: Dridi Boukelmoune <dridi.boukelmoune at gmail.com>
Date:   Fri Nov 26 12:56:10 2021 +0100

    std.ip: Always provide some form of fallback
    
    Otherwise valid code can panic on workspace exhaustion:
    
        std.ip(req.http.X-Real-IP, std.ip(req.http.X-Client-IP, client.ip))
    
    If the nested std.ip() call runs out of workspace, it will return a null
    ip instead of the fallback, and since the outer std.ip() call is getting
    a fallback argument, it will panic upon checking the suckaddr sanity.
    
    Refs a3b26d0ba7dd8763a4e34d9e18d92fc24f1c291c

diff --git a/vmod/vmod_std_conversions.c b/vmod/vmod_std_conversions.c
index 4ce88474b..c45410114 100644
--- a/vmod/vmod_std_conversions.c
+++ b/vmod/vmod_std_conversions.c
@@ -200,17 +200,23 @@ vmod_ip(VRT_CTX, struct VARGS(ip) *a)
 {
 	uintptr_t sn;
 	void *p;
-	VCL_IP retval = NULL;
+	VCL_IP retval = NULL, fb = bogo_ip;
 
 	CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
-	if (a->valid_fallback)
-		assert(VSA_Sane(a->fallback));
+
+	if (a->valid_fallback) {
+		if (a->fallback == NULL || !VSA_Sane(a->fallback)) {
+			VRT_fail(ctx, "std.ip: invalid fallback");
+			return (fb);
+		}
+		fb = a->fallback;
+	}
 
 	sn = WS_Snapshot(ctx->ws);
 	p = WS_Alloc(ctx->ws, vsa_suckaddr_len);
 	if (p == NULL) {
 		VRT_fail(ctx, "std.ip: insufficient workspace");
-		return (NULL);
+		return (fb);
 	}
 
 	if (a->s != NULL)
@@ -224,11 +230,10 @@ vmod_ip(VRT_CTX, struct VARGS(ip) *a)
 
 	WS_Reset(ctx->ws, sn);
 
-	if (a->valid_fallback)
-		return (a->fallback);
+	if (!a->valid_fallback)
+		VRT_fail(ctx, "std.ip: conversion failed");
 
-	VRT_fail(ctx, "std.ip: conversion failed");
-	return (NULL);
+	return (fb);
 }
 
 VCL_REAL v_matchproto_(td_std_real)


More information about the varnish-commit mailing list