aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2016-04-07 12:23:51 -0400
committerDavid S. Miller <davem@davemloft.net>2016-04-11 15:34:41 -0400
commit648af7fca15901740c7aaafd55904ebd54d01860 (patch)
tree5aaa5a3d4b192da7bc9bb268d39038c60c068125
parent6dd050f88d702e2718bd856ea014487563207756 (diff)
rxrpc: Absorb the rxkad security module
Absorb the rxkad security module into the af_rxrpc module so that there's only one module file. This avoids a circular dependency whereby rxkad pins af_rxrpc and cached connections pin rxkad but can't be manually evicted (they will expire eventually and cease pinning). With this change, af_rxrpc can just be unloaded, despite having cached connections. Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/rxrpc/Kconfig2
-rw-r--r--net/rxrpc/Makefile3
-rw-r--r--net/rxrpc/af_rxrpc.c9
-rw-r--r--net/rxrpc/ar-internal.h21
-rw-r--r--net/rxrpc/ar-security.c123
-rw-r--r--net/rxrpc/rxkad.c61
6 files changed, 85 insertions, 134 deletions
diff --git a/net/rxrpc/Kconfig b/net/rxrpc/Kconfig
index 23dcef12b986..784c53163b7b 100644
--- a/net/rxrpc/Kconfig
+++ b/net/rxrpc/Kconfig
@@ -30,7 +30,7 @@ config AF_RXRPC_DEBUG
30 30
31 31
32config RXKAD 32config RXKAD
33 tristate "RxRPC Kerberos security" 33 bool "RxRPC Kerberos security"
34 depends on AF_RXRPC 34 depends on AF_RXRPC
35 select CRYPTO 35 select CRYPTO
36 select CRYPTO_MANAGER 36 select CRYPTO_MANAGER
diff --git a/net/rxrpc/Makefile b/net/rxrpc/Makefile
index 5b98c1640d6d..fa09cb55bfce 100644
--- a/net/rxrpc/Makefile
+++ b/net/rxrpc/Makefile
@@ -22,8 +22,7 @@ af-rxrpc-y := \
22 misc.o 22 misc.o
23 23
24af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o 24af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o
25af-rxrpc-$(CONFIG_RXKAD) += rxkad.o
25af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o 26af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o
26 27
27obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o 28obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o
28
29obj-$(CONFIG_RXKAD) += rxkad.o
diff --git a/net/rxrpc/af_rxrpc.c b/net/rxrpc/af_rxrpc.c
index 9d935fa5a2a9..e45e94ca030f 100644
--- a/net/rxrpc/af_rxrpc.c
+++ b/net/rxrpc/af_rxrpc.c
@@ -806,6 +806,12 @@ static int __init af_rxrpc_init(void)
806 goto error_work_queue; 806 goto error_work_queue;
807 } 807 }
808 808
809 ret = rxrpc_init_security();
810 if (ret < 0) {
811 printk(KERN_CRIT "RxRPC: Cannot initialise security\n");
812 goto error_security;
813 }
814
809 ret = proto_register(&rxrpc_proto, 1); 815 ret = proto_register(&rxrpc_proto, 1);
810 if (ret < 0) { 816 if (ret < 0) {
811 printk(KERN_CRIT "RxRPC: Cannot register protocol\n"); 817 printk(KERN_CRIT "RxRPC: Cannot register protocol\n");
@@ -853,6 +859,8 @@ error_sock:
853 proto_unregister(&rxrpc_proto); 859 proto_unregister(&rxrpc_proto);
854error_proto: 860error_proto:
855 destroy_workqueue(rxrpc_workqueue); 861 destroy_workqueue(rxrpc_workqueue);
862error_security:
863 rxrpc_exit_security();
856error_work_queue: 864error_work_queue:
857 kmem_cache_destroy(rxrpc_call_jar); 865 kmem_cache_destroy(rxrpc_call_jar);
858error_call_jar: 866error_call_jar:
@@ -883,6 +891,7 @@ static void __exit af_rxrpc_exit(void)
883 remove_proc_entry("rxrpc_conns", init_net.proc_net); 891 remove_proc_entry("rxrpc_conns", init_net.proc_net);
884 remove_proc_entry("rxrpc_calls", init_net.proc_net); 892 remove_proc_entry("rxrpc_calls", init_net.proc_net);
885 destroy_workqueue(rxrpc_workqueue); 893 destroy_workqueue(rxrpc_workqueue);
894 rxrpc_exit_security();
886 kmem_cache_destroy(rxrpc_call_jar); 895 kmem_cache_destroy(rxrpc_call_jar);
887 _leave(""); 896 _leave("");
888} 897}
diff --git a/net/rxrpc/ar-internal.h b/net/rxrpc/ar-internal.h
index d38071b09f72..72fd675a891e 100644
--- a/net/rxrpc/ar-internal.h
+++ b/net/rxrpc/ar-internal.h
@@ -124,11 +124,15 @@ enum rxrpc_command {
124 * RxRPC security module interface 124 * RxRPC security module interface
125 */ 125 */
126struct rxrpc_security { 126struct rxrpc_security {
127 struct module *owner; /* providing module */
128 struct list_head link; /* link in master list */
129 const char *name; /* name of this service */ 127 const char *name; /* name of this service */
130 u8 security_index; /* security type provided */ 128 u8 security_index; /* security type provided */
131 129
130 /* Initialise a security service */
131 int (*init)(void);
132
133 /* Clean up a security service */
134 void (*exit)(void);
135
132 /* initialise a connection's security */ 136 /* initialise a connection's security */
133 int (*init_connection_security)(struct rxrpc_connection *); 137 int (*init_connection_security)(struct rxrpc_connection *);
134 138
@@ -268,7 +272,7 @@ struct rxrpc_connection {
268 struct rb_root calls; /* calls on this connection */ 272 struct rb_root calls; /* calls on this connection */
269 struct sk_buff_head rx_queue; /* received conn-level packets */ 273 struct sk_buff_head rx_queue; /* received conn-level packets */
270 struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */ 274 struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */
271 struct rxrpc_security *security; /* applied security module */ 275 const struct rxrpc_security *security; /* applied security module */
272 struct key *key; /* security for this connection (client) */ 276 struct key *key; /* security for this connection (client) */
273 struct key *server_key; /* security for this service */ 277 struct key *server_key; /* security for this service */
274 struct crypto_skcipher *cipher; /* encryption handle */ 278 struct crypto_skcipher *cipher; /* encryption handle */
@@ -604,8 +608,8 @@ int rxrpc_recvmsg(struct socket *, struct msghdr *, size_t, int);
604/* 608/*
605 * ar-security.c 609 * ar-security.c
606 */ 610 */
607int rxrpc_register_security(struct rxrpc_security *); 611int __init rxrpc_init_security(void);
608void rxrpc_unregister_security(struct rxrpc_security *); 612void rxrpc_exit_security(void);
609int rxrpc_init_client_conn_security(struct rxrpc_connection *); 613int rxrpc_init_client_conn_security(struct rxrpc_connection *);
610int rxrpc_init_server_conn_security(struct rxrpc_connection *); 614int rxrpc_init_server_conn_security(struct rxrpc_connection *);
611int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t, 615int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t,
@@ -646,6 +650,13 @@ extern const s8 rxrpc_ack_priority[];
646extern const char *rxrpc_acks(u8 reason); 650extern const char *rxrpc_acks(u8 reason);
647 651
648/* 652/*
653 * rxkad.c
654 */
655#ifdef CONFIG_RXKAD
656extern const struct rxrpc_security rxkad;
657#endif
658
659/*
649 * sysctl.c 660 * sysctl.c
650 */ 661 */
651#ifdef CONFIG_SYSCTL 662#ifdef CONFIG_SYSCTL
diff --git a/net/rxrpc/ar-security.c b/net/rxrpc/ar-security.c
index ceff6394a65f..6946aec7ab1f 100644
--- a/net/rxrpc/ar-security.c
+++ b/net/rxrpc/ar-security.c
@@ -22,109 +22,59 @@
22static LIST_HEAD(rxrpc_security_methods); 22static LIST_HEAD(rxrpc_security_methods);
23static DECLARE_RWSEM(rxrpc_security_sem); 23static DECLARE_RWSEM(rxrpc_security_sem);
24 24
25/* 25static const struct rxrpc_security *rxrpc_security_types[] = {
26 * get an RxRPC security module 26#ifdef CONFIG_RXKAD
27 */ 27 [RXRPC_SECURITY_RXKAD] = &rxkad,
28static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec) 28#endif
29{ 29};
30 return try_module_get(sec->owner) ? sec : NULL;
31}
32 30
33/* 31int __init rxrpc_init_security(void)
34 * release an RxRPC security module
35 */
36static void rxrpc_security_put(struct rxrpc_security *sec)
37{ 32{
38 module_put(sec->owner); 33 int i, ret;
39}
40 34
41/* 35 for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) {
42 * look up an rxrpc security module 36 if (rxrpc_security_types[i]) {
43 */ 37 ret = rxrpc_security_types[i]->init();
44static struct rxrpc_security *rxrpc_security_lookup(u8 security_index) 38 if (ret < 0)
45{ 39 goto failed;
46 struct rxrpc_security *sec = NULL;
47
48 _enter("");
49
50 down_read(&rxrpc_security_sem);
51
52 list_for_each_entry(sec, &rxrpc_security_methods, link) {
53 if (sec->security_index == security_index) {
54 if (unlikely(!rxrpc_security_get(sec)))
55 break;
56 goto out;
57 } 40 }
58 } 41 }
59 42
60 sec = NULL; 43 return 0;
61out: 44
62 up_read(&rxrpc_security_sem); 45failed:
63 _leave(" = %p [%s]", sec, sec ? sec->name : ""); 46 for (i--; i >= 0; i--)
64 return sec; 47 if (rxrpc_security_types[i])
48 rxrpc_security_types[i]->exit();
49 return ret;
65} 50}
66 51
67/** 52void rxrpc_exit_security(void)
68 * rxrpc_register_security - register an RxRPC security handler
69 * @sec: security module
70 *
71 * register an RxRPC security handler for use by RxRPC
72 */
73int rxrpc_register_security(struct rxrpc_security *sec)
74{ 53{
75 struct rxrpc_security *psec; 54 int i;
76 int ret;
77
78 _enter("");
79 down_write(&rxrpc_security_sem);
80
81 ret = -EEXIST;
82 list_for_each_entry(psec, &rxrpc_security_methods, link) {
83 if (psec->security_index == sec->security_index)
84 goto out;
85 }
86
87 list_add(&sec->link, &rxrpc_security_methods);
88
89 printk(KERN_NOTICE "RxRPC: Registered security type %d '%s'\n",
90 sec->security_index, sec->name);
91 ret = 0;
92 55
93out: 56 for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++)
94 up_write(&rxrpc_security_sem); 57 if (rxrpc_security_types[i])
95 _leave(" = %d", ret); 58 rxrpc_security_types[i]->exit();
96 return ret;
97} 59}
98 60
99EXPORT_SYMBOL_GPL(rxrpc_register_security); 61/*
100 62 * look up an rxrpc security module
101/**
102 * rxrpc_unregister_security - unregister an RxRPC security handler
103 * @sec: security module
104 *
105 * unregister an RxRPC security handler
106 */ 63 */
107void rxrpc_unregister_security(struct rxrpc_security *sec) 64static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index)
108{ 65{
109 66 if (security_index >= ARRAY_SIZE(rxrpc_security_types))
110 _enter(""); 67 return NULL;
111 down_write(&rxrpc_security_sem); 68 return rxrpc_security_types[security_index];
112 list_del_init(&sec->link);
113 up_write(&rxrpc_security_sem);
114
115 printk(KERN_NOTICE "RxRPC: Unregistered security type %d '%s'\n",
116 sec->security_index, sec->name);
117} 69}
118 70
119EXPORT_SYMBOL_GPL(rxrpc_unregister_security);
120
121/* 71/*
122 * initialise the security on a client connection 72 * initialise the security on a client connection
123 */ 73 */
124int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) 74int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
125{ 75{
76 const struct rxrpc_security *sec;
126 struct rxrpc_key_token *token; 77 struct rxrpc_key_token *token;
127 struct rxrpc_security *sec;
128 struct key *key = conn->key; 78 struct key *key = conn->key;
129 int ret; 79 int ret;
130 80
@@ -148,7 +98,6 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
148 98
149 ret = conn->security->init_connection_security(conn); 99 ret = conn->security->init_connection_security(conn);
150 if (ret < 0) { 100 if (ret < 0) {
151 rxrpc_security_put(conn->security);
152 conn->security = NULL; 101 conn->security = NULL;
153 return ret; 102 return ret;
154 } 103 }
@@ -162,7 +111,7 @@ int rxrpc_init_client_conn_security(struct rxrpc_connection *conn)
162 */ 111 */
163int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) 112int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
164{ 113{
165 struct rxrpc_security *sec; 114 const struct rxrpc_security *sec;
166 struct rxrpc_local *local = conn->trans->local; 115 struct rxrpc_local *local = conn->trans->local;
167 struct rxrpc_sock *rx; 116 struct rxrpc_sock *rx;
168 struct key *key; 117 struct key *key;
@@ -188,14 +137,12 @@ int rxrpc_init_server_conn_security(struct rxrpc_connection *conn)
188 137
189 /* the service appears to have died */ 138 /* the service appears to have died */
190 read_unlock_bh(&local->services_lock); 139 read_unlock_bh(&local->services_lock);
191 rxrpc_security_put(sec);
192 _leave(" = -ENOENT"); 140 _leave(" = -ENOENT");
193 return -ENOENT; 141 return -ENOENT;
194 142
195found_service: 143found_service:
196 if (!rx->securities) { 144 if (!rx->securities) {
197 read_unlock_bh(&local->services_lock); 145 read_unlock_bh(&local->services_lock);
198 rxrpc_security_put(sec);
199 _leave(" = -ENOKEY"); 146 _leave(" = -ENOKEY");
200 return -ENOKEY; 147 return -ENOKEY;
201 } 148 }
@@ -205,7 +152,6 @@ found_service:
205 &key_type_rxrpc_s, kdesc); 152 &key_type_rxrpc_s, kdesc);
206 if (IS_ERR(kref)) { 153 if (IS_ERR(kref)) {
207 read_unlock_bh(&local->services_lock); 154 read_unlock_bh(&local->services_lock);
208 rxrpc_security_put(sec);
209 _leave(" = %ld [search]", PTR_ERR(kref)); 155 _leave(" = %ld [search]", PTR_ERR(kref));
210 return PTR_ERR(kref); 156 return PTR_ERR(kref);
211 } 157 }
@@ -253,11 +199,8 @@ void rxrpc_clear_conn_security(struct rxrpc_connection *conn)
253{ 199{
254 _enter("{%d}", conn->debug_id); 200 _enter("{%d}", conn->debug_id);
255 201
256 if (conn->security) { 202 if (conn->security)
257 conn->security->clear(conn); 203 conn->security->clear(conn);
258 rxrpc_security_put(conn->security);
259 conn->security = NULL;
260 }
261 204
262 key_put(conn->key); 205 key_put(conn->key);
263 key_put(conn->server_key); 206 key_put(conn->server_key);
diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
index f0aeb8163688..6b726a046a7d 100644
--- a/net/rxrpc/rxkad.c
+++ b/net/rxrpc/rxkad.c
@@ -20,7 +20,6 @@
20#include <net/sock.h> 20#include <net/sock.h>
21#include <net/af_rxrpc.h> 21#include <net/af_rxrpc.h>
22#include <keys/rxrpc-type.h> 22#include <keys/rxrpc-type.h>
23#define rxrpc_debug rxkad_debug
24#include "ar-internal.h" 23#include "ar-internal.h"
25 24
26#define RXKAD_VERSION 2 25#define RXKAD_VERSION 2
@@ -31,10 +30,6 @@
31#define REALM_SZ 40 /* size of principal's auth domain */ 30#define REALM_SZ 40 /* size of principal's auth domain */
32#define SNAME_SZ 40 /* size of service name */ 31#define SNAME_SZ 40 /* size of service name */
33 32
34unsigned int rxrpc_debug;
35module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO);
36MODULE_PARM_DESC(debug, "rxkad debugging mask");
37
38struct rxkad_level1_hdr { 33struct rxkad_level1_hdr {
39 __be32 data_size; /* true data size (excluding padding) */ 34 __be32 data_size; /* true data size (excluding padding) */
40}; 35};
@@ -44,10 +39,6 @@ struct rxkad_level2_hdr {
44 __be32 checksum; /* decrypted data checksum */ 39 __be32 checksum; /* decrypted data checksum */
45}; 40};
46 41
47MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)");
48MODULE_AUTHOR("Red Hat, Inc.");
49MODULE_LICENSE("GPL");
50
51/* 42/*
52 * this holds a pinned cipher so that keventd doesn't get called by the cipher 43 * this holds a pinned cipher so that keventd doesn't get called by the cipher
53 * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE 44 * alloc routine, but since we have it to hand, we use it to decrypt RESPONSE
@@ -1164,12 +1155,35 @@ static void rxkad_clear(struct rxrpc_connection *conn)
1164} 1155}
1165 1156
1166/* 1157/*
1158 * Initialise the rxkad security service.
1159 */
1160static int rxkad_init(void)
1161{
1162 /* pin the cipher we need so that the crypto layer doesn't invoke
1163 * keventd to go get it */
1164 rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
1165 if (IS_ERR(rxkad_ci))
1166 return PTR_ERR(rxkad_ci);
1167 return 0;
1168}
1169
1170/*
1171 * Clean up the rxkad security service.
1172 */
1173static void rxkad_exit(void)
1174{
1175 if (rxkad_ci)
1176 crypto_free_skcipher(rxkad_ci);
1177}
1178
1179/*
1167 * RxRPC Kerberos-based security 1180 * RxRPC Kerberos-based security
1168 */ 1181 */
1169static struct rxrpc_security rxkad = { 1182const struct rxrpc_security rxkad = {
1170 .owner = THIS_MODULE,
1171 .name = "rxkad", 1183 .name = "rxkad",
1172 .security_index = RXRPC_SECURITY_RXKAD, 1184 .security_index = RXRPC_SECURITY_RXKAD,
1185 .init = rxkad_init,
1186 .exit = rxkad_exit,
1173 .init_connection_security = rxkad_init_connection_security, 1187 .init_connection_security = rxkad_init_connection_security,
1174 .prime_packet_security = rxkad_prime_packet_security, 1188 .prime_packet_security = rxkad_prime_packet_security,
1175 .secure_packet = rxkad_secure_packet, 1189 .secure_packet = rxkad_secure_packet,
@@ -1179,28 +1193,3 @@ static struct rxrpc_security rxkad = {
1179 .verify_response = rxkad_verify_response, 1193 .verify_response = rxkad_verify_response,
1180 .clear = rxkad_clear, 1194 .clear = rxkad_clear,
1181}; 1195};
1182
1183static __init int rxkad_init(void)
1184{
1185 _enter("");
1186
1187 /* pin the cipher we need so that the crypto layer doesn't invoke
1188 * keventd to go get it */
1189 rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC);
1190 if (IS_ERR(rxkad_ci))
1191 return PTR_ERR(rxkad_ci);
1192
1193 return rxrpc_register_security(&rxkad);
1194}
1195
1196module_init(rxkad_init);
1197
1198static __exit void rxkad_exit(void)
1199{
1200 _enter("");
1201
1202 rxrpc_unregister_security(&rxkad);
1203 crypto_free_skcipher(rxkad_ci);
1204}
1205
1206module_exit(rxkad_exit);