From: Sasha Levin <sashal@kernel.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: Eric Biggers <ebiggers@google.com>,
Jakub Kicinski <jakub.kicinski@netronome.com>,
Sasha Levin <sashal@kernel.org>,
netdev@vger.kernel.org
Subject: [PATCH AUTOSEL 4.14 314/371] llc: fix another potential sk_buff leak in llc_ui_sendmsg()
Date: Thu, 16 Jan 2020 12:23:06 -0500 [thread overview]
Message-ID: <20200116172403.18149-257-sashal@kernel.org> (raw)
In-Reply-To: <20200116172403.18149-1-sashal@kernel.org>
From: Eric Biggers <ebiggers@google.com>
[ Upstream commit fc8d5db10cbe1338a52ebc74e7feab9276721774 ]
All callers of llc_conn_state_process() except llc_build_and_send_pkt()
(via llc_ui_sendmsg() -> llc_ui_send_data()) assume that it always
consumes a reference to the skb. Fix this caller to do the same.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Biggers <ebiggers@google.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/llc/af_llc.c | 34 ++++++++++++++++++++--------------
net/llc/llc_conn.c | 2 ++
net/llc/llc_if.c | 12 ++++++++----
3 files changed, 30 insertions(+), 18 deletions(-)
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c
index 2e472d5c3ea4..d552e8819713 100644
--- a/net/llc/af_llc.c
+++ b/net/llc/af_llc.c
@@ -113,22 +113,26 @@ static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr)
*
* Send data via reliable llc2 connection.
* Returns 0 upon success, non-zero if action did not succeed.
+ *
+ * This function always consumes a reference to the skb.
*/
static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock)
{
struct llc_sock* llc = llc_sk(sk);
- int rc = 0;
if (unlikely(llc_data_accept_state(llc->state) ||
llc->remote_busy_flag ||
llc->p_flag)) {
long timeout = sock_sndtimeo(sk, noblock);
+ int rc;
rc = llc_ui_wait_for_busy_core(sk, timeout);
+ if (rc) {
+ kfree_skb(skb);
+ return rc;
+ }
}
- if (unlikely(!rc))
- rc = llc_build_and_send_pkt(sk, skb);
- return rc;
+ return llc_build_and_send_pkt(sk, skb);
}
static void llc_ui_sk_init(struct socket *sock, struct sock *sk)
@@ -900,7 +904,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
DECLARE_SOCKADDR(struct sockaddr_llc *, addr, msg->msg_name);
int flags = msg->msg_flags;
int noblock = flags & MSG_DONTWAIT;
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
size_t size = 0;
int rc = -EINVAL, copied = 0, hdrlen;
@@ -909,10 +913,10 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
lock_sock(sk);
if (addr) {
if (msg->msg_namelen < sizeof(*addr))
- goto release;
+ goto out;
} else {
if (llc_ui_addr_null(&llc->addr))
- goto release;
+ goto out;
addr = &llc->addr;
}
/* must bind connection to sap if user hasn't done it. */
@@ -920,7 +924,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
/* bind to sap with null dev, exclusive. */
rc = llc_ui_autobind(sock, addr);
if (rc)
- goto release;
+ goto out;
}
hdrlen = llc->dev->hard_header_len + llc_ui_header_len(sk, addr);
size = hdrlen + len;
@@ -929,12 +933,12 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
copied = size - hdrlen;
rc = -EINVAL;
if (copied < 0)
- goto release;
+ goto out;
release_sock(sk);
skb = sock_alloc_send_skb(sk, size, noblock, &rc);
lock_sock(sk);
if (!skb)
- goto release;
+ goto out;
skb->dev = llc->dev;
skb->protocol = llc_proto_type(addr->sllc_arphrd);
skb_reserve(skb, hdrlen);
@@ -944,29 +948,31 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, size_t len)
if (sk->sk_type == SOCK_DGRAM || addr->sllc_ua) {
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
+ skb = NULL;
goto out;
}
if (addr->sllc_test) {
llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
+ skb = NULL;
goto out;
}
if (addr->sllc_xid) {
llc_build_and_send_xid_pkt(llc->sap, skb, addr->sllc_mac,
addr->sllc_sap);
+ skb = NULL;
goto out;
}
rc = -ENOPROTOOPT;
if (!(sk->sk_type == SOCK_STREAM && !addr->sllc_ua))
goto out;
rc = llc_ui_send_data(sk, skb, noblock);
+ skb = NULL;
out:
- if (rc) {
- kfree_skb(skb);
-release:
+ kfree_skb(skb);
+ if (rc)
dprintk("%s: failed sending from %02X to %02X: %d\n",
__func__, llc->laddr.lsap, llc->daddr.lsap, rc);
- }
release_sock(sk);
return rc ? : copied;
}
diff --git a/net/llc/llc_conn.c b/net/llc/llc_conn.c
index 444c13e752a0..7340f23e16de 100644
--- a/net/llc/llc_conn.c
+++ b/net/llc/llc_conn.c
@@ -55,6 +55,8 @@ int sysctl_llc2_busy_timeout = LLC2_BUSY_TIME * HZ;
* (executing it's actions and changing state), upper layer will be
* indicated or confirmed, if needed. Returns 0 for success, 1 for
* failure. The socket lock has to be held before calling this function.
+ *
+ * This function always consumes a reference to the skb.
*/
int llc_conn_state_process(struct sock *sk, struct sk_buff *skb)
{
diff --git a/net/llc/llc_if.c b/net/llc/llc_if.c
index 6daf391b3e84..fc4d2bd8816f 100644
--- a/net/llc/llc_if.c
+++ b/net/llc/llc_if.c
@@ -38,6 +38,8 @@
* closed and -EBUSY when sending data is not permitted in this state or
* LLC has send an I pdu with p bit set to 1 and is waiting for it's
* response.
+ *
+ * This function always consumes a reference to the skb.
*/
int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
{
@@ -46,20 +48,22 @@ int llc_build_and_send_pkt(struct sock *sk, struct sk_buff *skb)
struct llc_sock *llc = llc_sk(sk);
if (unlikely(llc->state == LLC_CONN_STATE_ADM))
- goto out;
+ goto out_free;
rc = -EBUSY;
if (unlikely(llc_data_accept_state(llc->state) || /* data_conn_refuse */
llc->p_flag)) {
llc->failed_data_req = 1;
- goto out;
+ goto out_free;
}
ev = llc_conn_ev(skb);
ev->type = LLC_CONN_EV_TYPE_PRIM;
ev->prim = LLC_DATA_PRIM;
ev->prim_type = LLC_PRIM_TYPE_REQ;
skb->dev = llc->dev;
- rc = llc_conn_state_process(sk, skb);
-out:
+ return llc_conn_state_process(sk, skb);
+
+out_free:
+ kfree_skb(skb);
return rc;
}
--
2.20.1
next prev parent reply other threads:[~2020-01-16 18:14 UTC|newest]
Thread overview: 71+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20200116172403.18149-1-sashal@kernel.org>
2020-01-16 17:18 ` [PATCH AUTOSEL 4.14 067/371] iwlwifi: mvm: avoid possible access out of array Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 068/371] net/mlx5: Take lock with IRQs disabled to avoid deadlock Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 069/371] iwlwifi: mvm: fix A-MPDU reference assignment Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 080/371] iwlwifi: mvm: fix RSS config command Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 084/371] net: phy: fixed_phy: Fix fixed_phy not checking GPIO Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 110/371] net: dsa: qca8k: Enable delay for RGMII_ID mode Sasha Levin
2020-01-16 17:19 ` [PATCH AUTOSEL 4.14 126/371] netfilter: nft_set_hash: fix lookups with fixed size hash on big endian Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 128/371] net: aquantia: fixed instack structure overflow Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 135/371] net: sh_eth: fix a missing check of of_get_phy_mode Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 143/371] tipc: tipc clang warning Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 154/371] dccp: Fix memleak in __feat_register_sp Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 157/371] ehea: Fix a copy-paste err in ehea_init_port_res Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 161/371] net: hns3: fix for vport->bw_limit overflow problem Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 164/371] tipc: set sysctl_tipc_rmem and named_timeout right range Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 169/371] 6lowpan: Off by one handling ->nexthdr Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 176/371] packet: in recvmsg msg_name return at least sizeof sockaddr_ll Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 182/371] net: ena: fix swapped parameters when calling ena_com_indirect_table_fill_entry Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 183/371] net: ena: fix: Free napi resources when ena_up() fails Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 184/371] net: ena: fix incorrect test of supported hash function Sasha Levin
2020-01-16 17:20 ` [PATCH AUTOSEL 4.14 185/371] net: ena: fix ena_com_fill_hash_function() implementation Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 192/371] l2tp: Fix possible NULL pointer dereference Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 197/371] netfilter: ebtables: CONFIG_COMPAT: reject trailing data after last rule Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 220/371] inet: frags: call inet_frags_fini() after unregister_pernet_subsys() Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 221/371] netvsc: unshare skb in VF rx handler Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 225/371] mpls: fix warning with multi-label encap Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 227/371] qed: iWARP - Use READ_ONCE and smp_store_release to access ep->state Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 231/371] net: netem: fix backlog accounting for corrupted GSO frames Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 232/371] net/af_iucv: always register net_device notifier Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 241/371] bnxt_en: Fix ethtool selftest crash under error conditions Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 244/371] rxrpc: Fix uninitialized error code in rxrpc_send_data_packet() Sasha Levin
2020-01-16 17:21 ` [PATCH AUTOSEL 4.14 247/371] net: pasemi: fix an use-after-free in pasemi_mac_phy_init() Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 251/371] libertas_tf: Use correct channel range in lbtf_geo_init Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 252/371] qed: reduce maximum stack frame size Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 258/371] tipc: reduce risk of wakeup queue starvation Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 261/371] net/mlx5: Fix mlx5_ifc_query_lag_out_bits Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 268/371] net/rds: Add a few missing rds_stat_names entries Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 269/371] bnxt_en: Fix handling FRAG_ERR when NVM_INSTALL_UPDATE cmd fails Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 273/371] mac80211: minstrel_ht: fix per-group max throughput rate initialization Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 287/371] ath9k: dynack: fix possible deadlock in ath_dynack_node_{de}init Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 289/371] net: sonic: return NETDEV_TX_OK if failed to map buffer Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 295/371] ixgbe: sync the first fragment unconditionally Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 297/371] net: sonic: replace dev_kfree_skb in sonic_send_packet Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 299/371] ath10k: adjust skb length in ath10k_sdio_mbox_rx_packet Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 301/371] net/rds: Fix 'ib_evt_handler_call' element in 'rds_ib_stat_names' Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 303/371] net: aquantia: Fix aq_vec_isr_legacy() return value Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 304/371] net: hisilicon: Fix signedness bug in hix5hd2_dev_probe() Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 305/371] net: broadcom/bcmsysport: Fix signedness in bcm_sysport_probe() Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 306/371] net: stmmac: dwmac-meson8b: Fix signedness bug in probe Sasha Levin
2020-01-16 17:22 ` [PATCH AUTOSEL 4.14 307/371] net: axienet: fix a " Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 308/371] of: mdio: Fix a signedness bug in of_phy_get_and_connect() Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 309/371] net: ethernet: stmmac: Fix signedness bug in ipq806x_gmac_of_parse() Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 310/371] ipv6: Handle race in addrconf_dad_work Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 312/371] net: stmmac: gmac4+: Not all Unicast addresses may be available Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 313/371] mac80211: accept deauth frames in IBSS mode Sasha Levin
2020-01-16 17:23 ` Sasha Levin [this message]
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 315/371] llc: fix sk_buff refcounting in llc_conn_state_process() Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 316/371] net: stmmac: fix length of PTP clock's name string Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 317/371] act_mirred: Fix mirred_init_module error handling Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 318/371] net: avoid possible false sharing in sk_leave_memory_pressure() Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 319/371] net: add {READ|WRITE}_ONCE() annotations on ->rskq_accept_head Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 320/371] tcp: annotate lockless access to tcp_memory_pressure Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 324/371] net: netem: fix error path for corrupted GSO frames Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 325/371] net: netem: correct the parent's backlog when corrupted packet was dropped Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 326/371] net: qca_spi: Move reset_count to struct qcaspi Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 329/371] mt7601u: fix bbp version check in mt7601u_wait_bbp_ready Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 333/371] cw1200: Fix a signedness bug in cw1200_load_firmware() Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 338/371] rtlwifi: Remove unnecessary NULL check in rtl_regd_init Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 345/371] hv_netvsc: flag software created hash value Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 346/371] net: neigh: use long type to store jiffies delta Sasha Levin
2020-01-16 17:23 ` [PATCH AUTOSEL 4.14 349/371] packet: fix data-race in fanout_flow_is_huge() Sasha Levin
2020-01-16 17:24 ` [PATCH AUTOSEL 4.14 368/371] tipc: fix wrong timeout input for tipc_wait_for_cond() Sasha Levin
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20200116172403.18149-257-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=ebiggers@google.com \
--cc=jakub.kicinski@netronome.com \
--cc=linux-kernel@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=stable@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).