-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Socket ether linux step2 #17926
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
base: master
Are you sure you want to change the base?
Socket ether linux step2 #17926
Conversation
e201885
to
1f1f204
Compare
This has a bit of class design so it should be probably at least posted to internals (it's not like adding a constant or a simple funciton). I agree that there should be some namespacing as well possibly. Definitely not the current names that will easily result in BC break for appliations. |
9e8daaa
to
8cd42ca
Compare
ping @arnaud-lb I think I have, at least, addressed the majority of your remarks :). |
c2fa112
to
3a67b50
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.
Sorry for the delay, I missed you ping
f8cb8fe
to
d23895d
Compare
struct ipv6hdr a; | ||
memcpy(&a, payload, sizeof(a)); | ||
struct ipv6hdr *ip = &a; | ||
size_t totalip = sizeof(*ip) + ip->payload_len; |
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.
We should not trust ip->payload_len
ext/sockets/sockets.c
Outdated
|
||
switch (protocol) { | ||
case ETH_P_IP: { | ||
payload = ((unsigned char *)e + ETH_HLEN); |
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.
We must check that slen >= ETH_HLEN
ext/sockets/sockets.c
Outdated
switch (ip->protocol) { | ||
case IPPROTO_TCP: { | ||
struct tcphdr a; | ||
memcpy(&a, ipdata, sizeof(a)); |
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.
We must check that ipdata + sizeof(tcphdr) < ZSTR_VAL(recv_buf) + slen
ext/sockets/sockets.c
Outdated
} | ||
case IPPROTO_UDP: { | ||
struct udphdr a; | ||
memcpy(&a, ipdata, sizeof(a)); |
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.
Here too
ext/sockets/sockets.c
Outdated
break; | ||
} | ||
case ETH_P_IPV6: { | ||
payload = ((unsigned char *)e + ETH_HLEN); |
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.
Here too
ext/sockets/sockets.c
Outdated
switch (ipprotocol) { | ||
case IPPROTO_TCP: { | ||
struct tcphdr a; | ||
memcpy(&a, ipdata, sizeof(a)); |
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.
Here too (I think this switch block is the same as in the ETH_P_IP case, and could be extracted to a separate function?)
ext/sockets/sockets.c
Outdated
} | ||
case IPPROTO_UDP: { | ||
struct udphdr a; | ||
memcpy(&a, ipdata, sizeof(a)); |
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.
Here too
ext/sockets/sockets.c
Outdated
break; | ||
} | ||
case ETH_P_LOOP: { | ||
struct ethhdr *innere = (struct ethhdr *)((unsigned char *)e + ETH_HLEN); |
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.
Here too
ext/sockets/sockets.c
Outdated
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("srcPort"), ntohs(tcp->th_sport)); | ||
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("dstPort"), ntohs(tcp->th_dport)); | ||
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("headerSize"), sizeof(*tcp)); | ||
zend_update_property_string(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("rawPacket"), (char *)ipdata); |
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.
We should use zend_update_property_stringl()
here (and in other places), as ipdata
is not a null-terminated string
ac62db0
to
6d9466a
Compare
@arnaud-lb I plan to add more tests later but let me know if, at least, the direction it is taking looks ok. |
@devnexen yes, the direction it is taking is looking better! It feels safer now with |
696ef35
to
6b017cf
Compare
ext/sockets/sockets.c
Outdated
return FAILURE; | ||
} | ||
|
||
memcpy(ZSTR_VAL(dst), ZSTR_VAL(src) + offset, len); |
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.
Please also set the trailing null byte
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("srcPort"), ntohs(tcp->th_sport)); | ||
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("dstPort"), ntohs(tcp->th_dport)); | ||
zend_update_property_long(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("headerSize"), sizeof(*tcp)); | ||
zend_update_property_stringl(Z_OBJCE_P(szpayload), Z_OBJ_P(szpayload), ZEND_STRL("rawPacket"), (char *)ipdata, sizeof(*tcp)); |
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.
sizeof(*tcp)
is the header size, but you want the full packet size here
ext/sockets/sockets.c
Outdated
struct tcphdr a; | ||
ETH_SUB_CHECKLENGTH(a, "TCP"); | ||
memcpy(&a, ipdata, sizeof(a)); | ||
struct tcphdr *tcp = &a; |
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.
struct tcphdr a; | |
ETH_SUB_CHECKLENGTH(a, "TCP"); | |
memcpy(&a, ipdata, sizeof(a)); | |
struct tcphdr *tcp = &a; | |
struct tcphdr tcp; | |
ETH_SUB_CHECKLENGTH(tcp, "TCP"); | |
memcpy(&tcp, ipdata, sizeof(a)); |
Then use &tcp
instead of tcp
bellow.
static zend_result php_socket_afpacket_add_tcp(unsigned char *ipdata, struct sockaddr_ll sll, char *ifrname, zend_string *recv_buf, | ||
size_t slen, zval *szpayload, zval *zpayload, zval *obj, zval *arg2, zval *arg5, zval *arg6) { |
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.
Most params here are unused. These could be removed.
static zend_result php_socket_afpacket_add_udp(unsigned char *ipdata, struct sockaddr_ll sll, char *ifrname, zend_string *recv_buf, | ||
size_t slen, zval *szpayload, zval *zpayload, zval *obj, zval *arg2, zval *arg5, zval *arg6) { |
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.
Most params here are unused. These could be removed.
ext/sockets/sockets.c
Outdated
struct ethhdr a; | ||
memcpy(&a, ZSTR_VAL(dst_buf), ETH_HLEN); | ||
struct ethhdr *e = &a; |
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.
struct ethhdr a; | |
memcpy(&a, ZSTR_VAL(dst_buf), ETH_HLEN); | |
struct ethhdr *e = &a; | |
struct ethhdr e; | |
memcpy(&e, ZSTR_VAL(dst_buf), ETH_HLEN); |
ext/sockets/sockets.c
Outdated
struct iphdr a; | ||
memcpy(&a, payload, sizeof(a)); | ||
struct iphdr *ip = &a; |
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.
struct iphdr a; | |
memcpy(&a, payload, sizeof(a)); | |
struct iphdr *ip = &a; | |
struct iphdr ip; | |
memcpy(&ip, payload, sizeof(ip)); |
size_t tlayer = ip->ihl * 4; | ||
size_t totalip = ntohs(ip->tot_len); | ||
|
||
if (tlayer < sizeof(*ip) || totalip < tlayer || totalip < slen) { |
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.
We can probably replace this check by a php_socket_get_chunk()
call now
ext/sockets/sockets.c
Outdated
if (tlayer < sizeof(*ip) || totalip < tlayer || totalip < slen) { | ||
ZVAL_NULL(&zpayload); | ||
zend_update_property(Z_OBJCE(obj), Z_OBJ(obj), ZEND_STRL("payload"), &zpayload); | ||
zend_update_property_string(Z_OBJCE(obj), Z_OBJ(obj), ZEND_STRL("rawPacket"), ZSTR_VAL(recv_buf)); |
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.
rawPacket will be truncated if it contains null bytes. We should specify a length, or use zend_update_property_str()
(in which case we should replace zend_string_efree()
by zend_string_release()
bellow).
ext/sockets/sockets.c
Outdated
zend_update_property_long(Z_OBJCE(zpayload), Z_OBJ(zpayload), ZEND_STRL("headerSize"), totalip); | ||
zend_update_property_stringl(Z_OBJCE(zpayload), Z_OBJ(zpayload), ZEND_STRL("rawPacket"), (char *)payload, totalip); |
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 length look wrong
Back to the drawing board due to UAF with previous version. This reverts commit cc11606.
6b017cf
to
83453b9
Compare
No description provided.