summaryrefslogtreecommitdiffstats
path: root/net/ceph
diff options
context:
space:
mode:
authorJeff Layton <jlayton@kernel.org>2019-05-06 09:38:46 -0400
committerIlya Dryomov <idryomov@gmail.com>2019-05-07 13:43:05 -0400
commitcede185b1ba3118e1912385db4812a37d9e9b205 (patch)
treef5a68565273af192c4029845b087afd38c744b63 /net/ceph
parentb91a7bdca4439e286f26cdd6c15ed338e6a9fda2 (diff)
libceph: fix unaligned accesses in ceph_entity_addr handling
GCC9 is throwing a lot of warnings about unaligned access. This patch fixes some of them by changing most of the sockaddr handling functions to take a pointer to struct ceph_entity_addr instead of struct sockaddr_storage. The lower functions can then make copies or do unaligned accesses as needed. Signed-off-by: Jeff Layton <jlayton@kernel.org> Reviewed-by: Ilya Dryomov <idryomov@gmail.com> Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'net/ceph')
-rw-r--r--net/ceph/messenger.c77
1 files changed, 37 insertions, 40 deletions
diff --git a/net/ceph/messenger.c b/net/ceph/messenger.c
index 3083988ce729..3e0cc9808ae4 100644
--- a/net/ceph/messenger.c
+++ b/net/ceph/messenger.c
@@ -449,7 +449,7 @@ static void set_sock_callbacks(struct socket *sock,
449 */ 449 */
450static int ceph_tcp_connect(struct ceph_connection *con) 450static int ceph_tcp_connect(struct ceph_connection *con)
451{ 451{
452 struct sockaddr_storage *paddr = &con->peer_addr.in_addr; 452 struct sockaddr_storage ss = con->peer_addr.in_addr; /* align */
453 struct socket *sock; 453 struct socket *sock;
454 unsigned int noio_flag; 454 unsigned int noio_flag;
455 int ret; 455 int ret;
@@ -458,7 +458,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
458 458
459 /* sock_create_kern() allocates with GFP_KERNEL */ 459 /* sock_create_kern() allocates with GFP_KERNEL */
460 noio_flag = memalloc_noio_save(); 460 noio_flag = memalloc_noio_save();
461 ret = sock_create_kern(read_pnet(&con->msgr->net), paddr->ss_family, 461 ret = sock_create_kern(read_pnet(&con->msgr->net), ss.ss_family,
462 SOCK_STREAM, IPPROTO_TCP, &sock); 462 SOCK_STREAM, IPPROTO_TCP, &sock);
463 memalloc_noio_restore(noio_flag); 463 memalloc_noio_restore(noio_flag);
464 if (ret) 464 if (ret)
@@ -474,7 +474,7 @@ static int ceph_tcp_connect(struct ceph_connection *con)
474 dout("connect %s\n", ceph_pr_addr(&con->peer_addr.in_addr)); 474 dout("connect %s\n", ceph_pr_addr(&con->peer_addr.in_addr));
475 475
476 con_sock_state_connecting(con); 476 con_sock_state_connecting(con);
477 ret = sock->ops->connect(sock, (struct sockaddr *)paddr, sizeof(*paddr), 477 ret = sock->ops->connect(sock, (struct sockaddr *)&ss, sizeof(ss),
478 O_NONBLOCK); 478 O_NONBLOCK);
479 if (ret == -EINPROGRESS) { 479 if (ret == -EINPROGRESS) {
480 dout("connect %s EINPROGRESS sk_state = %u\n", 480 dout("connect %s EINPROGRESS sk_state = %u\n",
@@ -1795,14 +1795,15 @@ static int verify_hello(struct ceph_connection *con)
1795 return 0; 1795 return 0;
1796} 1796}
1797 1797
1798static bool addr_is_blank(struct sockaddr_storage *ss) 1798static bool addr_is_blank(struct ceph_entity_addr *addr)
1799{ 1799{
1800 struct in_addr *addr = &((struct sockaddr_in *)ss)->sin_addr; 1800 struct sockaddr_storage ss = addr->in_addr; /* align */
1801 struct in6_addr *addr6 = &((struct sockaddr_in6 *)ss)->sin6_addr; 1801 struct in_addr *addr4 = &((struct sockaddr_in *)&ss)->sin_addr;
1802 struct in6_addr *addr6 = &((struct sockaddr_in6 *)&ss)->sin6_addr;
1802 1803
1803 switch (ss->ss_family) { 1804 switch (ss.ss_family) {
1804 case AF_INET: 1805 case AF_INET:
1805 return addr->s_addr == htonl(INADDR_ANY); 1806 return addr4->s_addr == htonl(INADDR_ANY);
1806 case AF_INET6: 1807 case AF_INET6:
1807 return ipv6_addr_any(addr6); 1808 return ipv6_addr_any(addr6);
1808 default: 1809 default:
@@ -1810,25 +1811,25 @@ static bool addr_is_blank(struct sockaddr_storage *ss)
1810 } 1811 }
1811} 1812}
1812 1813
1813static int addr_port(struct sockaddr_storage *ss) 1814static int addr_port(struct ceph_entity_addr *addr)
1814{ 1815{
1815 switch (ss->ss_family) { 1816 switch (get_unaligned(&addr->in_addr.ss_family)) {
1816 case AF_INET: 1817 case AF_INET:
1817 return ntohs(((struct sockaddr_in *)ss)->sin_port); 1818 return ntohs(get_unaligned(&((struct sockaddr_in *)&addr->in_addr)->sin_port));
1818 case AF_INET6: 1819 case AF_INET6:
1819 return ntohs(((struct sockaddr_in6 *)ss)->sin6_port); 1820 return ntohs(get_unaligned(&((struct sockaddr_in6 *)&addr->in_addr)->sin6_port));
1820 } 1821 }
1821 return 0; 1822 return 0;
1822} 1823}
1823 1824
1824static void addr_set_port(struct sockaddr_storage *ss, int p) 1825static void addr_set_port(struct ceph_entity_addr *addr, int p)
1825{ 1826{
1826 switch (ss->ss_family) { 1827 switch (get_unaligned(&addr->in_addr.ss_family)) {
1827 case AF_INET: 1828 case AF_INET:
1828 ((struct sockaddr_in *)ss)->sin_port = htons(p); 1829 put_unaligned(htons(p), &((struct sockaddr_in *)&addr->in_addr)->sin_port);
1829 break; 1830 break;
1830 case AF_INET6: 1831 case AF_INET6:
1831 ((struct sockaddr_in6 *)ss)->sin6_port = htons(p); 1832 put_unaligned(htons(p), &((struct sockaddr_in6 *)&addr->in_addr)->sin6_port);
1832 break; 1833 break;
1833 } 1834 }
1834} 1835}
@@ -1836,21 +1837,18 @@ static void addr_set_port(struct sockaddr_storage *ss, int p)
1836/* 1837/*
1837 * Unlike other *_pton function semantics, zero indicates success. 1838 * Unlike other *_pton function semantics, zero indicates success.
1838 */ 1839 */
1839static int ceph_pton(const char *str, size_t len, struct sockaddr_storage *ss, 1840static int ceph_pton(const char *str, size_t len, struct ceph_entity_addr *addr,
1840 char delim, const char **ipend) 1841 char delim, const char **ipend)
1841{ 1842{
1842 struct sockaddr_in *in4 = (struct sockaddr_in *) ss; 1843 memset(&addr->in_addr, 0, sizeof(addr->in_addr));
1843 struct sockaddr_in6 *in6 = (struct sockaddr_in6 *) ss;
1844
1845 memset(ss, 0, sizeof(*ss));
1846 1844
1847 if (in4_pton(str, len, (u8 *)&in4->sin_addr.s_addr, delim, ipend)) { 1845 if (in4_pton(str, len, (u8 *)&((struct sockaddr_in *)&addr->in_addr)->sin_addr.s_addr, delim, ipend)) {
1848 ss->ss_family = AF_INET; 1846 put_unaligned(AF_INET, &addr->in_addr.ss_family);
1849 return 0; 1847 return 0;
1850 } 1848 }
1851 1849
1852 if (in6_pton(str, len, (u8 *)&in6->sin6_addr.s6_addr, delim, ipend)) { 1850 if (in6_pton(str, len, (u8 *)&((struct sockaddr_in6 *)&addr->in_addr)->sin6_addr.s6_addr, delim, ipend)) {
1853 ss->ss_family = AF_INET6; 1851 put_unaligned(AF_INET6, &addr->in_addr.ss_family);
1854 return 0; 1852 return 0;
1855 } 1853 }
1856 1854
@@ -1862,7 +1860,7 @@ static int ceph_pton(const char *str, size_t len, struct sockaddr_storage *ss,
1862 */ 1860 */
1863#ifdef CONFIG_CEPH_LIB_USE_DNS_RESOLVER 1861#ifdef CONFIG_CEPH_LIB_USE_DNS_RESOLVER
1864static int ceph_dns_resolve_name(const char *name, size_t namelen, 1862static int ceph_dns_resolve_name(const char *name, size_t namelen,
1865 struct sockaddr_storage *ss, char delim, const char **ipend) 1863 struct ceph_entity_addr *addr, char delim, const char **ipend)
1866{ 1864{
1867 const char *end, *delim_p; 1865 const char *end, *delim_p;
1868 char *colon_p, *ip_addr = NULL; 1866 char *colon_p, *ip_addr = NULL;
@@ -1891,7 +1889,7 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
1891 /* do dns_resolve upcall */ 1889 /* do dns_resolve upcall */
1892 ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL); 1890 ip_len = dns_query(NULL, name, end - name, NULL, &ip_addr, NULL);
1893 if (ip_len > 0) 1891 if (ip_len > 0)
1894 ret = ceph_pton(ip_addr, ip_len, ss, -1, NULL); 1892 ret = ceph_pton(ip_addr, ip_len, addr, -1, NULL);
1895 else 1893 else
1896 ret = -ESRCH; 1894 ret = -ESRCH;
1897 1895
@@ -1900,13 +1898,13 @@ static int ceph_dns_resolve_name(const char *name, size_t namelen,
1900 *ipend = end; 1898 *ipend = end;
1901 1899
1902 pr_info("resolve '%.*s' (ret=%d): %s\n", (int)(end - name), name, 1900 pr_info("resolve '%.*s' (ret=%d): %s\n", (int)(end - name), name,
1903 ret, ret ? "failed" : ceph_pr_addr(ss)); 1901 ret, ret ? "failed" : ceph_pr_addr(&addr->in_addr));
1904 1902
1905 return ret; 1903 return ret;
1906} 1904}
1907#else 1905#else
1908static inline int ceph_dns_resolve_name(const char *name, size_t namelen, 1906static inline int ceph_dns_resolve_name(const char *name, size_t namelen,
1909 struct sockaddr_storage *ss, char delim, const char **ipend) 1907 struct ceph_entity_addr *addr, char delim, const char **ipend)
1910{ 1908{
1911 return -EINVAL; 1909 return -EINVAL;
1912} 1910}
@@ -1917,13 +1915,13 @@ static inline int ceph_dns_resolve_name(const char *name, size_t namelen,
1917 * then try to extract a hostname to resolve using userspace DNS upcall. 1915 * then try to extract a hostname to resolve using userspace DNS upcall.
1918 */ 1916 */
1919static int ceph_parse_server_name(const char *name, size_t namelen, 1917static int ceph_parse_server_name(const char *name, size_t namelen,
1920 struct sockaddr_storage *ss, char delim, const char **ipend) 1918 struct ceph_entity_addr *addr, char delim, const char **ipend)
1921{ 1919{
1922 int ret; 1920 int ret;
1923 1921
1924 ret = ceph_pton(name, namelen, ss, delim, ipend); 1922 ret = ceph_pton(name, namelen, addr, delim, ipend);
1925 if (ret) 1923 if (ret)
1926 ret = ceph_dns_resolve_name(name, namelen, ss, delim, ipend); 1924 ret = ceph_dns_resolve_name(name, namelen, addr, delim, ipend);
1927 1925
1928 return ret; 1926 return ret;
1929} 1927}
@@ -1942,7 +1940,6 @@ int ceph_parse_ips(const char *c, const char *end,
1942 dout("parse_ips on '%.*s'\n", (int)(end-c), c); 1940 dout("parse_ips on '%.*s'\n", (int)(end-c), c);
1943 for (i = 0; i < max_count; i++) { 1941 for (i = 0; i < max_count; i++) {
1944 const char *ipend; 1942 const char *ipend;
1945 struct sockaddr_storage *ss = &addr[i].in_addr;
1946 int port; 1943 int port;
1947 char delim = ','; 1944 char delim = ',';
1948 1945
@@ -1951,7 +1948,7 @@ int ceph_parse_ips(const char *c, const char *end,
1951 p++; 1948 p++;
1952 } 1949 }
1953 1950
1954 ret = ceph_parse_server_name(p, end - p, ss, delim, &ipend); 1951 ret = ceph_parse_server_name(p, end - p, &addr[i], delim, &ipend);
1955 if (ret) 1952 if (ret)
1956 goto bad; 1953 goto bad;
1957 ret = -EINVAL; 1954 ret = -EINVAL;
@@ -1982,9 +1979,9 @@ int ceph_parse_ips(const char *c, const char *end,
1982 port = CEPH_MON_PORT; 1979 port = CEPH_MON_PORT;
1983 } 1980 }
1984 1981
1985 addr_set_port(ss, port); 1982 addr_set_port(&addr[i], port);
1986 1983
1987 dout("parse_ips got %s\n", ceph_pr_addr(ss)); 1984 dout("parse_ips got %s\n", ceph_pr_addr(&addr[i].in_addr));
1988 1985
1989 if (p == end) 1986 if (p == end)
1990 break; 1987 break;
@@ -2023,7 +2020,7 @@ static int process_banner(struct ceph_connection *con)
2023 */ 2020 */
2024 if (memcmp(&con->peer_addr, &con->actual_peer_addr, 2021 if (memcmp(&con->peer_addr, &con->actual_peer_addr,
2025 sizeof(con->peer_addr)) != 0 && 2022 sizeof(con->peer_addr)) != 0 &&
2026 !(addr_is_blank(&con->actual_peer_addr.in_addr) && 2023 !(addr_is_blank(&con->actual_peer_addr) &&
2027 con->actual_peer_addr.nonce == con->peer_addr.nonce)) { 2024 con->actual_peer_addr.nonce == con->peer_addr.nonce)) {
2028 pr_warn("wrong peer, want %s/%d, got %s/%d\n", 2025 pr_warn("wrong peer, want %s/%d, got %s/%d\n",
2029 ceph_pr_addr(&con->peer_addr.in_addr), 2026 ceph_pr_addr(&con->peer_addr.in_addr),
@@ -2037,13 +2034,13 @@ static int process_banner(struct ceph_connection *con)
2037 /* 2034 /*
2038 * did we learn our address? 2035 * did we learn our address?
2039 */ 2036 */
2040 if (addr_is_blank(&con->msgr->inst.addr.in_addr)) { 2037 if (addr_is_blank(&con->msgr->inst.addr)) {
2041 int port = addr_port(&con->msgr->inst.addr.in_addr); 2038 int port = addr_port(&con->msgr->inst.addr);
2042 2039
2043 memcpy(&con->msgr->inst.addr.in_addr, 2040 memcpy(&con->msgr->inst.addr.in_addr,
2044 &con->peer_addr_for_me.in_addr, 2041 &con->peer_addr_for_me.in_addr,
2045 sizeof(con->peer_addr_for_me.in_addr)); 2042 sizeof(con->peer_addr_for_me.in_addr));
2046 addr_set_port(&con->msgr->inst.addr.in_addr, port); 2043 addr_set_port(&con->msgr->inst.addr, port);
2047 encode_my_addr(con->msgr); 2044 encode_my_addr(con->msgr);
2048 dout("process_banner learned my addr is %s\n", 2045 dout("process_banner learned my addr is %s\n",
2049 ceph_pr_addr(&con->msgr->inst.addr.in_addr)); 2046 ceph_pr_addr(&con->msgr->inst.addr.in_addr));