summaryrefslogtreecommitdiff
path: root/net/atm
diff options
context:
space:
mode:
authorKuniyuki Iwashima <kuniyu@google.com>2025-07-04 06:23:52 +0000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2025-07-17 18:25:02 +0200
commit2fb37ab3226606cbfc9b2b6f9e301b0b735734c5 (patch)
tree48dbddf35d7abed6dccf72b588da199c805a88ae /net/atm
parenta4c5785feb979cd996a99cfaad8bf353b2e79301 (diff)
downloadlinux-2fb37ab3226606cbfc9b2b6f9e301b0b735734c5.tar.gz
linux-2fb37ab3226606cbfc9b2b6f9e301b0b735734c5.tar.bz2
linux-2fb37ab3226606cbfc9b2b6f9e301b0b735734c5.zip
atm: clip: Fix memory leak of struct clip_vcc.
[ Upstream commit 62dba28275a9a3104d4e33595c7b3328d4032d8d ] ioctl(ATMARP_MKIP) allocates struct clip_vcc and set it to vcc->user_back. The code assumes that vcc_destroy_socket() passes NULL skb to vcc->push() when the socket is close()d, and then clip_push() frees clip_vcc. However, ioctl(ATMARPD_CTRL) sets NULL to vcc->push() in atm_init_atmarp(), resulting in memory leak. Let's serialise two ioctl() by lock_sock() and check vcc->push() in atm_init_atmarp() to prevent memleak. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com> Reviewed-by: Simon Horman <horms@kernel.org> Link: https://patch.msgid.link/20250704062416.1613927-3-kuniyu@google.com Signed-off-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'net/atm')
-rw-r--r--net/atm/clip.c8
1 files changed, 8 insertions, 0 deletions
diff --git a/net/atm/clip.c b/net/atm/clip.c
index d5363ae5296a..8415ac280547 100644
--- a/net/atm/clip.c
+++ b/net/atm/clip.c
@@ -646,6 +646,9 @@ static struct atm_dev atmarpd_dev = {
static int atm_init_atmarp(struct atm_vcc *vcc)
{
+ if (vcc->push == clip_push)
+ return -EINVAL;
+
mutex_lock(&atmarpd_lock);
if (atmarpd) {
mutex_unlock(&atmarpd_lock);
@@ -670,6 +673,7 @@ static int atm_init_atmarp(struct atm_vcc *vcc)
static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
{
struct atm_vcc *vcc = ATM_SD(sock);
+ struct sock *sk = sock->sk;
int err = 0;
switch (cmd) {
@@ -690,14 +694,18 @@ static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
err = clip_create(arg);
break;
case ATMARPD_CTRL:
+ lock_sock(sk);
err = atm_init_atmarp(vcc);
if (!err) {
sock->state = SS_CONNECTED;
__module_get(THIS_MODULE);
}
+ release_sock(sk);
break;
case ATMARP_MKIP:
+ lock_sock(sk);
err = clip_mkip(vcc, arg);
+ release_sock(sk);
break;
case ATMARP_SETENTRY:
err = clip_setentry(vcc, (__force __be32)arg);