Hi Dmitry, Thank you for the patch! Perhaps something to improve: [auto build test WARNING on bf682942cd26ce9cd5e87f73ae099b383041e782] url: https://github.com/intel-lab-lkp/linux/commits/Dmitry-Safonov/net-tcp-Add-TCP-AO-support/20220924-042311 base: bf682942cd26ce9cd5e87f73ae099b383041e782 config: um-x86_64_defconfig compiler: gcc-11 (Debian 11.3.0-5) 11.3.0 reproduce (this is a W=1 build): # https://github.com/intel-lab-lkp/linux/commit/464de48068a05d5b8690ca346f382b74914e5ce3 git remote add linux-review https://github.com/intel-lab-lkp/linux git fetch --no-tags linux-review Dmitry-Safonov/net-tcp-Add-TCP-AO-support/20220924-042311 git checkout 464de48068a05d5b8690ca346f382b74914e5ce3 # save the config file mkdir build_dir && cp config build_dir/.config make W=1 O=build_dir ARCH=um SUBARCH=x86_64 SHELL=/bin/bash net/ipv4/ If you fix the issue, kindly add following tag where applicable | Reported-by: kernel test robot All warnings (new ones prefixed by >>): net/ipv4/tcp_ao.c:113:20: warning: no previous prototype for 'tcp_ao_do_lookup_keyid' [-Wmissing-prototypes] 113 | struct tcp_ao_key *tcp_ao_do_lookup_keyid(struct tcp_ao_info *ao, | ^~~~~~~~~~~~~~~~~~~~~~ net/ipv4/tcp_ao.c:270:20: warning: no previous prototype for 'tcp_ao_copy_key' [-Wmissing-prototypes] 270 | struct tcp_ao_key *tcp_ao_copy_key(struct sock *sk, struct tcp_ao_key *key) | ^~~~~~~~~~~~~~~ >> net/ipv4/tcp_ao.c:1778:5: warning: no previous prototype for 'tcp_ao_copy_mkts_to_user' [-Wmissing-prototypes] 1778 | int tcp_ao_copy_mkts_to_user(struct tcp_ao_info *ao_info, | ^~~~~~~~~~~~~~~~~~~~~~~~ vim +/tcp_ao_copy_mkts_to_user +1778 net/ipv4/tcp_ao.c 1742 1743 /* tcp_ao_copy_mkts_to_user(ao_info, optval, optlen) 1744 * 1745 * @ao_info: struct tcp_ao_info on the socket that 1746 * socket getsockopt(TCP_AO_GET) is executed on 1747 * @optval: pointer to array of tcp_ao_getsockopt structures in user space. 1748 * Must be != NULL. 1749 * @optlen: pointer to size of tcp_ao_getsockopt structure. 1750 * Must be != NULL. 1751 * 1752 * Return value: 0 on success, a negative error number otherwise. 1753 * 1754 * optval points to an array of tcp_ao_getsockopt structures in user space. 1755 * optval[0] is used as both input and output to getsockopt. It determines 1756 * which keys are returned by the kernel. 1757 * optval[0].nkeys is the size of the array in user space. On return it contains 1758 * the number of keys matching the search criteria. 1759 * If TCP_AO_GET_ALL is set in "flags", then all keys in the socket are 1760 * returned, otherwise only keys matching 1761 * in optval[0] are returned. 1762 * optlen is also used as both input and output. The user provides the size 1763 * of struct tcp_ao_getsockopt in user space, and the kernel returns the size 1764 * of the structure in kernel space. 1765 * The size of struct tcp_ao_getsockopt may differ between user and kernel. 1766 * There are three cases to consider: 1767 * * If usize == ksize, then keys are copied verbatim. 1768 * * If usize < ksize, then the userspace has passed an old struct to a 1769 * newer kernel. The rest of the trailing bytes in optval[0] 1770 * (ksize - usize) are interpreted as 0 by the kernel. 1771 * * If usize > ksize, then the userspace has passed a new struct to an 1772 * older kernel. The trailing bytes unknown to the kernel (usize - ksize) 1773 * are checked to ensure they are zeroed, otherwise -E2BIG is returned. 1774 * On return the kernel fills in min(usize, ksize) in each entry of the array. 1775 * The layout of the fields in the user and kernel structures is expected to 1776 * be the same (including in the 32bit vs 64bit case). 1777 */ > 1778 int tcp_ao_copy_mkts_to_user(struct tcp_ao_info *ao_info, 1779 char __user *optval, int __user *optlen) 1780 { 1781 struct tcp_ao_getsockopt opt_in; 1782 struct tcp_ao_getsockopt opt_out; 1783 struct tcp_ao_getsockopt __user *optval_in; 1784 int user_len; 1785 unsigned int max_keys; /* maximum number of keys to copy to user */ 1786 u32 copied_keys; /* keys copied to user so far */ 1787 int matched_keys; /* keys from ao_info matched so far */ 1788 int bytes_to_write; /* number of bytes to write to user level */ 1789 struct tcp_ao_key *key; 1790 struct sockaddr_in *sin; /* (struct sockaddr_in *)&opt_in.addr */ 1791 struct sockaddr_in6 *sin6; /* (struct sockaddr_in6 *)&opt_in.addr */ 1792 struct in6_addr *addr6; /* &sin6->sin6_addr */ 1793 __kernel_sa_family_t ss_family; 1794 union tcp_ao_addr *addr; 1795 int optlen_out; 1796 u8 prefix_in; 1797 u16 port = 0; 1798 bool copy_all, copy_current, copy_next; 1799 int err; 1800 1801 if (get_user(user_len, optlen)) 1802 return -EFAULT; 1803 1804 if (user_len <= 0) 1805 return -EINVAL; 1806 1807 memset(&opt_in, 0, sizeof(struct tcp_ao_getsockopt)); 1808 err = copy_struct_from_user(&opt_in, sizeof(struct tcp_ao_getsockopt), 1809 optval, user_len); 1810 if (err < 0) 1811 return err; 1812 1813 optval_in = (struct tcp_ao_getsockopt __user *)optval; 1814 ss_family = opt_in.addr.ss_family; 1815 1816 BUILD_BUG_ON(TCP_AO_GET_ALL & (TCP_AO_GET_CURR | TCP_AO_GET_NEXT)); 1817 if (opt_in.flags & ~TCP_AO_GETF_VALID) 1818 return -EINVAL; 1819 1820 max_keys = opt_in.nkeys; 1821 copy_all = !!(opt_in.flags & TCP_AO_GET_ALL); 1822 copy_current = !!(opt_in.flags & TCP_AO_GET_CURR); 1823 copy_next = !!(opt_in.flags & TCP_AO_GET_NEXT); 1824 1825 if (!(copy_all || copy_current || copy_next)) { 1826 prefix_in = opt_in.prefix; 1827 1828 switch (ss_family) { 1829 case AF_INET: { 1830 sin = (struct sockaddr_in *)&opt_in.addr; 1831 port = sin->sin_port; 1832 addr = (union tcp_ao_addr *)&sin->sin_addr; 1833 1834 if (prefix_in > 32) 1835 return -EINVAL; 1836 1837 if (sin->sin_addr.s_addr == INADDR_ANY && 1838 prefix_in != 0) 1839 return -EINVAL; 1840 1841 break; 1842 } 1843 case AF_INET6: { 1844 sin6 = (struct sockaddr_in6 *)&opt_in.addr; 1845 addr = (union tcp_ao_addr *)&sin6->sin6_addr; 1846 addr6 = &sin6->sin6_addr; 1847 port = sin6->sin6_port; 1848 1849 if (prefix_in != 0) { 1850 if (ipv6_addr_v4mapped(addr6)) { 1851 __be32 addr4 = addr6->s6_addr32[3]; 1852 1853 if (prefix_in > 32 || 1854 addr4 == INADDR_ANY) 1855 return -EINVAL; 1856 } else { 1857 if (ipv6_addr_any(addr6) || 1858 prefix_in > 128) 1859 return -EINVAL; 1860 } 1861 } else if (!ipv6_addr_any(addr6)) { 1862 return -EINVAL; 1863 } 1864 1865 break; 1866 } 1867 default: 1868 return -EINVAL; 1869 } 1870 } 1871 1872 bytes_to_write = min(user_len, (int)sizeof(struct tcp_ao_getsockopt)); 1873 copied_keys = 0; 1874 matched_keys = 0; 1875 1876 hlist_for_each_entry_rcu(key, &ao_info->head, node) { 1877 if (copy_all) 1878 goto match; 1879 1880 if (copy_current || copy_next) { 1881 if (copy_current && key == ao_info->current_key) 1882 goto match; 1883 if (copy_next && key == ao_info->rnext_key) 1884 goto match; 1885 continue; 1886 } 1887 1888 if (tcp_ao_key_cmp(key, addr, opt_in.prefix, 1889 opt_in.addr.ss_family, 1890 opt_in.sndid, opt_in.rcvid, port) != 0) 1891 continue; 1892 match: 1893 matched_keys++; 1894 if (copied_keys >= max_keys) 1895 continue; 1896 1897 memset(&opt_out, 0, sizeof(struct tcp_ao_getsockopt)); 1898 1899 if (key->family == AF_INET) { 1900 struct sockaddr_in *sin_out = (struct sockaddr_in *)&opt_out.addr; 1901 1902 sin_out->sin_family = key->family; 1903 sin_out->sin_port = ntohs(key->port); 1904 memcpy(&sin_out->sin_addr, &key->addr, sizeof(struct in_addr)); 1905 } else { 1906 struct sockaddr_in6 *sin6_out = (struct sockaddr_in6 *)&opt_out.addr; 1907 1908 sin6_out->sin6_family = key->family; 1909 sin6_out->sin6_port = ntohs(key->port); 1910 memcpy(&sin6_out->sin6_addr, &key->addr, sizeof(struct in6_addr)); 1911 } 1912 opt_out.sndid = key->sndid; 1913 opt_out.rcvid = key->rcvid; 1914 opt_out.prefix = key->prefixlen; 1915 opt_out.keyflags = key->keyflags; 1916 opt_out.flags = 0; 1917 if (key == ao_info->current_key) 1918 opt_out.flags |= TCP_AO_GET_CURR; 1919 if (key == ao_info->rnext_key) 1920 opt_out.flags |= TCP_AO_GET_NEXT; 1921 opt_out.nkeys = 0; 1922 opt_out.maclen = key->maclen; 1923 opt_out.keylen = key->keylen; 1924 memcpy(&opt_out.key, key->key, key->keylen); 1925 crypto_pool_algo(key->crypto_pool_id, opt_out.alg_name, 64); 1926 1927 /* Copy key to user */ 1928 if (copy_to_user(optval, &opt_out, bytes_to_write)) 1929 return -EFAULT; 1930 optval += user_len; 1931 copied_keys++; 1932 } 1933 1934 optlen_out = (int)sizeof(struct tcp_ao_getsockopt); 1935 if (copy_to_user(optlen, &optlen_out, sizeof(int))) 1936 return -EFAULT; 1937 1938 if (copy_to_user(&optval_in->nkeys, &matched_keys, sizeof(u32))) 1939 return -EFAULT; 1940 1941 return 0; 1942 } 1943 -- 0-DAY CI Kernel Test Service https://01.org/lkp