| From foo@baz Mon Apr 9 17:09:24 CEST 2018 |
| From: linzhang <xiaolou4617@gmail.com> |
| Date: Wed, 17 May 2017 12:05:07 +0800 |
| Subject: net: x25: fix one potential use-after-free issue |
| |
| From: linzhang <xiaolou4617@gmail.com> |
| |
| |
| [ Upstream commit 64df6d525fcff1630098db9238bfd2b3e092d5c1 ] |
| |
| The function x25_init is not properly unregister related resources |
| on error handler.It is will result in kernel oops if x25_init init |
| failed, so add properly unregister call on error handler. |
| |
| Also, i adjust the coding style and make x25_register_sysctl properly |
| return failure. |
| |
| Signed-off-by: linzhang <xiaolou4617@gmail.com> |
| Signed-off-by: David S. Miller <davem@davemloft.net> |
| Signed-off-by: Sasha Levin <alexander.levin@microsoft.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| include/net/x25.h | 4 ++-- |
| net/x25/af_x25.c | 24 ++++++++++++++++-------- |
| net/x25/sysctl_net_x25.c | 5 ++++- |
| 3 files changed, 22 insertions(+), 11 deletions(-) |
| |
| --- a/include/net/x25.h |
| +++ b/include/net/x25.h |
| @@ -298,10 +298,10 @@ void x25_check_rbuf(struct sock *); |
| |
| /* sysctl_net_x25.c */ |
| #ifdef CONFIG_SYSCTL |
| -void x25_register_sysctl(void); |
| +int x25_register_sysctl(void); |
| void x25_unregister_sysctl(void); |
| #else |
| -static inline void x25_register_sysctl(void) {}; |
| +static inline int x25_register_sysctl(void) { return 0; }; |
| static inline void x25_unregister_sysctl(void) {}; |
| #endif /* CONFIG_SYSCTL */ |
| |
| --- a/net/x25/af_x25.c |
| +++ b/net/x25/af_x25.c |
| @@ -1790,32 +1790,40 @@ void x25_kill_by_neigh(struct x25_neigh |
| |
| static int __init x25_init(void) |
| { |
| - int rc = proto_register(&x25_proto, 0); |
| + int rc; |
| |
| - if (rc != 0) |
| + rc = proto_register(&x25_proto, 0); |
| + if (rc) |
| goto out; |
| |
| rc = sock_register(&x25_family_ops); |
| - if (rc != 0) |
| + if (rc) |
| goto out_proto; |
| |
| dev_add_pack(&x25_packet_type); |
| |
| rc = register_netdevice_notifier(&x25_dev_notifier); |
| - if (rc != 0) |
| + if (rc) |
| goto out_sock; |
| |
| - pr_info("Linux Version 0.2\n"); |
| + rc = x25_register_sysctl(); |
| + if (rc) |
| + goto out_dev; |
| |
| - x25_register_sysctl(); |
| rc = x25_proc_init(); |
| - if (rc != 0) |
| - goto out_dev; |
| + if (rc) |
| + goto out_sysctl; |
| + |
| + pr_info("Linux Version 0.2\n"); |
| + |
| out: |
| return rc; |
| +out_sysctl: |
| + x25_unregister_sysctl(); |
| out_dev: |
| unregister_netdevice_notifier(&x25_dev_notifier); |
| out_sock: |
| + dev_remove_pack(&x25_packet_type); |
| sock_unregister(AF_X25); |
| out_proto: |
| proto_unregister(&x25_proto); |
| --- a/net/x25/sysctl_net_x25.c |
| +++ b/net/x25/sysctl_net_x25.c |
| @@ -73,9 +73,12 @@ static struct ctl_table x25_table[] = { |
| { 0, }, |
| }; |
| |
| -void __init x25_register_sysctl(void) |
| +int __init x25_register_sysctl(void) |
| { |
| x25_table_header = register_net_sysctl(&init_net, "net/x25", x25_table); |
| + if (!x25_table_header) |
| + return -ENOMEM; |
| + return 0; |
| } |
| |
| void x25_unregister_sysctl(void) |