@@ -1450,6 +1450,17 @@ PHP_FUNCTION(socket_bind)
1450
1450
return FAILURE; \
1451
1451
} \
1452
1452
} while (0)
1453
+
1454
+ static zend_result php_socket_get_chunk (zend_string * dst , const zend_string * src , size_t offset , size_t len ) {
1455
+ if (UNEXPECTED ((offset > SIZE_MAX - len ) || offset + len > ZSTR_LEN (src ))) {
1456
+ return FAILURE ;
1457
+ }
1458
+
1459
+ memcpy (ZSTR_VAL (dst ), ZSTR_VAL (src ) + offset , len );
1460
+ ZSTR_LEN (dst ) = len ;
1461
+ return SUCCESS ;
1462
+ }
1463
+
1453
1464
static zend_result php_socket_afpacket_add_tcp (unsigned char * ipdata , struct sockaddr_ll sll , char * ifrname , zend_string * recv_buf ,
1454
1465
size_t slen , zval * szpayload , zval * zpayload , zval * obj , zval * arg2 , zval * arg5 , zval * arg6 ) {
1455
1466
struct tcphdr a ;
@@ -1614,7 +1625,7 @@ PHP_FUNCTION(socket_recvfrom)
1614
1625
}
1615
1626
#endif
1616
1627
1617
- recv_buf = zend_string_alloc (arg3 + 1 , 0 );
1628
+ recv_buf = zend_string_alloc (arg3 + 1 , false );
1618
1629
1619
1630
switch (php_sock -> type ) {
1620
1631
case AF_UNIX :
@@ -1700,6 +1711,7 @@ PHP_FUNCTION(socket_recvfrom)
1700
1711
zend_argument_value_error (1 , "must be SOCK_RAW socket type" );
1701
1712
RETURN_THROWS ();
1702
1713
}
1714
+ zend_string * dst_buf ;
1703
1715
slen = sizeof (sll );
1704
1716
memset (& sll , 0 , sizeof (sll ));
1705
1717
sll .sll_family = AF_PACKET ;
@@ -1726,7 +1738,18 @@ PHP_FUNCTION(socket_recvfrom)
1726
1738
RETURN_FALSE ;
1727
1739
}
1728
1740
1729
- struct ethhdr * e = (struct ethhdr * )ZSTR_VAL (recv_buf );
1741
+ dst_buf = zend_string_alloc (arg3 , false);
1742
+
1743
+ if (php_socket_get_chunk (dst_buf , recv_buf , 0 , ETH_HLEN ) == FAILURE ) {
1744
+ zend_value_error ("invalid ethernet frame buffer length" );
1745
+ zend_string_efree (dst_buf );
1746
+ zend_string_efree (recv_buf );
1747
+ RETURN_THROWS ();
1748
+ }
1749
+
1750
+ struct ethhdr a ;
1751
+ memcpy (& a , ZSTR_VAL (dst_buf ), ETH_HLEN );
1752
+ struct ethhdr * e = & a ;
1730
1753
unsigned short protocol = ntohs (e -> h_proto );
1731
1754
unsigned char * payload ;
1732
1755
@@ -1739,7 +1762,13 @@ PHP_FUNCTION(socket_recvfrom)
1739
1762
1740
1763
switch (protocol ) {
1741
1764
case ETH_P_IP : {
1742
- payload = ((unsigned char * )e + ETH_HLEN );
1765
+ if (php_socket_get_chunk (dst_buf , recv_buf , ETH_HLEN , sizeof (struct iphdr )) == FAILURE ) {
1766
+ zend_value_error ("invalid ipv4 frame buffer length" );
1767
+ zend_string_efree (dst_buf );
1768
+ zend_string_efree (recv_buf );
1769
+ RETURN_THROWS ();
1770
+ }
1771
+ payload = ((unsigned char * )ZSTR_VAL (dst_buf ));
1743
1772
struct iphdr a ;
1744
1773
memcpy (& a , payload , sizeof (a ));
1745
1774
struct iphdr * ip = & a ;
@@ -1760,7 +1789,6 @@ PHP_FUNCTION(socket_recvfrom)
1760
1789
zend_value_error ("invalid transport header length" );
1761
1790
RETURN_THROWS ();
1762
1791
}
1763
- unsigned char * ipdata = payload + tlayer ;
1764
1792
struct in_addr s , d ;
1765
1793
s .s_addr = ip -> saddr ;
1766
1794
d .s_addr = ip -> daddr ;
@@ -1773,12 +1801,26 @@ PHP_FUNCTION(socket_recvfrom)
1773
1801
1774
1802
switch (ip -> protocol ) {
1775
1803
case IPPROTO_TCP : {
1804
+ if (php_socket_get_chunk (dst_buf , recv_buf , tlayer , sizeof (struct tcphdr )) == FAILURE ) {
1805
+ zend_value_error ("invalid ipv4 frame buffer length" );
1806
+ zend_string_efree (dst_buf );
1807
+ zend_string_efree (recv_buf );
1808
+ RETURN_THROWS ();
1809
+ }
1810
+ unsigned char * ipdata = (unsigned char * )ZSTR_VAL (dst_buf );
1776
1811
if (php_socket_afpacket_add_tcp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1777
1812
RETURN_THROWS ();
1778
1813
}
1779
1814
break ;
1780
1815
}
1781
1816
case IPPROTO_UDP : {
1817
+ if (php_socket_get_chunk (dst_buf , recv_buf , tlayer , sizeof (struct udphdr )) == FAILURE ) {
1818
+ zend_value_error ("invalid ipv4 frame buffer length" );
1819
+ zend_string_efree (dst_buf );
1820
+ zend_string_efree (recv_buf );
1821
+ RETURN_THROWS ();
1822
+ }
1823
+ unsigned char * ipdata = (unsigned char * )ZSTR_VAL (dst_buf );
1782
1824
if (php_socket_afpacket_add_udp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1783
1825
RETURN_THROWS ();
1784
1826
}
@@ -1788,6 +1830,7 @@ PHP_FUNCTION(socket_recvfrom)
1788
1830
zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("payload" ), & zpayload );
1789
1831
zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("rawPacket" ), ZSTR_VAL (recv_buf ));
1790
1832
zend_string_efree (recv_buf );
1833
+ zend_string_efree (dst_buf );
1791
1834
Z_DELREF (zpayload );
1792
1835
ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1793
1836
ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
@@ -1801,7 +1844,13 @@ PHP_FUNCTION(socket_recvfrom)
1801
1844
break ;
1802
1845
}
1803
1846
case ETH_P_IPV6 : {
1804
- payload = ((unsigned char * )e + ETH_HLEN );
1847
+ if (php_socket_get_chunk (dst_buf , recv_buf , ETH_HLEN , sizeof (struct iphdr )) == FAILURE ) {
1848
+ zend_value_error ("invalid ipv4 frame buffer length" );
1849
+ zend_string_efree (dst_buf );
1850
+ zend_string_efree (recv_buf );
1851
+ RETURN_THROWS ();
1852
+ }
1853
+ payload = ((unsigned char * )ZSTR_VAL (dst_buf ));
1805
1854
struct ipv6hdr a ;
1806
1855
memcpy (& a , payload , sizeof (a ));
1807
1856
struct ipv6hdr * ip = & a ;
@@ -1830,16 +1879,29 @@ PHP_FUNCTION(socket_recvfrom)
1830
1879
zend_update_property_long (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("headerSize" ), totalip );
1831
1880
zend_update_property_stringl (Z_OBJCE (zpayload ), Z_OBJ (zpayload ), ZEND_STRL ("rawPacket" ), (char * )payload , totalip );
1832
1881
unsigned char ipprotocol = ip -> nexthdr ;
1833
- unsigned char * ipdata = payload + sizeof (* ip );
1834
1882
1835
1883
switch (ipprotocol ) {
1836
1884
case IPPROTO_TCP : {
1885
+ if (php_socket_get_chunk (dst_buf , recv_buf , sizeof (* ip ), sizeof (struct tcphdr )) == FAILURE ) {
1886
+ zend_value_error ("invalid ipv4 frame buffer length" );
1887
+ zend_string_efree (dst_buf );
1888
+ zend_string_efree (recv_buf );
1889
+ RETURN_THROWS ();
1890
+ }
1891
+ unsigned char * ipdata = (unsigned char * )ZSTR_VAL (dst_buf );
1837
1892
if (php_socket_afpacket_add_tcp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1838
1893
RETURN_THROWS ();
1839
1894
}
1840
1895
break ;
1841
1896
}
1842
1897
case IPPROTO_UDP : {
1898
+ if (php_socket_get_chunk (dst_buf , recv_buf , sizeof (* ip ), sizeof (struct udphdr )) == FAILURE ) {
1899
+ zend_value_error ("invalid ipv4 frame buffer length" );
1900
+ zend_string_efree (dst_buf );
1901
+ zend_string_efree (recv_buf );
1902
+ RETURN_THROWS ();
1903
+ }
1904
+ unsigned char * ipdata = (unsigned char * )ZSTR_VAL (dst_buf );
1843
1905
if (php_socket_afpacket_add_udp (ipdata , sll , ifrname , recv_buf , slen , & szpayload , & zpayload , & obj , arg2 , arg5 , arg6 ) == FAILURE ) {
1844
1906
RETURN_THROWS ();
1845
1907
}
@@ -1850,6 +1912,7 @@ PHP_FUNCTION(socket_recvfrom)
1850
1912
zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("payload" ), & zpayload );
1851
1913
zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("rawPacket" ), ZSTR_VAL (recv_buf ));
1852
1914
zend_string_efree (recv_buf );
1915
+ zend_string_efree (dst_buf );
1853
1916
Z_DELREF (zpayload );
1854
1917
ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1855
1918
ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
@@ -1863,7 +1926,13 @@ PHP_FUNCTION(socket_recvfrom)
1863
1926
break ;
1864
1927
}
1865
1928
case ETH_P_LOOP : {
1866
- payload = ((unsigned char * )e + ETH_HLEN );
1929
+ if (php_socket_get_chunk (dst_buf , recv_buf , ETH_HLEN , ETH_HLEN ) == FAILURE ) {
1930
+ zend_value_error ("invalid ethernet frame buffer length" );
1931
+ zend_string_efree (dst_buf );
1932
+ zend_string_efree (recv_buf );
1933
+ RETURN_THROWS ();
1934
+ }
1935
+ payload = (unsigned char * )ZSTR_VAL (dst_buf );
1867
1936
struct ethhdr a ;
1868
1937
if ((char * )payload + sizeof (a ) < ZSTR_VAL (recv_buf ) + slen ) {
1869
1938
zend_string_efree (recv_buf );
@@ -1895,6 +1964,8 @@ PHP_FUNCTION(socket_recvfrom)
1895
1964
zend_update_property (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("payload" ), & zpayload );
1896
1965
zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("rawPacket" ), ZSTR_VAL (recv_buf ));
1897
1966
zend_string_efree (recv_buf );
1967
+ zend_string_efree (dst_buf );
1968
+
1898
1969
ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1899
1970
ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
1900
1971
@@ -1911,6 +1982,7 @@ PHP_FUNCTION(socket_recvfrom)
1911
1982
zend_update_property_string (Z_OBJCE (obj ), Z_OBJ (obj ), ZEND_STRL ("rawPacket" ), ZSTR_VAL (recv_buf ));
1912
1983
Z_DELREF (zpayload );
1913
1984
zend_string_efree (recv_buf );
1985
+ zend_string_free (dst_buf );
1914
1986
1915
1987
ZEND_TRY_ASSIGN_REF_VALUE (arg2 , & obj );
1916
1988
ZEND_TRY_ASSIGN_REF_STRING (arg5 , ifrname );
0 commit comments