-
Notifications
You must be signed in to change notification settings - Fork 7.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix #16944: Invalid filtering of IPv6 with FILTER_FLAG_NO_RES_RANGE #17111
base: PHP-8.3
Are you sure you want to change the base?
Conversation
/cc @nielsdos @nicolas-grekas — It makes most sense to review this commit-by-commit. |
1096e89
to
0a5aab6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is much much nicer, thanks a lot!
*private = false; | ||
|
||
if (ip[0] == 0) { | ||
/* RFC 1122 - This host on this network */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The errata for RFC6890 changes this, see https://www.rfc-editor.org/errata_search.php?rfc=6890&rec_status=1&presentation=records
Should instead be: /* RFC 0791 - This network */
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It actually splits up the record into two, so I've made this change instead:
}
/* }}} */
-/* From the tables in RFC 6890 - Special-Purpose IP Address Registries */
-static bool ipv4_get_status_flags(int ip[8], bool *global, bool *reserved, bool *private)
+/* From the tables in RFC 6890 - Special-Purpose IP Address Registriesi
+ * Including errata: https://www.rfc-editor.org/errata_search.php?rfc=6890&rec_status=1 */
+static bool ipv4_get_status_flags(const int ip[8], bool *global, bool *reserved, bool *private)
{
*global = false;
*reserved = false;
*private = false;
if (ip[0] == 0) {
+ /* RFC 0791 - This network */
+ *reserved = true;
+ } else if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
/* RFC 1122 - This host on this network */
*reserved = true;
} else if (ip[0] == 10) {
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems good to me. The compiler will optimize that anyway so it's okay to be verbose 🙂
ext/filter/logical_filters.c
Outdated
*private = true; | ||
} else if (ip[0] == 192 && ip[1] == 0 && ip[2] == 0) { | ||
/* RFC 6890 - IETF Protocol Assignments */ | ||
} else if (ip[0] == 192 && ip[1] >= 0 && ip[1] <= 31) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The range is 192.0.0.0/29
. So this seems wrong because it is 192.0.0.0
until 192.0.0.7
, because only the 3 bottom bits are free to use. So both the range and indices of the ip in this check are not correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! It looks like the original code didn't even check for this one.
ext/filter/logical_filters.c
Outdated
@@ -869,6 +869,106 @@ static int _php_filter_validate_ipv6(const char *str, size_t str_len, int ip[8]) | |||
} | |||
/* }}} */ | |||
|
|||
/* From the tables in RFC 6890 - Special-Purpose IP Address Registries */ | |||
static bool ipv4_get_status_flags(int ip[8], bool *global, bool *reserved, bool *private) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could be const int ip[8]
in theory, but doesn't matter much.
Also note that this should target branch PHP-8.3, see https://externals.io/message/125995 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also going to retarget this for PHP 8.3
ext/filter/logical_filters.c
Outdated
*private = true; | ||
} else if (ip[0] == 192 && ip[1] == 0 && ip[2] == 0) { | ||
/* RFC 6890 - IETF Protocol Assignments */ | ||
} else if (ip[0] == 192 && ip[1] >= 0 && ip[1] <= 31) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! It looks like the original code didn't even check for this one.
*private = false; | ||
|
||
if (ip[0] == 0) { | ||
/* RFC 1122 - This host on this network */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It actually splits up the record into two, so I've made this change instead:
}
/* }}} */
-/* From the tables in RFC 6890 - Special-Purpose IP Address Registries */
-static bool ipv4_get_status_flags(int ip[8], bool *global, bool *reserved, bool *private)
+/* From the tables in RFC 6890 - Special-Purpose IP Address Registriesi
+ * Including errata: https://www.rfc-editor.org/errata_search.php?rfc=6890&rec_status=1 */
+static bool ipv4_get_status_flags(const int ip[8], bool *global, bool *reserved, bool *private)
{
*global = false;
*reserved = false;
*private = false;
if (ip[0] == 0) {
+ /* RFC 0791 - This network */
+ *reserved = true;
+ } else if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0) {
/* RFC 1122 - This host on this network */
*reserved = true;
} else if (ip[0] == 10) {
ext/filter/logical_filters.c
Outdated
/* RFC 1122 - Reserved */ | ||
*reserved = true; | ||
} else if (ip[0] == 255 && ip[1] == 255 && ip[2] == 255 && ip[3] == 255) { | ||
/* RFC 0919 - Limited Broadcast */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I did another pass over the PR, and I only have one question for this line here.
RFC8190 updates some parts of RFC6890, but the only change relevant to this RP seems to be "2.2. Updates to the IPv4 Special-Purpose Address Registry". It states:
Limited Broadcast prefix (255.255.255.255/32) - The Reserved-by-
Protocol value has changed from False to True. This change was
made to align the registry with reservation of the limited
broadcast address with Section 7 of [RFC919].
So this likely now needs to set reserved
to true.
…turned to IANA (RFC 3701)
103c9ae
to
50f99af
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks right, thanks
It also refactors the code to use the actual tables from RFC 6890, and fixed other bugs with these ranges that were introduced with #7893