diff options
author | YueHaibing <yuehaibing@huawei.com> | 2019-03-14 01:47:59 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2019-03-15 14:25:48 -0400 |
commit | 9804501fa1228048857910a6bf23e085aade37cc (patch) | |
tree | d51cf99870eb02f0b90107a449586d2ab20dbe9e | |
parent | f261c4e529dac5608a604d3dd3ae1cd2adf23c89 (diff) |
appletalk: Fix potential NULL pointer dereference in unregister_snap_client
register_snap_client may return NULL, all the callers
check it, but only print a warning. This will result in
NULL pointer dereference in unregister_snap_client and other
places.
It has always been used like this since v2.6
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | include/linux/atalk.h | 2 | ||||
-rw-r--r-- | net/appletalk/aarp.c | 15 | ||||
-rw-r--r-- | net/appletalk/ddp.c | 20 |
3 files changed, 25 insertions, 12 deletions
diff --git a/include/linux/atalk.h b/include/linux/atalk.h index d5cfc0b15b76..f6034ba774be 100644 --- a/include/linux/atalk.h +++ b/include/linux/atalk.h | |||
@@ -108,7 +108,7 @@ static __inline__ struct elapaarp *aarp_hdr(struct sk_buff *skb) | |||
108 | #define AARP_RESOLVE_TIME (10 * HZ) | 108 | #define AARP_RESOLVE_TIME (10 * HZ) |
109 | 109 | ||
110 | extern struct datalink_proto *ddp_dl, *aarp_dl; | 110 | extern struct datalink_proto *ddp_dl, *aarp_dl; |
111 | extern void aarp_proto_init(void); | 111 | extern int aarp_proto_init(void); |
112 | 112 | ||
113 | /* Inter module exports */ | 113 | /* Inter module exports */ |
114 | 114 | ||
diff --git a/net/appletalk/aarp.c b/net/appletalk/aarp.c index 49a16cee2aae..420a98bf79b5 100644 --- a/net/appletalk/aarp.c +++ b/net/appletalk/aarp.c | |||
@@ -879,15 +879,24 @@ static struct notifier_block aarp_notifier = { | |||
879 | 879 | ||
880 | static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; | 880 | static unsigned char aarp_snap_id[] = { 0x00, 0x00, 0x00, 0x80, 0xF3 }; |
881 | 881 | ||
882 | void __init aarp_proto_init(void) | 882 | int __init aarp_proto_init(void) |
883 | { | 883 | { |
884 | int rc; | ||
885 | |||
884 | aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); | 886 | aarp_dl = register_snap_client(aarp_snap_id, aarp_rcv); |
885 | if (!aarp_dl) | 887 | if (!aarp_dl) { |
886 | printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); | 888 | printk(KERN_CRIT "Unable to register AARP with SNAP.\n"); |
889 | return -ENOMEM; | ||
890 | } | ||
887 | timer_setup(&aarp_timer, aarp_expire_timeout, 0); | 891 | timer_setup(&aarp_timer, aarp_expire_timeout, 0); |
888 | aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; | 892 | aarp_timer.expires = jiffies + sysctl_aarp_expiry_time; |
889 | add_timer(&aarp_timer); | 893 | add_timer(&aarp_timer); |
890 | register_netdevice_notifier(&aarp_notifier); | 894 | rc = register_netdevice_notifier(&aarp_notifier); |
895 | if (rc) { | ||
896 | del_timer_sync(&aarp_timer); | ||
897 | unregister_snap_client(aarp_dl); | ||
898 | } | ||
899 | return rc; | ||
891 | } | 900 | } |
892 | 901 | ||
893 | /* Remove the AARP entries associated with a device. */ | 902 | /* Remove the AARP entries associated with a device. */ |
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 795fbc6c06aa..709d2542f729 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c | |||
@@ -1904,9 +1904,6 @@ static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B }; | |||
1904 | EXPORT_SYMBOL(atrtr_get_dev); | 1904 | EXPORT_SYMBOL(atrtr_get_dev); |
1905 | EXPORT_SYMBOL(atalk_find_dev_addr); | 1905 | EXPORT_SYMBOL(atalk_find_dev_addr); |
1906 | 1906 | ||
1907 | static const char atalk_err_snap[] __initconst = | ||
1908 | KERN_CRIT "Unable to register DDP with SNAP.\n"; | ||
1909 | |||
1910 | /* Called by proto.c on kernel start up */ | 1907 | /* Called by proto.c on kernel start up */ |
1911 | static int __init atalk_init(void) | 1908 | static int __init atalk_init(void) |
1912 | { | 1909 | { |
@@ -1921,17 +1918,22 @@ static int __init atalk_init(void) | |||
1921 | goto out_proto; | 1918 | goto out_proto; |
1922 | 1919 | ||
1923 | ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); | 1920 | ddp_dl = register_snap_client(ddp_snap_id, atalk_rcv); |
1924 | if (!ddp_dl) | 1921 | if (!ddp_dl) { |
1925 | printk(atalk_err_snap); | 1922 | pr_crit("Unable to register DDP with SNAP.\n"); |
1923 | goto out_sock; | ||
1924 | } | ||
1926 | 1925 | ||
1927 | dev_add_pack(<alk_packet_type); | 1926 | dev_add_pack(<alk_packet_type); |
1928 | dev_add_pack(&ppptalk_packet_type); | 1927 | dev_add_pack(&ppptalk_packet_type); |
1929 | 1928 | ||
1930 | rc = register_netdevice_notifier(&ddp_notifier); | 1929 | rc = register_netdevice_notifier(&ddp_notifier); |
1931 | if (rc) | 1930 | if (rc) |
1932 | goto out_sock; | 1931 | goto out_snap; |
1932 | |||
1933 | rc = aarp_proto_init(); | ||
1934 | if (rc) | ||
1935 | goto out_dev; | ||
1933 | 1936 | ||
1934 | aarp_proto_init(); | ||
1935 | rc = atalk_proc_init(); | 1937 | rc = atalk_proc_init(); |
1936 | if (rc) | 1938 | if (rc) |
1937 | goto out_aarp; | 1939 | goto out_aarp; |
@@ -1945,11 +1947,13 @@ out_proc: | |||
1945 | atalk_proc_exit(); | 1947 | atalk_proc_exit(); |
1946 | out_aarp: | 1948 | out_aarp: |
1947 | aarp_cleanup_module(); | 1949 | aarp_cleanup_module(); |
1950 | out_dev: | ||
1948 | unregister_netdevice_notifier(&ddp_notifier); | 1951 | unregister_netdevice_notifier(&ddp_notifier); |
1949 | out_sock: | 1952 | out_snap: |
1950 | dev_remove_pack(&ppptalk_packet_type); | 1953 | dev_remove_pack(&ppptalk_packet_type); |
1951 | dev_remove_pack(<alk_packet_type); | 1954 | dev_remove_pack(<alk_packet_type); |
1952 | unregister_snap_client(ddp_dl); | 1955 | unregister_snap_client(ddp_dl); |
1956 | out_sock: | ||
1953 | sock_unregister(PF_APPLETALK); | 1957 | sock_unregister(PF_APPLETALK); |
1954 | out_proto: | 1958 | out_proto: |
1955 | proto_unregister(&ddp_proto); | 1959 | proto_unregister(&ddp_proto); |