未验证 提交 d636f566 编写于 作者: O openeuler-ci-bot 提交者: Gitee

!1629 can: raw: fix receiver memory leak

Merge Pull Request from: @ci-robot 
 
PR sync from: Ziyang Xuan <william.xuanziyang@huawei.com>
https://mailweb.openeuler.org/hyperkitty/list/kernel@openeuler.org/message/PN6CJX7CQ6YCEZFFWSQPDTGBGIIF7PGE/ 
Backport can/raw receiver memory leak fix commits.

Eric Dumazet (1):
  can: raw: fix lockdep issue in raw_release()

Ziyang Xuan (1):
  can: raw: fix receiver memory leak


-- 
2.25.1
 
https://gitee.com/openeuler/kernel/issues/I7PM10 
 
Link:https://gitee.com/openeuler/kernel/pulls/1629 

Reviewed-by: Yue Haibing <yuehaibing@huawei.com> 
Signed-off-by: Liu YongQiang <liuyongqiang13@huawei.com> 
......@@ -84,6 +84,7 @@ struct raw_sock {
struct sock sk;
int bound;
int ifindex;
struct net_device *dev;
struct list_head notifier;
int loopback;
int recv_own_msgs;
......@@ -278,7 +279,7 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
if (!net_eq(dev_net(dev), sock_net(sk)))
return;
if (ro->ifindex != dev->ifindex)
if (ro->dev != dev)
return;
switch (msg) {
......@@ -293,8 +294,9 @@ static void raw_notify(struct raw_sock *ro, unsigned long msg,
kfree(ro->filter);
ro->ifindex = 0;
ro->bound = 0;
ro->count = 0;
ro->bound = 0;
ro->dev = NULL;
ro->count = 0;
release_sock(sk);
sk->sk_err = ENODEV;
......@@ -339,6 +341,7 @@ static int raw_init(struct sock *sk)
ro->bound = 0;
ro->ifindex = 0;
ro->dev = NULL;
/* set default filter to single entry dfilter */
ro->dfilter.can_id = 0;
......@@ -384,19 +387,14 @@ static int raw_release(struct socket *sock)
list_del(&ro->notifier);
spin_unlock(&raw_notifier_lock);
rtnl_lock();
lock_sock(sk);
/* remove current filters & unregister */
if (ro->bound) {
if (ro->ifindex) {
struct net_device *dev;
dev = dev_get_by_index(sock_net(sk), ro->ifindex);
if (dev) {
raw_disable_allfilters(dev_net(dev), dev, sk);
dev_put(dev);
}
} else
if (ro->dev)
raw_disable_allfilters(dev_net(ro->dev), ro->dev, sk);
else
raw_disable_allfilters(sock_net(sk), NULL, sk);
}
......@@ -404,14 +402,17 @@ static int raw_release(struct socket *sock)
kfree(ro->filter);
ro->ifindex = 0;
ro->bound = 0;
ro->count = 0;
ro->bound = 0;
ro->dev = NULL;
ro->count = 0;
free_percpu(ro->uniq);
sock_orphan(sk);
sock->sk = NULL;
release_sock(sk);
rtnl_unlock();
sock_put(sk);
return 0;
......@@ -422,6 +423,7 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
struct sockaddr_can *addr = (struct sockaddr_can *)uaddr;
struct sock *sk = sock->sk;
struct raw_sock *ro = raw_sk(sk);
struct net_device *dev = NULL;
int ifindex;
int err = 0;
int notify_enetdown = 0;
......@@ -431,14 +433,13 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
if (addr->can_family != AF_CAN)
return -EINVAL;
rtnl_lock();
lock_sock(sk);
if (ro->bound && addr->can_ifindex == ro->ifindex)
goto out;
if (addr->can_ifindex) {
struct net_device *dev;
dev = dev_get_by_index(sock_net(sk), addr->can_ifindex);
if (!dev) {
err = -ENODEV;
......@@ -467,25 +468,20 @@ static int raw_bind(struct socket *sock, struct sockaddr *uaddr, int len)
if (!err) {
if (ro->bound) {
/* unregister old filters */
if (ro->ifindex) {
struct net_device *dev;
dev = dev_get_by_index(sock_net(sk),
ro->ifindex);
if (dev) {
raw_disable_allfilters(dev_net(dev),
dev, sk);
dev_put(dev);
}
} else
if (ro->dev)
raw_disable_allfilters(dev_net(ro->dev),
ro->dev, sk);
else
raw_disable_allfilters(sock_net(sk), NULL, sk);
}
ro->ifindex = ifindex;
ro->bound = 1;
ro->dev = dev;
}
out:
release_sock(sk);
rtnl_unlock();
if (notify_enetdown) {
sk->sk_err = ENETDOWN;
......@@ -552,9 +548,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
rtnl_lock();
lock_sock(sk);
if (ro->bound && ro->ifindex) {
dev = dev_get_by_index(sock_net(sk), ro->ifindex);
if (!dev) {
dev = ro->dev;
if (ro->bound && dev) {
if (dev->reg_state != NETREG_REGISTERED) {
if (count > 1)
kfree(filter);
err = -ENODEV;
......@@ -595,9 +591,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
ro->count = count;
out_fil:
if (dev)
dev_put(dev);
release_sock(sk);
rtnl_unlock();
......@@ -615,9 +608,9 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
rtnl_lock();
lock_sock(sk);
if (ro->bound && ro->ifindex) {
dev = dev_get_by_index(sock_net(sk), ro->ifindex);
if (!dev) {
dev = ro->dev;
if (ro->bound && dev) {
if (dev->reg_state != NETREG_REGISTERED) {
err = -ENODEV;
goto out_err;
}
......@@ -641,9 +634,6 @@ static int raw_setsockopt(struct socket *sock, int level, int optname,
ro->err_mask = err_mask;
out_err:
if (dev)
dev_put(dev);
release_sock(sk);
rtnl_unlock();
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册