iproute2: backport json_print-fix-hidden-64-bit-type-promotion
The sender domain has a DMARC Reject/Quarantine policy which disallows sending mailing list messages using the original "From" header. To mitigate this problem, the original message has been wrapped automatically by the mailing list software. print_uint() will silently promote its variable type to uint64_t, but there is nothing that ensures that the format string specifier passed along with it fits (and the function name suggest to pass "%u"). Fix this by changing print_uint() to use a native 'unsigned int' type, and introduce a separate print_u64() function for printing 64-bit values. All call sites that were actually printing 64-bit values using print_uint() are converted to use print_u64() instead. Since print_int() was already using native int types, just add a print_s64() to match, but don't convert any call sites. Fixes wonkyness in some stats from some qdiscs under tc Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk>
This commit is contained in:
		 Kevin Darbyshire-Bryant
					Kevin Darbyshire-Bryant
				
			
				
					committed by
					
						 John Crispin
						John Crispin
					
				
			
			
				
	
			
			
			 John Crispin
						John Crispin
					
				
			
						parent
						
							53c474abbd
						
					
				
				
					commit
					ad5af37ca7
				
			| @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk | |||||||
|  |  | ||||||
| PKG_NAME:=iproute2 | PKG_NAME:=iproute2 | ||||||
| PKG_VERSION:=4.16.0 | PKG_VERSION:=4.16.0 | ||||||
| PKG_RELEASE:=1 | PKG_RELEASE:=2 | ||||||
|  |  | ||||||
| PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz | ||||||
| PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2 | PKG_SOURCE_URL:=@KERNEL/linux/utils/net/iproute2 | ||||||
|   | |||||||
| @@ -0,0 +1,288 @@ | |||||||
|  | From 8de9593bb9dc05cb1be593a237682e8707e41aa9 Mon Sep 17 00:00:00 2001 | ||||||
|  | From: =?UTF-8?q?Toke=20H=C3=B8iland-J=C3=B8rgensen?= <toke@toke.dk> | ||||||
|  | Date: Wed, 25 Apr 2018 16:19:35 +0200 | ||||||
|  | Subject: [PATCH] json_print: Fix hidden 64-bit type promotion | ||||||
|  | MIME-Version: 1.0 | ||||||
|  | Content-Type: text/plain; charset=UTF-8 | ||||||
|  | Content-Transfer-Encoding: 8bit | ||||||
|  |  | ||||||
|  | print_uint() will silently promote its variable type to uint64_t, but there | ||||||
|  | is nothing that ensures that the format string specifier passed along with | ||||||
|  | it fits (and the function name suggest to pass "%u"). | ||||||
|  |  | ||||||
|  | Fix this by changing print_uint() to use a native 'unsigned int' type, and | ||||||
|  | introduce a separate print_u64() function for printing 64-bit values. All | ||||||
|  | call sites that were actually printing 64-bit values using print_uint() are | ||||||
|  | converted to use print_u64() instead. | ||||||
|  |  | ||||||
|  | Since print_int() was already using native int types, just add a | ||||||
|  | print_s64() to match, but don't convert any call sites. | ||||||
|  |  | ||||||
|  | Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk> | ||||||
|  | Signed-off-by: Kevin Darbyshire-Bryant <ldir@darbyshire-bryant.me.uk> | ||||||
|  | --- | ||||||
|  |  include/json_print.h  |  4 +++- | ||||||
|  |  include/json_writer.h | 12 ++++++---- | ||||||
|  |  ip/ipaddress.c        | 62 +++++++++++++++++++++++++-------------------------- | ||||||
|  |  ip/ipmacsec.c         |  8 +++---- | ||||||
|  |  ip/ipmroute.c         |  6 ++--- | ||||||
|  |  lib/json_print.c      |  4 +++- | ||||||
|  |  lib/json_writer.c     | 30 +++++++++++++++++++++---- | ||||||
|  |  7 files changed, 78 insertions(+), 48 deletions(-) | ||||||
|  |  | ||||||
|  | --- a/include/json_print.h | ||||||
|  | +++ b/include/json_print.h | ||||||
|  | @@ -56,10 +56,12 @@ void close_json_array(enum output_type t | ||||||
|  |  		print_color_##type_name(t, COLOR_NONE, key, fmt, value);	\ | ||||||
|  |  	} | ||||||
|  |  _PRINT_FUNC(int, int); | ||||||
|  | +_PRINT_FUNC(s64, int64_t); | ||||||
|  |  _PRINT_FUNC(bool, bool); | ||||||
|  |  _PRINT_FUNC(null, const char*); | ||||||
|  |  _PRINT_FUNC(string, const char*); | ||||||
|  | -_PRINT_FUNC(uint, uint64_t); | ||||||
|  | +_PRINT_FUNC(uint, unsigned int); | ||||||
|  | +_PRINT_FUNC(u64, uint64_t); | ||||||
|  |  _PRINT_FUNC(hu, unsigned short); | ||||||
|  |  _PRINT_FUNC(hex, unsigned int); | ||||||
|  |  _PRINT_FUNC(0xhex, unsigned int); | ||||||
|  | --- a/include/json_writer.h | ||||||
|  | +++ b/include/json_writer.h | ||||||
|  | @@ -34,9 +34,11 @@ void jsonw_string(json_writer_t *self, c | ||||||
|  |  void jsonw_bool(json_writer_t *self, bool value); | ||||||
|  |  void jsonw_float(json_writer_t *self, double number); | ||||||
|  |  void jsonw_float_fmt(json_writer_t *self, const char *fmt, double num); | ||||||
|  | -void jsonw_uint(json_writer_t *self, uint64_t number); | ||||||
|  | +void jsonw_uint(json_writer_t *self, unsigned int number); | ||||||
|  | +void jsonw_u64(json_writer_t *self, uint64_t number); | ||||||
|  |  void jsonw_hu(json_writer_t *self, unsigned short number); | ||||||
|  | -void jsonw_int(json_writer_t *self, int64_t number); | ||||||
|  | +void jsonw_int(json_writer_t *self, int number); | ||||||
|  | +void jsonw_s64(json_writer_t *self, int64_t number); | ||||||
|  |  void jsonw_null(json_writer_t *self); | ||||||
|  |  void jsonw_lluint(json_writer_t *self, unsigned long long int num); | ||||||
|  |   | ||||||
|  | @@ -44,9 +46,11 @@ void jsonw_lluint(json_writer_t *self, u | ||||||
|  |  void jsonw_string_field(json_writer_t *self, const char *prop, const char *val); | ||||||
|  |  void jsonw_bool_field(json_writer_t *self, const char *prop, bool value); | ||||||
|  |  void jsonw_float_field(json_writer_t *self, const char *prop, double num); | ||||||
|  | -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num); | ||||||
|  | +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num); | ||||||
|  | +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num); | ||||||
|  |  void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num); | ||||||
|  | -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num); | ||||||
|  | +void jsonw_int_field(json_writer_t *self, const char *prop, int num); | ||||||
|  | +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num); | ||||||
|  |  void jsonw_null_field(json_writer_t *self, const char *prop); | ||||||
|  |  void jsonw_lluint_field(json_writer_t *self, const char *prop, | ||||||
|  |  			unsigned long long int num); | ||||||
|  | --- a/ip/ipaddress.c | ||||||
|  | +++ b/ip/ipaddress.c | ||||||
|  | @@ -555,21 +555,21 @@ static void print_vf_stats64(FILE *fp, s | ||||||
|  |   | ||||||
|  |  		/* RX stats */ | ||||||
|  |  		open_json_object("rx"); | ||||||
|  | -		print_uint(PRINT_JSON, "bytes", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "bytes", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_RX_BYTES])); | ||||||
|  | -		print_uint(PRINT_JSON, "packets", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "packets", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_RX_PACKETS])); | ||||||
|  | -		print_uint(PRINT_JSON, "multicast", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "multicast", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_MULTICAST])); | ||||||
|  | -		print_uint(PRINT_JSON, "broadcast", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "broadcast", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_BROADCAST])); | ||||||
|  |  		close_json_object(); | ||||||
|  |   | ||||||
|  |  		/* TX stats */ | ||||||
|  |  		open_json_object("tx"); | ||||||
|  | -		print_uint(PRINT_JSON, "tx_bytes", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "tx_bytes", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_TX_BYTES])); | ||||||
|  | -		print_uint(PRINT_JSON, "tx_packets", NULL, | ||||||
|  | +		print_u64(PRINT_JSON, "tx_packets", NULL, | ||||||
|  |  			   rta_getattr_u64(vf[IFLA_VF_STATS_TX_PACKETS])); | ||||||
|  |  		close_json_object(); | ||||||
|  |  		close_json_object(); | ||||||
|  | @@ -602,50 +602,50 @@ static void print_link_stats64(FILE *fp, | ||||||
|  |   | ||||||
|  |  		/* RX stats */ | ||||||
|  |  		open_json_object("rx"); | ||||||
|  | -		print_uint(PRINT_JSON, "bytes", NULL, s->rx_bytes); | ||||||
|  | -		print_uint(PRINT_JSON, "packets", NULL, s->rx_packets); | ||||||
|  | -		print_uint(PRINT_JSON, "errors", NULL, s->rx_errors); | ||||||
|  | -		print_uint(PRINT_JSON, "dropped", NULL, s->rx_dropped); | ||||||
|  | -		print_uint(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); | ||||||
|  | -		print_uint(PRINT_JSON, "multicast", NULL, s->multicast); | ||||||
|  | +		print_u64(PRINT_JSON, "bytes", NULL, s->rx_bytes); | ||||||
|  | +		print_u64(PRINT_JSON, "packets", NULL, s->rx_packets); | ||||||
|  | +		print_u64(PRINT_JSON, "errors", NULL, s->rx_errors); | ||||||
|  | +		print_u64(PRINT_JSON, "dropped", NULL, s->rx_dropped); | ||||||
|  | +		print_u64(PRINT_JSON, "over_errors", NULL, s->rx_over_errors); | ||||||
|  | +		print_u64(PRINT_JSON, "multicast", NULL, s->multicast); | ||||||
|  |  		if (s->rx_compressed) | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "compressed", | ||||||
|  |  				   NULL, s->rx_compressed); | ||||||
|  |   | ||||||
|  |  		/* RX error stats */ | ||||||
|  |  		if (show_stats > 1) { | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "length_errors", | ||||||
|  |  				   NULL, s->rx_length_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "crc_errors", | ||||||
|  |  				   NULL, s->rx_crc_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "frame_errors", | ||||||
|  |  				   NULL, s->rx_frame_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "fifo_errors", | ||||||
|  |  				   NULL, s->rx_fifo_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "missed_errors", | ||||||
|  |  				   NULL, s->rx_missed_errors); | ||||||
|  |  			if (s->rx_nohandler) | ||||||
|  | -				print_uint(PRINT_JSON, | ||||||
|  | +				print_u64(PRINT_JSON, | ||||||
|  |  					   "nohandler", NULL, s->rx_nohandler); | ||||||
|  |  		} | ||||||
|  |  		close_json_object(); | ||||||
|  |   | ||||||
|  |  		/* TX stats */ | ||||||
|  |  		open_json_object("tx"); | ||||||
|  | -		print_uint(PRINT_JSON, "bytes", NULL, s->tx_bytes); | ||||||
|  | -		print_uint(PRINT_JSON, "packets", NULL, s->tx_packets); | ||||||
|  | -		print_uint(PRINT_JSON, "errors", NULL, s->tx_errors); | ||||||
|  | -		print_uint(PRINT_JSON, "dropped", NULL, s->tx_dropped); | ||||||
|  | -		print_uint(PRINT_JSON, | ||||||
|  | +		print_u64(PRINT_JSON, "bytes", NULL, s->tx_bytes); | ||||||
|  | +		print_u64(PRINT_JSON, "packets", NULL, s->tx_packets); | ||||||
|  | +		print_u64(PRINT_JSON, "errors", NULL, s->tx_errors); | ||||||
|  | +		print_u64(PRINT_JSON, "dropped", NULL, s->tx_dropped); | ||||||
|  | +		print_u64(PRINT_JSON, | ||||||
|  |  			   "carrier_errors", | ||||||
|  |  			   NULL, s->tx_carrier_errors); | ||||||
|  | -		print_uint(PRINT_JSON, "collisions", NULL, s->collisions); | ||||||
|  | +		print_u64(PRINT_JSON, "collisions", NULL, s->collisions); | ||||||
|  |  		if (s->tx_compressed) | ||||||
|  |  			print_uint(PRINT_JSON, | ||||||
|  |  				   "compressed", | ||||||
|  | @@ -653,20 +653,20 @@ static void print_link_stats64(FILE *fp, | ||||||
|  |   | ||||||
|  |  		/* TX error stats */ | ||||||
|  |  		if (show_stats > 1) { | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "aborted_errors", | ||||||
|  |  				   NULL, s->tx_aborted_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "fifo_errors", | ||||||
|  |  				   NULL, s->tx_fifo_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "window_errors", | ||||||
|  |  				   NULL, s->tx_window_errors); | ||||||
|  | -			print_uint(PRINT_JSON, | ||||||
|  | +			print_u64(PRINT_JSON, | ||||||
|  |  				   "heartbeat_errors", | ||||||
|  |  				   NULL, s->tx_heartbeat_errors); | ||||||
|  |  			if (carrier_changes) | ||||||
|  | -				print_uint(PRINT_JSON, "carrier_changes", NULL, | ||||||
|  | +				print_u64(PRINT_JSON, "carrier_changes", NULL, | ||||||
|  |  					   rta_getattr_u32(carrier_changes)); | ||||||
|  |  		} | ||||||
|  |  		close_json_object(); | ||||||
|  | --- a/lib/json_print.c | ||||||
|  | +++ b/lib/json_print.c | ||||||
|  | @@ -117,8 +117,10 @@ void close_json_array(enum output_type t | ||||||
|  |  		}							\ | ||||||
|  |  	} | ||||||
|  |  _PRINT_FUNC(int, int); | ||||||
|  | +_PRINT_FUNC(s64, int64_t); | ||||||
|  |  _PRINT_FUNC(hu, unsigned short); | ||||||
|  | -_PRINT_FUNC(uint, uint64_t); | ||||||
|  | +_PRINT_FUNC(uint, unsigned int); | ||||||
|  | +_PRINT_FUNC(u64, uint64_t); | ||||||
|  |  _PRINT_FUNC(lluint, unsigned long long int); | ||||||
|  |  _PRINT_FUNC(float, double); | ||||||
|  |  #undef _PRINT_FUNC | ||||||
|  | --- a/lib/json_writer.c | ||||||
|  | +++ b/lib/json_writer.c | ||||||
|  | @@ -215,7 +215,12 @@ void jsonw_hu(json_writer_t *self, unsig | ||||||
|  |  	jsonw_printf(self, "%hu", num); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void jsonw_uint(json_writer_t *self, uint64_t num) | ||||||
|  | +void jsonw_uint(json_writer_t *self, unsigned int num) | ||||||
|  | +{ | ||||||
|  | +	jsonw_printf(self, "%u", num); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void jsonw_u64(json_writer_t *self, uint64_t num) | ||||||
|  |  { | ||||||
|  |  	jsonw_printf(self, "%"PRIu64, num); | ||||||
|  |  } | ||||||
|  | @@ -225,7 +230,12 @@ void jsonw_lluint(json_writer_t *self, u | ||||||
|  |  	jsonw_printf(self, "%llu", num); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void jsonw_int(json_writer_t *self, int64_t num) | ||||||
|  | +void jsonw_int(json_writer_t *self, int num) | ||||||
|  | +{ | ||||||
|  | +	jsonw_printf(self, "%d", num); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  | +void jsonw_s64(json_writer_t *self, int64_t num) | ||||||
|  |  { | ||||||
|  |  	jsonw_printf(self, "%"PRId64, num); | ||||||
|  |  } | ||||||
|  | @@ -258,12 +268,18 @@ void jsonw_float_field_fmt(json_writer_t | ||||||
|  |  	jsonw_float_fmt(self, fmt, val); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void jsonw_uint_field(json_writer_t *self, const char *prop, uint64_t num) | ||||||
|  | +void jsonw_uint_field(json_writer_t *self, const char *prop, unsigned int num) | ||||||
|  |  { | ||||||
|  |  	jsonw_name(self, prop); | ||||||
|  |  	jsonw_uint(self, num); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void jsonw_u64_field(json_writer_t *self, const char *prop, uint64_t num) | ||||||
|  | +{ | ||||||
|  | +	jsonw_name(self, prop); | ||||||
|  | +	jsonw_u64(self, num); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  void jsonw_hu_field(json_writer_t *self, const char *prop, unsigned short num) | ||||||
|  |  { | ||||||
|  |  	jsonw_name(self, prop); | ||||||
|  | @@ -278,12 +294,18 @@ void jsonw_lluint_field(json_writer_t *s | ||||||
|  |  	jsonw_lluint(self, num); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | -void jsonw_int_field(json_writer_t *self, const char *prop, int64_t num) | ||||||
|  | +void jsonw_int_field(json_writer_t *self, const char *prop, int num) | ||||||
|  |  { | ||||||
|  |  	jsonw_name(self, prop); | ||||||
|  |  	jsonw_int(self, num); | ||||||
|  |  } | ||||||
|  |   | ||||||
|  | +void jsonw_s64_field(json_writer_t *self, const char *prop, int64_t num) | ||||||
|  | +{ | ||||||
|  | +	jsonw_name(self, prop); | ||||||
|  | +	jsonw_s64(self, num); | ||||||
|  | +} | ||||||
|  | + | ||||||
|  |  void jsonw_null_field(json_writer_t *self, const char *prop) | ||||||
|  |  { | ||||||
|  |  	jsonw_name(self, prop); | ||||||
		Reference in New Issue
	
	Block a user