From 0e45dba29ce4c395b6e0dcfd3804d92593b8700c Mon Sep 17 00:00:00 2001 From: David Wen Date: Mon, 4 Nov 2019 16:29:28 +1100 Subject: [PATCH 1/2] 4.16 and 4.17 kernel panic fix In Linux kernel 4.16 and 4.17, the function i2c_bit_add_bus attempts to set the clock and data signals on the i2c bus. However, the exanic pointer was not filled in until after the bus was registered, resulting in NULL pointer dereference. This commit fills the exanic pointer into the i2c adapter data before registering the bus to work around the issue. --- modules/exanic/exanic-i2c.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/exanic/exanic-i2c.c b/modules/exanic/exanic-i2c.c index 2bc1bfb..3bd1641 100644 --- a/modules/exanic/exanic-i2c.c +++ b/modules/exanic/exanic-i2c.c @@ -550,6 +550,7 @@ exanic_i2c_bus_register(struct exanic *exanic, int port, data->bit_data.udelay = 20; data->bit_data.timeout = HZ; data->bit_data.data = data; + data->exanic = exanic; /* fill in i2c adapter */ adap->owner = THIS_MODULE; @@ -564,8 +565,6 @@ exanic_i2c_bus_register(struct exanic *exanic, int port, data->xfer_wrapped = adap->algo->master_xfer; exanic_i2c_bit_algo.functionality = adap->algo->functionality; adap->algo = &exanic_i2c_bit_algo; - - data->exanic = exanic; /* add to bus list */ list_add_tail(&data->link, &exanic->i2c_list); From 90d43275f5700d8b0244901a5fec0ac789286c7a Mon Sep 17 00:00:00 2001 From: Lian Xuezhi Date: Tue, 12 Nov 2019 18:16:28 +0800 Subject: [PATCH 2/2] getpeername should check if tcp connection has been fully established --- libs/exasock/exanic.c | 8 ++++++++ libs/exasock/exanic.h | 1 + libs/exasock/socket/socket.c | 6 +++++- libs/exasock/tcp.h | 8 ++++++++ 4 files changed, 22 insertions(+), 1 deletion(-) diff --git a/libs/exasock/exanic.c b/libs/exasock/exanic.c index 234cf04..8bf8567 100644 --- a/libs/exasock/exanic.c +++ b/libs/exasock/exanic.c @@ -1529,6 +1529,14 @@ exanic_tcp_connecting(struct exa_socket * restrict sock) return exa_tcp_connecting(&ctx->tcp); } +bool +exanic_tcp_established(struct exa_socket * restrict sock) +{ + struct exanic_tcp * restrict ctx = sock->ctx.tcp; + + return exa_tcp_established(&ctx->tcp); +} + bool exanic_tcp_listening(struct exa_socket * restrict sock) { diff --git a/libs/exasock/exanic.h b/libs/exasock/exanic.h index 117268a..0ee78bf 100644 --- a/libs/exasock/exanic.h +++ b/libs/exasock/exanic.h @@ -50,6 +50,7 @@ void exanic_tcp_connect(struct exa_socket * restrict sock, void exanic_tcp_shutdown_write(struct exa_socket * restrict sock); void exanic_tcp_reset(struct exa_socket * restrict sock); bool exanic_tcp_connecting(struct exa_socket * restrict sock); +bool exanic_tcp_established(struct exa_socket * restrict sock); bool exanic_tcp_listening(struct exa_socket * restrict sock); bool exanic_tcp_writeable(struct exa_socket * restrict sock); bool exanic_tcp_write_closed(struct exa_socket *sock); diff --git a/libs/exasock/socket/socket.c b/libs/exasock/socket/socket.c index 0f1ffb6..801bd4b 100644 --- a/libs/exasock/socket/socket.c +++ b/libs/exasock/socket/socket.c @@ -1199,6 +1199,7 @@ int getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { struct exa_socket * restrict sock = exa_socket_get(sockfd); + bool connected = false; int ret; TRACE_CALL("getpeername"); @@ -1209,7 +1210,10 @@ getpeername(int sockfd, struct sockaddr *addr, socklen_t *addrlen) { exa_read_lock(&sock->lock); - if (!sock->connected) + connected = sock->connected; + if (SOCK_STREAM == sock->type) + connected = exanic_tcp_established(sock); + if (!connected) { errno = ENOTCONN; ret = -1; diff --git a/libs/exasock/tcp.h b/libs/exasock/tcp.h index b07f217..97be50d 100644 --- a/libs/exasock/tcp.h +++ b/libs/exasock/tcp.h @@ -261,6 +261,14 @@ exa_tcp_connecting(struct exa_tcp_conn * restrict ctx) state->state == EXA_TCP_SYN_RCVD; } +static inline bool +exa_tcp_established(struct exa_tcp_conn * restrict ctx) +{ + struct exa_tcp_state * restrict state = &ctx->state->p.tcp; + + return EXA_TCP_ESTABLISHED == state->state; +} + /* Return true if the write side of the connection has closed */ static inline bool exa_tcp_write_closed(struct exa_tcp_conn * restrict ctx)