Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

David Howells and committed by
David S. Miller
648af7fc 6dd050f8

+89 -138
+1 -1
net/rxrpc/Kconfig
··· 30 30 31 31 32 32 config RXKAD 33 - tristate "RxRPC Kerberos security" 33 + bool "RxRPC Kerberos security" 34 34 depends on AF_RXRPC 35 35 select CRYPTO 36 36 select CRYPTO_MANAGER
+1 -2
net/rxrpc/Makefile
··· 22 22 misc.o 23 23 24 24 af-rxrpc-$(CONFIG_PROC_FS) += ar-proc.o 25 + af-rxrpc-$(CONFIG_RXKAD) += rxkad.o 25 26 af-rxrpc-$(CONFIG_SYSCTL) += sysctl.o 26 27 27 28 obj-$(CONFIG_AF_RXRPC) += af-rxrpc.o 28 - 29 - obj-$(CONFIG_RXKAD) += rxkad.o
+9
net/rxrpc/af_rxrpc.c
··· 806 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 815 ret = proto_register(&rxrpc_proto, 1); 810 816 if (ret < 0) { 811 817 printk(KERN_CRIT "RxRPC: Cannot register protocol\n"); ··· 859 853 proto_unregister(&rxrpc_proto); 860 854 error_proto: 861 855 destroy_workqueue(rxrpc_workqueue); 856 + error_security: 857 + rxrpc_exit_security(); 862 858 error_work_queue: 863 859 kmem_cache_destroy(rxrpc_call_jar); 864 860 error_call_jar: ··· 891 883 remove_proc_entry("rxrpc_conns", init_net.proc_net); 892 884 remove_proc_entry("rxrpc_calls", init_net.proc_net); 893 885 destroy_workqueue(rxrpc_workqueue); 886 + rxrpc_exit_security(); 894 887 kmem_cache_destroy(rxrpc_call_jar); 895 888 _leave(""); 896 889 }
+16 -5
net/rxrpc/ar-internal.h
··· 124 124 * RxRPC security module interface 125 125 */ 126 126 struct rxrpc_security { 127 - struct module *owner; /* providing module */ 128 - struct list_head link; /* link in master list */ 129 127 const char *name; /* name of this service */ 130 128 u8 security_index; /* security type provided */ 129 + 130 + /* Initialise a security service */ 131 + int (*init)(void); 132 + 133 + /* Clean up a security service */ 134 + void (*exit)(void); 131 135 132 136 /* initialise a connection's security */ 133 137 int (*init_connection_security)(struct rxrpc_connection *); ··· 272 268 struct rb_root calls; /* calls on this connection */ 273 269 struct sk_buff_head rx_queue; /* received conn-level packets */ 274 270 struct rxrpc_call *channels[RXRPC_MAXCALLS]; /* channels (active calls) */ 275 - struct rxrpc_security *security; /* applied security module */ 271 + const struct rxrpc_security *security; /* applied security module */ 276 272 struct key *key; /* security for this connection (client) */ 277 273 struct key *server_key; /* security for this service */ 278 274 struct crypto_skcipher *cipher; /* encryption handle */ ··· 608 604 /* 609 605 * ar-security.c 610 606 */ 611 - int rxrpc_register_security(struct rxrpc_security *); 612 - void rxrpc_unregister_security(struct rxrpc_security *); 607 + int __init rxrpc_init_security(void); 608 + void rxrpc_exit_security(void); 613 609 int rxrpc_init_client_conn_security(struct rxrpc_connection *); 614 610 int rxrpc_init_server_conn_security(struct rxrpc_connection *); 615 611 int rxrpc_secure_packet(const struct rxrpc_call *, struct sk_buff *, size_t, ··· 648 644 extern const s8 rxrpc_ack_priority[]; 649 645 650 646 extern const char *rxrpc_acks(u8 reason); 647 + 648 + /* 649 + * rxkad.c 650 + */ 651 + #ifdef CONFIG_RXKAD 652 + extern const struct rxrpc_security rxkad; 653 + #endif 651 654 652 655 /* 653 656 * sysctl.c
+37 -94
net/rxrpc/ar-security.c
··· 22 22 static LIST_HEAD(rxrpc_security_methods); 23 23 static DECLARE_RWSEM(rxrpc_security_sem); 24 24 25 - /* 26 - * get an RxRPC security module 27 - */ 28 - static struct rxrpc_security *rxrpc_security_get(struct rxrpc_security *sec) 25 + static const struct rxrpc_security *rxrpc_security_types[] = { 26 + #ifdef CONFIG_RXKAD 27 + [RXRPC_SECURITY_RXKAD] = &rxkad, 28 + #endif 29 + }; 30 + 31 + int __init rxrpc_init_security(void) 29 32 { 30 - return try_module_get(sec->owner) ? sec : NULL; 33 + int i, ret; 34 + 35 + for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) { 36 + if (rxrpc_security_types[i]) { 37 + ret = rxrpc_security_types[i]->init(); 38 + if (ret < 0) 39 + goto failed; 40 + } 41 + } 42 + 43 + return 0; 44 + 45 + failed: 46 + for (i--; i >= 0; i--) 47 + if (rxrpc_security_types[i]) 48 + rxrpc_security_types[i]->exit(); 49 + return ret; 31 50 } 32 51 33 - /* 34 - * release an RxRPC security module 35 - */ 36 - static void rxrpc_security_put(struct rxrpc_security *sec) 52 + void rxrpc_exit_security(void) 37 53 { 38 - module_put(sec->owner); 54 + int i; 55 + 56 + for (i = 0; i < ARRAY_SIZE(rxrpc_security_types); i++) 57 + if (rxrpc_security_types[i]) 58 + rxrpc_security_types[i]->exit(); 39 59 } 40 60 41 61 /* 42 62 * look up an rxrpc security module 43 63 */ 44 - static struct rxrpc_security *rxrpc_security_lookup(u8 security_index) 64 + static const struct rxrpc_security *rxrpc_security_lookup(u8 security_index) 45 65 { 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 - } 58 - } 59 - 60 - sec = NULL; 61 - out: 62 - up_read(&rxrpc_security_sem); 63 - _leave(" = %p [%s]", sec, sec ? sec->name : ""); 64 - return sec; 66 + if (security_index >= ARRAY_SIZE(rxrpc_security_types)) 67 + return NULL; 68 + return rxrpc_security_types[security_index]; 65 69 } 66 - 67 - /** 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 - */ 73 - int rxrpc_register_security(struct rxrpc_security *sec) 74 - { 75 - struct rxrpc_security *psec; 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 - 93 - out: 94 - up_write(&rxrpc_security_sem); 95 - _leave(" = %d", ret); 96 - return ret; 97 - } 98 - 99 - EXPORT_SYMBOL_GPL(rxrpc_register_security); 100 - 101 - /** 102 - * rxrpc_unregister_security - unregister an RxRPC security handler 103 - * @sec: security module 104 - * 105 - * unregister an RxRPC security handler 106 - */ 107 - void rxrpc_unregister_security(struct rxrpc_security *sec) 108 - { 109 - 110 - _enter(""); 111 - down_write(&rxrpc_security_sem); 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 - } 118 - 119 - EXPORT_SYMBOL_GPL(rxrpc_unregister_security); 120 70 121 71 /* 122 72 * initialise the security on a client connection 123 73 */ 124 74 int rxrpc_init_client_conn_security(struct rxrpc_connection *conn) 125 75 { 76 + const struct rxrpc_security *sec; 126 77 struct rxrpc_key_token *token; 127 - struct rxrpc_security *sec; 128 78 struct key *key = conn->key; 129 79 int ret; 130 80 ··· 98 148 99 149 ret = conn->security->init_connection_security(conn); 100 150 if (ret < 0) { 101 - rxrpc_security_put(conn->security); 102 151 conn->security = NULL; 103 152 return ret; 104 153 } ··· 111 162 */ 112 163 int rxrpc_init_server_conn_security(struct rxrpc_connection *conn) 113 164 { 114 - struct rxrpc_security *sec; 165 + const struct rxrpc_security *sec; 115 166 struct rxrpc_local *local = conn->trans->local; 116 167 struct rxrpc_sock *rx; 117 168 struct key *key; ··· 137 188 138 189 /* the service appears to have died */ 139 190 read_unlock_bh(&local->services_lock); 140 - rxrpc_security_put(sec); 141 191 _leave(" = -ENOENT"); 142 192 return -ENOENT; 143 193 144 194 found_service: 145 195 if (!rx->securities) { 146 196 read_unlock_bh(&local->services_lock); 147 - rxrpc_security_put(sec); 148 197 _leave(" = -ENOKEY"); 149 198 return -ENOKEY; 150 199 } ··· 152 205 &key_type_rxrpc_s, kdesc); 153 206 if (IS_ERR(kref)) { 154 207 read_unlock_bh(&local->services_lock); 155 - rxrpc_security_put(sec); 156 208 _leave(" = %ld [search]", PTR_ERR(kref)); 157 209 return PTR_ERR(kref); 158 210 } ··· 199 253 { 200 254 _enter("{%d}", conn->debug_id); 201 255 202 - if (conn->security) { 256 + if (conn->security) 203 257 conn->security->clear(conn); 204 - rxrpc_security_put(conn->security); 205 - conn->security = NULL; 206 - } 207 258 208 259 key_put(conn->key); 209 260 key_put(conn->server_key);
+25 -36
net/rxrpc/rxkad.c
··· 20 20 #include <net/sock.h> 21 21 #include <net/af_rxrpc.h> 22 22 #include <keys/rxrpc-type.h> 23 - #define rxrpc_debug rxkad_debug 24 23 #include "ar-internal.h" 25 24 26 25 #define RXKAD_VERSION 2 ··· 30 31 #define REALM_SZ 40 /* size of principal's auth domain */ 31 32 #define SNAME_SZ 40 /* size of service name */ 32 33 33 - unsigned int rxrpc_debug; 34 - module_param_named(debug, rxrpc_debug, uint, S_IWUSR | S_IRUGO); 35 - MODULE_PARM_DESC(debug, "rxkad debugging mask"); 36 - 37 34 struct rxkad_level1_hdr { 38 35 __be32 data_size; /* true data size (excluding padding) */ 39 36 }; ··· 38 43 __be32 data_size; /* true data size (excluding padding) */ 39 44 __be32 checksum; /* decrypted data checksum */ 40 45 }; 41 - 42 - MODULE_DESCRIPTION("RxRPC network protocol type-2 security (Kerberos 4)"); 43 - MODULE_AUTHOR("Red Hat, Inc."); 44 - MODULE_LICENSE("GPL"); 45 46 46 47 /* 47 48 * this holds a pinned cipher so that keventd doesn't get called by the cipher ··· 1155 1164 } 1156 1165 1157 1166 /* 1167 + * Initialise the rxkad security service. 1168 + */ 1169 + static int rxkad_init(void) 1170 + { 1171 + /* pin the cipher we need so that the crypto layer doesn't invoke 1172 + * keventd to go get it */ 1173 + rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); 1174 + if (IS_ERR(rxkad_ci)) 1175 + return PTR_ERR(rxkad_ci); 1176 + return 0; 1177 + } 1178 + 1179 + /* 1180 + * Clean up the rxkad security service. 1181 + */ 1182 + static void rxkad_exit(void) 1183 + { 1184 + if (rxkad_ci) 1185 + crypto_free_skcipher(rxkad_ci); 1186 + } 1187 + 1188 + /* 1158 1189 * RxRPC Kerberos-based security 1159 1190 */ 1160 - static struct rxrpc_security rxkad = { 1161 - .owner = THIS_MODULE, 1191 + const struct rxrpc_security rxkad = { 1162 1192 .name = "rxkad", 1163 1193 .security_index = RXRPC_SECURITY_RXKAD, 1194 + .init = rxkad_init, 1195 + .exit = rxkad_exit, 1164 1196 .init_connection_security = rxkad_init_connection_security, 1165 1197 .prime_packet_security = rxkad_prime_packet_security, 1166 1198 .secure_packet = rxkad_secure_packet, ··· 1193 1179 .verify_response = rxkad_verify_response, 1194 1180 .clear = rxkad_clear, 1195 1181 }; 1196 - 1197 - static __init int rxkad_init(void) 1198 - { 1199 - _enter(""); 1200 - 1201 - /* pin the cipher we need so that the crypto layer doesn't invoke 1202 - * keventd to go get it */ 1203 - rxkad_ci = crypto_alloc_skcipher("pcbc(fcrypt)", 0, CRYPTO_ALG_ASYNC); 1204 - if (IS_ERR(rxkad_ci)) 1205 - return PTR_ERR(rxkad_ci); 1206 - 1207 - return rxrpc_register_security(&rxkad); 1208 - } 1209 - 1210 - module_init(rxkad_init); 1211 - 1212 - static __exit void rxkad_exit(void) 1213 - { 1214 - _enter(""); 1215 - 1216 - rxrpc_unregister_security(&rxkad); 1217 - crypto_free_skcipher(rxkad_ci); 1218 - } 1219 - 1220 - module_exit(rxkad_exit);