aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/rxrpc.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-04-26 18:57:07 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-26 18:57:07 -0400
commit00d3b7a4533e367b0dc2812a706db8f9f071c27f (patch)
treef0b1ae0266267cb2c54cb11aa61ad0758ce9c0f5 /fs/afs/rxrpc.c
parent436058a49e0fb91c74454dbee9cfee6fb53b4336 (diff)
[AFS]: Add security support.
Add security support to the AFS filesystem. Kerberos IV tickets are added as RxRPC keys are added to the session keyring with the klog program. open() and other VFS operations then find this ticket with request_key() and either use it immediately (eg: mkdir, unlink) or attach it to a file descriptor (open). Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/rxrpc.c')
-rw-r--r--fs/afs/rxrpc.c137
1 files changed, 107 insertions, 30 deletions
diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
index b92774231b3c..e86c527d87a1 100644
--- a/fs/afs/rxrpc.c
+++ b/fs/afs/rxrpc.c
@@ -17,6 +17,8 @@
17 17
18static struct socket *afs_socket; /* my RxRPC socket */ 18static struct socket *afs_socket; /* my RxRPC socket */
19static struct workqueue_struct *afs_async_calls; 19static struct workqueue_struct *afs_async_calls;
20static atomic_t afs_outstanding_calls;
21static atomic_t afs_outstanding_skbs;
20 22
21static void afs_wake_up_call_waiter(struct afs_call *); 23static void afs_wake_up_call_waiter(struct afs_call *);
22static int afs_wait_for_call_to_complete(struct afs_call *); 24static int afs_wait_for_call_to_complete(struct afs_call *);
@@ -45,6 +47,7 @@ static const struct afs_wait_mode afs_async_incoming_call = {
45 47
46/* asynchronous incoming call initial processing */ 48/* asynchronous incoming call initial processing */
47static const struct afs_call_type afs_RXCMxxxx = { 49static const struct afs_call_type afs_RXCMxxxx = {
50 .name = "CB.xxxx",
48 .deliver = afs_deliver_cm_op_id, 51 .deliver = afs_deliver_cm_op_id,
49 .abort_to_error = afs_abort_to_error, 52 .abort_to_error = afs_abort_to_error,
50}; 53};
@@ -118,10 +121,67 @@ void afs_close_socket(void)
118 121
119 _debug("dework"); 122 _debug("dework");
120 destroy_workqueue(afs_async_calls); 123 destroy_workqueue(afs_async_calls);
124
125 ASSERTCMP(atomic_read(&afs_outstanding_skbs), ==, 0);
126 ASSERTCMP(atomic_read(&afs_outstanding_calls), ==, 0);
121 _leave(""); 127 _leave("");
122} 128}
123 129
124/* 130/*
131 * note that the data in a socket buffer is now delivered and that the buffer
132 * should be freed
133 */
134static void afs_data_delivered(struct sk_buff *skb)
135{
136 if (!skb) {
137 _debug("DLVR NULL [%d]", atomic_read(&afs_outstanding_skbs));
138 dump_stack();
139 } else {
140 _debug("DLVR %p{%u} [%d]",
141 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
142 if (atomic_dec_return(&afs_outstanding_skbs) == -1)
143 BUG();
144 rxrpc_kernel_data_delivered(skb);
145 }
146}
147
148/*
149 * free a socket buffer
150 */
151static void afs_free_skb(struct sk_buff *skb)
152{
153 if (!skb) {
154 _debug("FREE NULL [%d]", atomic_read(&afs_outstanding_skbs));
155 dump_stack();
156 } else {
157 _debug("FREE %p{%u} [%d]",
158 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
159 if (atomic_dec_return(&afs_outstanding_skbs) == -1)
160 BUG();
161 rxrpc_kernel_free_skb(skb);
162 }
163}
164
165/*
166 * free a call
167 */
168static void afs_free_call(struct afs_call *call)
169{
170 _debug("DONE %p{%s} [%d]",
171 call, call->type->name, atomic_read(&afs_outstanding_calls));
172 if (atomic_dec_return(&afs_outstanding_calls) == -1)
173 BUG();
174
175 ASSERTCMP(call->rxcall, ==, NULL);
176 ASSERT(!work_pending(&call->async_work));
177 ASSERT(skb_queue_empty(&call->rx_queue));
178 ASSERT(call->type->name != NULL);
179
180 kfree(call->request);
181 kfree(call);
182}
183
184/*
125 * allocate a call with flat request and reply buffers 185 * allocate a call with flat request and reply buffers
126 */ 186 */
127struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type, 187struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
@@ -133,30 +193,32 @@ struct afs_call *afs_alloc_flat_call(const struct afs_call_type *type,
133 if (!call) 193 if (!call)
134 goto nomem_call; 194 goto nomem_call;
135 195
196 _debug("CALL %p{%s} [%d]",
197 call, type->name, atomic_read(&afs_outstanding_calls));
198 atomic_inc(&afs_outstanding_calls);
199
200 call->type = type;
201 call->request_size = request_size;
202 call->reply_max = reply_size;
203
136 if (request_size) { 204 if (request_size) {
137 call->request = kmalloc(request_size, GFP_NOFS); 205 call->request = kmalloc(request_size, GFP_NOFS);
138 if (!call->request) 206 if (!call->request)
139 goto nomem_request; 207 goto nomem_free;
140 } 208 }
141 209
142 if (reply_size) { 210 if (reply_size) {
143 call->buffer = kmalloc(reply_size, GFP_NOFS); 211 call->buffer = kmalloc(reply_size, GFP_NOFS);
144 if (!call->buffer) 212 if (!call->buffer)
145 goto nomem_buffer; 213 goto nomem_free;
146 } 214 }
147 215
148 call->type = type;
149 call->request_size = request_size;
150 call->reply_max = reply_size;
151
152 init_waitqueue_head(&call->waitq); 216 init_waitqueue_head(&call->waitq);
153 skb_queue_head_init(&call->rx_queue); 217 skb_queue_head_init(&call->rx_queue);
154 return call; 218 return call;
155 219
156nomem_buffer: 220nomem_free:
157 kfree(call->request); 221 afs_free_call(call);
158nomem_request:
159 kfree(call);
160nomem_call: 222nomem_call:
161 return NULL; 223 return NULL;
162} 224}
@@ -188,6 +250,12 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
188 250
189 _enter("%x,{%d},", addr->s_addr, ntohs(call->port)); 251 _enter("%x,{%d},", addr->s_addr, ntohs(call->port));
190 252
253 ASSERT(call->type != NULL);
254 ASSERT(call->type->name != NULL);
255
256 _debug("MAKE %p{%s} [%d]",
257 call, call->type->name, atomic_read(&afs_outstanding_calls));
258
191 call->wait_mode = wait_mode; 259 call->wait_mode = wait_mode;
192 INIT_WORK(&call->async_work, afs_process_async_call); 260 INIT_WORK(&call->async_work, afs_process_async_call);
193 261
@@ -203,6 +271,7 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
203 /* create a call */ 271 /* create a call */
204 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key, 272 rxcall = rxrpc_kernel_begin_call(afs_socket, &srx, call->key,
205 (unsigned long) call, gfp); 273 (unsigned long) call, gfp);
274 call->key = NULL;
206 if (IS_ERR(rxcall)) { 275 if (IS_ERR(rxcall)) {
207 ret = PTR_ERR(rxcall); 276 ret = PTR_ERR(rxcall);
208 goto error_kill_call; 277 goto error_kill_call;
@@ -237,10 +306,10 @@ int afs_make_call(struct in_addr *addr, struct afs_call *call, gfp_t gfp,
237error_do_abort: 306error_do_abort:
238 rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT); 307 rxrpc_kernel_abort_call(rxcall, RX_USER_ABORT);
239 rxrpc_kernel_end_call(rxcall); 308 rxrpc_kernel_end_call(rxcall);
309 call->rxcall = NULL;
240error_kill_call: 310error_kill_call:
241 call->type->destructor(call); 311 call->type->destructor(call);
242 ASSERT(skb_queue_empty(&call->rx_queue)); 312 afs_free_call(call);
243 kfree(call);
244 _leave(" = %d", ret); 313 _leave(" = %d", ret);
245 return ret; 314 return ret;
246} 315}
@@ -257,15 +326,19 @@ static void afs_rx_interceptor(struct sock *sk, unsigned long user_call_ID,
257 326
258 _enter("%p,,%u", call, skb->mark); 327 _enter("%p,,%u", call, skb->mark);
259 328
329 _debug("ICPT %p{%u} [%d]",
330 skb, skb->mark, atomic_read(&afs_outstanding_skbs));
331
260 ASSERTCMP(sk, ==, afs_socket->sk); 332 ASSERTCMP(sk, ==, afs_socket->sk);
333 atomic_inc(&afs_outstanding_skbs);
261 334
262 if (!call) { 335 if (!call) {
263 /* its an incoming call for our callback service */ 336 /* its an incoming call for our callback service */
264 __skb_queue_tail(&afs_incoming_calls, skb); 337 skb_queue_tail(&afs_incoming_calls, skb);
265 schedule_work(&afs_collect_incoming_call_work); 338 schedule_work(&afs_collect_incoming_call_work);
266 } else { 339 } else {
267 /* route the messages directly to the appropriate call */ 340 /* route the messages directly to the appropriate call */
268 __skb_queue_tail(&call->rx_queue, skb); 341 skb_queue_tail(&call->rx_queue, skb);
269 call->wait_mode->rx_wakeup(call); 342 call->wait_mode->rx_wakeup(call);
270 } 343 }
271 344
@@ -317,9 +390,9 @@ static void afs_deliver_to_call(struct afs_call *call)
317 call->state = AFS_CALL_ERROR; 390 call->state = AFS_CALL_ERROR;
318 break; 391 break;
319 } 392 }
320 rxrpc_kernel_data_delivered(skb); 393 afs_data_delivered(skb);
321 skb = NULL; 394 skb = NULL;
322 break; 395 continue;
323 case RXRPC_SKB_MARK_FINAL_ACK: 396 case RXRPC_SKB_MARK_FINAL_ACK:
324 _debug("Rcv ACK"); 397 _debug("Rcv ACK");
325 call->state = AFS_CALL_COMPLETE; 398 call->state = AFS_CALL_COMPLETE;
@@ -350,19 +423,19 @@ static void afs_deliver_to_call(struct afs_call *call)
350 break; 423 break;
351 } 424 }
352 425
353 rxrpc_kernel_free_skb(skb); 426 afs_free_skb(skb);
354 } 427 }
355 428
356 /* make sure the queue is empty if the call is done with (we might have 429 /* make sure the queue is empty if the call is done with (we might have
357 * aborted the call early because of an unmarshalling error) */ 430 * aborted the call early because of an unmarshalling error) */
358 if (call->state >= AFS_CALL_COMPLETE) { 431 if (call->state >= AFS_CALL_COMPLETE) {
359 while ((skb = skb_dequeue(&call->rx_queue))) 432 while ((skb = skb_dequeue(&call->rx_queue)))
360 rxrpc_kernel_free_skb(skb); 433 afs_free_skb(skb);
361 if (call->incoming) { 434 if (call->incoming) {
362 rxrpc_kernel_end_call(call->rxcall); 435 rxrpc_kernel_end_call(call->rxcall);
436 call->rxcall = NULL;
363 call->type->destructor(call); 437 call->type->destructor(call);
364 ASSERT(skb_queue_empty(&call->rx_queue)); 438 afs_free_call(call);
365 kfree(call);
366 } 439 }
367 } 440 }
368 441
@@ -409,14 +482,14 @@ static int afs_wait_for_call_to_complete(struct afs_call *call)
409 _debug("call incomplete"); 482 _debug("call incomplete");
410 rxrpc_kernel_abort_call(call->rxcall, RX_CALL_DEAD); 483 rxrpc_kernel_abort_call(call->rxcall, RX_CALL_DEAD);
411 while ((skb = skb_dequeue(&call->rx_queue))) 484 while ((skb = skb_dequeue(&call->rx_queue)))
412 rxrpc_kernel_free_skb(skb); 485 afs_free_skb(skb);
413 } 486 }
414 487
415 _debug("call complete"); 488 _debug("call complete");
416 rxrpc_kernel_end_call(call->rxcall); 489 rxrpc_kernel_end_call(call->rxcall);
490 call->rxcall = NULL;
417 call->type->destructor(call); 491 call->type->destructor(call);
418 ASSERT(skb_queue_empty(&call->rx_queue)); 492 afs_free_call(call);
419 kfree(call);
420 _leave(" = %d", ret); 493 _leave(" = %d", ret);
421 return ret; 494 return ret;
422} 495}
@@ -459,9 +532,7 @@ static void afs_delete_async_call(struct work_struct *work)
459 532
460 _enter(""); 533 _enter("");
461 534
462 ASSERT(skb_queue_empty(&call->rx_queue)); 535 afs_free_call(call);
463 ASSERT(!work_pending(&call->async_work));
464 kfree(call);
465 536
466 _leave(""); 537 _leave("");
467} 538}
@@ -489,6 +560,7 @@ static void afs_process_async_call(struct work_struct *work)
489 560
490 /* kill the call */ 561 /* kill the call */
491 rxrpc_kernel_end_call(call->rxcall); 562 rxrpc_kernel_end_call(call->rxcall);
563 call->rxcall = NULL;
492 if (call->type->destructor) 564 if (call->type->destructor)
493 call->type->destructor(call); 565 call->type->destructor(call);
494 566
@@ -526,7 +598,7 @@ static void afs_collect_incoming_call(struct work_struct *work)
526 _debug("new call"); 598 _debug("new call");
527 599
528 /* don't need the notification */ 600 /* don't need the notification */
529 rxrpc_kernel_free_skb(skb); 601 afs_free_skb(skb);
530 602
531 if (!call) { 603 if (!call) {
532 call = kzalloc(sizeof(struct afs_call), GFP_KERNEL); 604 call = kzalloc(sizeof(struct afs_call), GFP_KERNEL);
@@ -541,6 +613,11 @@ static void afs_collect_incoming_call(struct work_struct *work)
541 init_waitqueue_head(&call->waitq); 613 init_waitqueue_head(&call->waitq);
542 skb_queue_head_init(&call->rx_queue); 614 skb_queue_head_init(&call->rx_queue);
543 call->state = AFS_CALL_AWAIT_OP_ID; 615 call->state = AFS_CALL_AWAIT_OP_ID;
616
617 _debug("CALL %p{%s} [%d]",
618 call, call->type->name,
619 atomic_read(&afs_outstanding_calls));
620 atomic_inc(&afs_outstanding_calls);
544 } 621 }
545 622
546 rxcall = rxrpc_kernel_accept_call(afs_socket, 623 rxcall = rxrpc_kernel_accept_call(afs_socket,
@@ -551,7 +628,8 @@ static void afs_collect_incoming_call(struct work_struct *work)
551 } 628 }
552 } 629 }
553 630
554 kfree(call); 631 if (call)
632 afs_free_call(call);
555} 633}
556 634
557/* 635/*
@@ -629,8 +707,7 @@ void afs_send_empty_reply(struct afs_call *call)
629 rxrpc_kernel_end_call(call->rxcall); 707 rxrpc_kernel_end_call(call->rxcall);
630 call->rxcall = NULL; 708 call->rxcall = NULL;
631 call->type->destructor(call); 709 call->type->destructor(call);
632 ASSERT(skb_queue_empty(&call->rx_queue)); 710 afs_free_call(call);
633 kfree(call);
634 _leave(" [error]"); 711 _leave(" [error]");
635 return; 712 return;
636 } 713 }