• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  *  linux/fs/ncpfs/sock.c
4  *
5  *  Copyright (C) 1992, 1993  Rick Sladkey
6  *
7  *  Modified 1995, 1996 by Volker Lendecke to be usable for ncp
8  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
9  *
10  */
11 
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 
14 #include <linux/time.h>
15 #include <linux/errno.h>
16 #include <linux/socket.h>
17 #include <linux/fcntl.h>
18 #include <linux/stat.h>
19 #include <linux/string.h>
20 #include <linux/sched/signal.h>
21 #include <linux/uaccess.h>
22 #include <linux/in.h>
23 #include <linux/net.h>
24 #include <linux/mm.h>
25 #include <linux/netdevice.h>
26 #include <linux/signal.h>
27 #include <linux/slab.h>
28 #include <net/scm.h>
29 #include <net/sock.h>
30 #include <linux/ipx.h>
31 #include <linux/poll.h>
32 #include <linux/file.h>
33 
34 #include "ncp_fs.h"
35 
36 #include "ncpsign_kernel.h"
37 
_recv(struct socket * sock,void * buf,int size,unsigned flags)38 static int _recv(struct socket *sock, void *buf, int size, unsigned flags)
39 {
40 	struct msghdr msg = {NULL, };
41 	struct kvec iov = {buf, size};
42 	return kernel_recvmsg(sock, &msg, &iov, 1, size, flags);
43 }
44 
_send(struct socket * sock,const void * buff,int len)45 static int _send(struct socket *sock, const void *buff, int len)
46 {
47 	struct msghdr msg = { .msg_flags = 0 };
48 	struct kvec vec = {.iov_base = (void *)buff, .iov_len = len};
49 	iov_iter_kvec(&msg.msg_iter, WRITE | ITER_KVEC, &vec, 1, len);
50 	return sock_sendmsg(sock, &msg);
51 }
52 
53 struct ncp_request_reply {
54 	struct list_head req;
55 	wait_queue_head_t wq;
56 	atomic_t refs;
57 	unsigned char* reply_buf;
58 	size_t datalen;
59 	int result;
60 	enum { RQ_DONE, RQ_INPROGRESS, RQ_QUEUED, RQ_IDLE, RQ_ABANDONED } status;
61 	struct iov_iter from;
62 	struct kvec tx_iov[3];
63 	u_int16_t tx_type;
64 	u_int32_t sign[6];
65 };
66 
ncp_alloc_req(void)67 static inline struct ncp_request_reply* ncp_alloc_req(void)
68 {
69 	struct ncp_request_reply *req;
70 
71 	req = kmalloc(sizeof(struct ncp_request_reply), GFP_KERNEL);
72 	if (!req)
73 		return NULL;
74 
75 	init_waitqueue_head(&req->wq);
76 	atomic_set(&req->refs, (1));
77 	req->status = RQ_IDLE;
78 
79 	return req;
80 }
81 
ncp_req_get(struct ncp_request_reply * req)82 static void ncp_req_get(struct ncp_request_reply *req)
83 {
84 	atomic_inc(&req->refs);
85 }
86 
ncp_req_put(struct ncp_request_reply * req)87 static void ncp_req_put(struct ncp_request_reply *req)
88 {
89 	if (atomic_dec_and_test(&req->refs))
90 		kfree(req);
91 }
92 
ncp_tcp_data_ready(struct sock * sk)93 void ncp_tcp_data_ready(struct sock *sk)
94 {
95 	struct ncp_server *server = sk->sk_user_data;
96 
97 	server->data_ready(sk);
98 	schedule_work(&server->rcv.tq);
99 }
100 
ncp_tcp_error_report(struct sock * sk)101 void ncp_tcp_error_report(struct sock *sk)
102 {
103 	struct ncp_server *server = sk->sk_user_data;
104 
105 	server->error_report(sk);
106 	schedule_work(&server->rcv.tq);
107 }
108 
ncp_tcp_write_space(struct sock * sk)109 void ncp_tcp_write_space(struct sock *sk)
110 {
111 	struct ncp_server *server = sk->sk_user_data;
112 
113 	/* We do not need any locking: we first set tx.creq, and then we do sendmsg,
114 	   not vice versa... */
115 	server->write_space(sk);
116 	if (server->tx.creq)
117 		schedule_work(&server->tx.tq);
118 }
119 
ncpdgram_timeout_call(unsigned long v)120 void ncpdgram_timeout_call(unsigned long v)
121 {
122 	struct ncp_server *server = (void*)v;
123 
124 	schedule_work(&server->timeout_tq);
125 }
126 
ncp_finish_request(struct ncp_server * server,struct ncp_request_reply * req,int result)127 static inline void ncp_finish_request(struct ncp_server *server, struct ncp_request_reply *req, int result)
128 {
129 	req->result = result;
130 	if (req->status != RQ_ABANDONED)
131 		memcpy(req->reply_buf, server->rxbuf, req->datalen);
132 	req->status = RQ_DONE;
133 	wake_up_all(&req->wq);
134 	ncp_req_put(req);
135 }
136 
__abort_ncp_connection(struct ncp_server * server)137 static void __abort_ncp_connection(struct ncp_server *server)
138 {
139 	struct ncp_request_reply *req;
140 
141 	ncp_invalidate_conn(server);
142 	del_timer(&server->timeout_tm);
143 	while (!list_empty(&server->tx.requests)) {
144 		req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
145 
146 		list_del_init(&req->req);
147 		ncp_finish_request(server, req, -EIO);
148 	}
149 	req = server->rcv.creq;
150 	if (req) {
151 		server->rcv.creq = NULL;
152 		ncp_finish_request(server, req, -EIO);
153 		server->rcv.ptr = NULL;
154 		server->rcv.state = 0;
155 	}
156 	req = server->tx.creq;
157 	if (req) {
158 		server->tx.creq = NULL;
159 		ncp_finish_request(server, req, -EIO);
160 	}
161 }
162 
get_conn_number(struct ncp_reply_header * rp)163 static inline int get_conn_number(struct ncp_reply_header *rp)
164 {
165 	return rp->conn_low | (rp->conn_high << 8);
166 }
167 
__ncp_abort_request(struct ncp_server * server,struct ncp_request_reply * req,int err)168 static inline void __ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
169 {
170 	/* If req is done, we got signal, but we also received answer... */
171 	switch (req->status) {
172 		case RQ_IDLE:
173 		case RQ_DONE:
174 			break;
175 		case RQ_QUEUED:
176 			list_del_init(&req->req);
177 			ncp_finish_request(server, req, err);
178 			break;
179 		case RQ_INPROGRESS:
180 			req->status = RQ_ABANDONED;
181 			break;
182 		case RQ_ABANDONED:
183 			break;
184 	}
185 }
186 
ncp_abort_request(struct ncp_server * server,struct ncp_request_reply * req,int err)187 static inline void ncp_abort_request(struct ncp_server *server, struct ncp_request_reply *req, int err)
188 {
189 	mutex_lock(&server->rcv.creq_mutex);
190 	__ncp_abort_request(server, req, err);
191 	mutex_unlock(&server->rcv.creq_mutex);
192 }
193 
__ncptcp_abort(struct ncp_server * server)194 static inline void __ncptcp_abort(struct ncp_server *server)
195 {
196 	__abort_ncp_connection(server);
197 }
198 
ncpdgram_send(struct socket * sock,struct ncp_request_reply * req)199 static int ncpdgram_send(struct socket *sock, struct ncp_request_reply *req)
200 {
201 	struct msghdr msg = { .msg_iter = req->from, .msg_flags = MSG_DONTWAIT };
202 	return sock_sendmsg(sock, &msg);
203 }
204 
__ncptcp_try_send(struct ncp_server * server)205 static void __ncptcp_try_send(struct ncp_server *server)
206 {
207 	struct ncp_request_reply *rq;
208 	struct msghdr msg = { .msg_flags = MSG_NOSIGNAL | MSG_DONTWAIT };
209 	int result;
210 
211 	rq = server->tx.creq;
212 	if (!rq)
213 		return;
214 
215 	msg.msg_iter = rq->from;
216 	result = sock_sendmsg(server->ncp_sock, &msg);
217 
218 	if (result == -EAGAIN)
219 		return;
220 
221 	if (result < 0) {
222 		pr_err("tcp: Send failed: %d\n", result);
223 		__ncp_abort_request(server, rq, result);
224 		return;
225 	}
226 	if (!msg_data_left(&msg)) {
227 		server->rcv.creq = rq;
228 		server->tx.creq = NULL;
229 		return;
230 	}
231 	rq->from = msg.msg_iter;
232 }
233 
ncp_init_header(struct ncp_server * server,struct ncp_request_reply * req,struct ncp_request_header * h)234 static inline void ncp_init_header(struct ncp_server *server, struct ncp_request_reply *req, struct ncp_request_header *h)
235 {
236 	req->status = RQ_INPROGRESS;
237 	h->conn_low = server->connection;
238 	h->conn_high = server->connection >> 8;
239 	h->sequence = ++server->sequence;
240 }
241 
ncpdgram_start_request(struct ncp_server * server,struct ncp_request_reply * req)242 static void ncpdgram_start_request(struct ncp_server *server, struct ncp_request_reply *req)
243 {
244 	size_t signlen, len = req->tx_iov[1].iov_len;
245 	struct ncp_request_header *h = req->tx_iov[1].iov_base;
246 
247 	ncp_init_header(server, req, h);
248 	signlen = sign_packet(server,
249 			req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
250 			len - sizeof(struct ncp_request_header) + 1,
251 			cpu_to_le32(len), req->sign);
252 	if (signlen) {
253 		/* NCP over UDP appends signature */
254 		req->tx_iov[2].iov_base = req->sign;
255 		req->tx_iov[2].iov_len = signlen;
256 	}
257 	iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
258 			req->tx_iov + 1, signlen ? 2 : 1, len + signlen);
259 	server->rcv.creq = req;
260 	server->timeout_last = server->m.time_out;
261 	server->timeout_retries = server->m.retry_count;
262 	ncpdgram_send(server->ncp_sock, req);
263 	mod_timer(&server->timeout_tm, jiffies + server->m.time_out);
264 }
265 
266 #define NCP_TCP_XMIT_MAGIC	(0x446D6454)
267 #define NCP_TCP_XMIT_VERSION	(1)
268 #define NCP_TCP_RCVD_MAGIC	(0x744E6350)
269 
ncptcp_start_request(struct ncp_server * server,struct ncp_request_reply * req)270 static void ncptcp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
271 {
272 	size_t signlen, len = req->tx_iov[1].iov_len;
273 	struct ncp_request_header *h = req->tx_iov[1].iov_base;
274 
275 	ncp_init_header(server, req, h);
276 	signlen = sign_packet(server, req->tx_iov[1].iov_base + sizeof(struct ncp_request_header) - 1,
277 			len - sizeof(struct ncp_request_header) + 1,
278 			cpu_to_be32(len + 24), req->sign + 4) + 16;
279 
280 	req->sign[0] = htonl(NCP_TCP_XMIT_MAGIC);
281 	req->sign[1] = htonl(len + signlen);
282 	req->sign[2] = htonl(NCP_TCP_XMIT_VERSION);
283 	req->sign[3] = htonl(req->datalen + 8);
284 	/* NCP over TCP prepends signature */
285 	req->tx_iov[0].iov_base = req->sign;
286 	req->tx_iov[0].iov_len = signlen;
287 	iov_iter_kvec(&req->from, WRITE | ITER_KVEC,
288 			req->tx_iov, 2, len + signlen);
289 
290 	server->tx.creq = req;
291 	__ncptcp_try_send(server);
292 }
293 
__ncp_start_request(struct ncp_server * server,struct ncp_request_reply * req)294 static inline void __ncp_start_request(struct ncp_server *server, struct ncp_request_reply *req)
295 {
296 	/* we copy the data so that we do not depend on the caller
297 	   staying alive */
298 	memcpy(server->txbuf, req->tx_iov[1].iov_base, req->tx_iov[1].iov_len);
299 	req->tx_iov[1].iov_base = server->txbuf;
300 
301 	if (server->ncp_sock->type == SOCK_STREAM)
302 		ncptcp_start_request(server, req);
303 	else
304 		ncpdgram_start_request(server, req);
305 }
306 
ncp_add_request(struct ncp_server * server,struct ncp_request_reply * req)307 static int ncp_add_request(struct ncp_server *server, struct ncp_request_reply *req)
308 {
309 	mutex_lock(&server->rcv.creq_mutex);
310 	if (!ncp_conn_valid(server)) {
311 		mutex_unlock(&server->rcv.creq_mutex);
312 		pr_err("tcp: Server died\n");
313 		return -EIO;
314 	}
315 	ncp_req_get(req);
316 	if (server->tx.creq || server->rcv.creq) {
317 		req->status = RQ_QUEUED;
318 		list_add_tail(&req->req, &server->tx.requests);
319 		mutex_unlock(&server->rcv.creq_mutex);
320 		return 0;
321 	}
322 	__ncp_start_request(server, req);
323 	mutex_unlock(&server->rcv.creq_mutex);
324 	return 0;
325 }
326 
__ncp_next_request(struct ncp_server * server)327 static void __ncp_next_request(struct ncp_server *server)
328 {
329 	struct ncp_request_reply *req;
330 
331 	server->rcv.creq = NULL;
332 	if (list_empty(&server->tx.requests)) {
333 		return;
334 	}
335 	req = list_entry(server->tx.requests.next, struct ncp_request_reply, req);
336 	list_del_init(&req->req);
337 	__ncp_start_request(server, req);
338 }
339 
info_server(struct ncp_server * server,unsigned int id,const void * data,size_t len)340 static void info_server(struct ncp_server *server, unsigned int id, const void * data, size_t len)
341 {
342 	if (server->info_sock) {
343 		struct msghdr msg = { .msg_flags = MSG_NOSIGNAL };
344 		__be32 hdr[2] = {cpu_to_be32(len + 8), cpu_to_be32(id)};
345 		struct kvec iov[2] = {
346 			{.iov_base = hdr, .iov_len = 8},
347 			{.iov_base = (void *)data, .iov_len = len},
348 		};
349 
350 		iov_iter_kvec(&msg.msg_iter, ITER_KVEC | WRITE,
351 				iov, 2, len + 8);
352 
353 		sock_sendmsg(server->info_sock, &msg);
354 	}
355 }
356 
ncpdgram_rcv_proc(struct work_struct * work)357 void ncpdgram_rcv_proc(struct work_struct *work)
358 {
359 	struct ncp_server *server =
360 		container_of(work, struct ncp_server, rcv.tq);
361 	struct socket* sock;
362 
363 	sock = server->ncp_sock;
364 
365 	while (1) {
366 		struct ncp_reply_header reply;
367 		int result;
368 
369 		result = _recv(sock, &reply, sizeof(reply), MSG_PEEK | MSG_DONTWAIT);
370 		if (result < 0) {
371 			break;
372 		}
373 		if (result >= sizeof(reply)) {
374 			struct ncp_request_reply *req;
375 
376 			if (reply.type == NCP_WATCHDOG) {
377 				unsigned char buf[10];
378 
379 				if (server->connection != get_conn_number(&reply)) {
380 					goto drop;
381 				}
382 				result = _recv(sock, buf, sizeof(buf), MSG_DONTWAIT);
383 				if (result < 0) {
384 					ncp_dbg(1, "recv failed with %d\n", result);
385 					continue;
386 				}
387 				if (result < 10) {
388 					ncp_dbg(1, "too short (%u) watchdog packet\n", result);
389 					continue;
390 				}
391 				if (buf[9] != '?') {
392 					ncp_dbg(1, "bad signature (%02X) in watchdog packet\n", buf[9]);
393 					continue;
394 				}
395 				buf[9] = 'Y';
396 				_send(sock, buf, sizeof(buf));
397 				continue;
398 			}
399 			if (reply.type != NCP_POSITIVE_ACK && reply.type != NCP_REPLY) {
400 				result = _recv(sock, server->unexpected_packet.data, sizeof(server->unexpected_packet.data), MSG_DONTWAIT);
401 				if (result < 0) {
402 					continue;
403 				}
404 				info_server(server, 0, server->unexpected_packet.data, result);
405 				continue;
406 			}
407 			mutex_lock(&server->rcv.creq_mutex);
408 			req = server->rcv.creq;
409 			if (req && (req->tx_type == NCP_ALLOC_SLOT_REQUEST || (server->sequence == reply.sequence &&
410 					server->connection == get_conn_number(&reply)))) {
411 				if (reply.type == NCP_POSITIVE_ACK) {
412 					server->timeout_retries = server->m.retry_count;
413 					server->timeout_last = NCP_MAX_RPC_TIMEOUT;
414 					mod_timer(&server->timeout_tm, jiffies + NCP_MAX_RPC_TIMEOUT);
415 				} else if (reply.type == NCP_REPLY) {
416 					result = _recv(sock, server->rxbuf, req->datalen, MSG_DONTWAIT);
417 #ifdef CONFIG_NCPFS_PACKET_SIGNING
418 					if (result >= 0 && server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
419 						if (result < 8 + 8) {
420 							result = -EIO;
421 						} else {
422 							unsigned int hdrl;
423 
424 							result -= 8;
425 							hdrl = sock->sk->sk_family == AF_INET ? 8 : 6;
426 							if (sign_verify_reply(server, server->rxbuf + hdrl, result - hdrl, cpu_to_le32(result), server->rxbuf + result)) {
427 								pr_info("Signature violation\n");
428 								result = -EIO;
429 							}
430 						}
431 					}
432 #endif
433 					del_timer(&server->timeout_tm);
434 				     	server->rcv.creq = NULL;
435 					ncp_finish_request(server, req, result);
436 					__ncp_next_request(server);
437 					mutex_unlock(&server->rcv.creq_mutex);
438 					continue;
439 				}
440 			}
441 			mutex_unlock(&server->rcv.creq_mutex);
442 		}
443 drop:;
444 		_recv(sock, &reply, sizeof(reply), MSG_DONTWAIT);
445 	}
446 }
447 
__ncpdgram_timeout_proc(struct ncp_server * server)448 static void __ncpdgram_timeout_proc(struct ncp_server *server)
449 {
450 	/* If timer is pending, we are processing another request... */
451 	if (!timer_pending(&server->timeout_tm)) {
452 		struct ncp_request_reply* req;
453 
454 		req = server->rcv.creq;
455 		if (req) {
456 			int timeout;
457 
458 			if (server->m.flags & NCP_MOUNT_SOFT) {
459 				if (server->timeout_retries-- == 0) {
460 					__ncp_abort_request(server, req, -ETIMEDOUT);
461 					return;
462 				}
463 			}
464 			/* Ignore errors */
465 			ncpdgram_send(server->ncp_sock, req);
466 			timeout = server->timeout_last << 1;
467 			if (timeout > NCP_MAX_RPC_TIMEOUT) {
468 				timeout = NCP_MAX_RPC_TIMEOUT;
469 			}
470 			server->timeout_last = timeout;
471 			mod_timer(&server->timeout_tm, jiffies + timeout);
472 		}
473 	}
474 }
475 
ncpdgram_timeout_proc(struct work_struct * work)476 void ncpdgram_timeout_proc(struct work_struct *work)
477 {
478 	struct ncp_server *server =
479 		container_of(work, struct ncp_server, timeout_tq);
480 	mutex_lock(&server->rcv.creq_mutex);
481 	__ncpdgram_timeout_proc(server);
482 	mutex_unlock(&server->rcv.creq_mutex);
483 }
484 
do_tcp_rcv(struct ncp_server * server,void * buffer,size_t len)485 static int do_tcp_rcv(struct ncp_server *server, void *buffer, size_t len)
486 {
487 	int result;
488 
489 	if (buffer) {
490 		result = _recv(server->ncp_sock, buffer, len, MSG_DONTWAIT);
491 	} else {
492 		static unsigned char dummy[1024];
493 
494 		if (len > sizeof(dummy)) {
495 			len = sizeof(dummy);
496 		}
497 		result = _recv(server->ncp_sock, dummy, len, MSG_DONTWAIT);
498 	}
499 	if (result < 0) {
500 		return result;
501 	}
502 	if (result > len) {
503 		pr_err("tcp: bug in recvmsg (%u > %zu)\n", result, len);
504 		return -EIO;
505 	}
506 	return result;
507 }
508 
__ncptcp_rcv_proc(struct ncp_server * server)509 static int __ncptcp_rcv_proc(struct ncp_server *server)
510 {
511 	/* We have to check the result, so store the complete header */
512 	while (1) {
513 		int result;
514 		struct ncp_request_reply *req;
515 		int datalen;
516 		int type;
517 
518 		while (server->rcv.len) {
519 			result = do_tcp_rcv(server, server->rcv.ptr, server->rcv.len);
520 			if (result == -EAGAIN) {
521 				return 0;
522 			}
523 			if (result <= 0) {
524 				req = server->rcv.creq;
525 				if (req) {
526 					__ncp_abort_request(server, req, -EIO);
527 				} else {
528 					__ncptcp_abort(server);
529 				}
530 				if (result < 0) {
531 					pr_err("tcp: error in recvmsg: %d\n", result);
532 				} else {
533 					ncp_dbg(1, "tcp: EOF\n");
534 				}
535 				return -EIO;
536 			}
537 			if (server->rcv.ptr) {
538 				server->rcv.ptr += result;
539 			}
540 			server->rcv.len -= result;
541 		}
542 		switch (server->rcv.state) {
543 			case 0:
544 				if (server->rcv.buf.magic != htonl(NCP_TCP_RCVD_MAGIC)) {
545 					pr_err("tcp: Unexpected reply type %08X\n", ntohl(server->rcv.buf.magic));
546 					__ncptcp_abort(server);
547 					return -EIO;
548 				}
549 				datalen = ntohl(server->rcv.buf.len) & 0x0FFFFFFF;
550 				if (datalen < 10) {
551 					pr_err("tcp: Unexpected reply len %d\n", datalen);
552 					__ncptcp_abort(server);
553 					return -EIO;
554 				}
555 #ifdef CONFIG_NCPFS_PACKET_SIGNING
556 				if (server->sign_active) {
557 					if (datalen < 18) {
558 						pr_err("tcp: Unexpected reply len %d\n", datalen);
559 						__ncptcp_abort(server);
560 						return -EIO;
561 					}
562 					server->rcv.buf.len = datalen - 8;
563 					server->rcv.ptr = (unsigned char*)&server->rcv.buf.p1;
564 					server->rcv.len = 8;
565 					server->rcv.state = 4;
566 					break;
567 				}
568 #endif
569 				type = ntohs(server->rcv.buf.type);
570 #ifdef CONFIG_NCPFS_PACKET_SIGNING
571 cont:;
572 #endif
573 				if (type != NCP_REPLY) {
574 					if (datalen - 8 <= sizeof(server->unexpected_packet.data)) {
575 						*(__u16*)(server->unexpected_packet.data) = htons(type);
576 						server->unexpected_packet.len = datalen - 8;
577 
578 						server->rcv.state = 5;
579 						server->rcv.ptr = server->unexpected_packet.data + 2;
580 						server->rcv.len = datalen - 10;
581 						break;
582 					}
583 					ncp_dbg(1, "tcp: Unexpected NCP type %02X\n", type);
584 skipdata2:;
585 					server->rcv.state = 2;
586 skipdata:;
587 					server->rcv.ptr = NULL;
588 					server->rcv.len = datalen - 10;
589 					break;
590 				}
591 				req = server->rcv.creq;
592 				if (!req) {
593 					ncp_dbg(1, "Reply without appropriate request\n");
594 					goto skipdata2;
595 				}
596 				if (datalen > req->datalen + 8) {
597 					pr_err("tcp: Unexpected reply len %d (expected at most %zd)\n", datalen, req->datalen + 8);
598 					server->rcv.state = 3;
599 					goto skipdata;
600 				}
601 				req->datalen = datalen - 8;
602 				((struct ncp_reply_header*)server->rxbuf)->type = NCP_REPLY;
603 				server->rcv.ptr = server->rxbuf + 2;
604 				server->rcv.len = datalen - 10;
605 				server->rcv.state = 1;
606 				break;
607 #ifdef CONFIG_NCPFS_PACKET_SIGNING
608 			case 4:
609 				datalen = server->rcv.buf.len;
610 				type = ntohs(server->rcv.buf.type2);
611 				goto cont;
612 #endif
613 			case 1:
614 				req = server->rcv.creq;
615 				if (req->tx_type != NCP_ALLOC_SLOT_REQUEST) {
616 					if (((struct ncp_reply_header*)server->rxbuf)->sequence != server->sequence) {
617 						pr_err("tcp: Bad sequence number\n");
618 						__ncp_abort_request(server, req, -EIO);
619 						return -EIO;
620 					}
621 					if ((((struct ncp_reply_header*)server->rxbuf)->conn_low | (((struct ncp_reply_header*)server->rxbuf)->conn_high << 8)) != server->connection) {
622 						pr_err("tcp: Connection number mismatch\n");
623 						__ncp_abort_request(server, req, -EIO);
624 						return -EIO;
625 					}
626 				}
627 #ifdef CONFIG_NCPFS_PACKET_SIGNING
628 				if (server->sign_active && req->tx_type != NCP_DEALLOC_SLOT_REQUEST) {
629 					if (sign_verify_reply(server, server->rxbuf + 6, req->datalen - 6, cpu_to_be32(req->datalen + 16), &server->rcv.buf.type)) {
630 						pr_err("tcp: Signature violation\n");
631 						__ncp_abort_request(server, req, -EIO);
632 						return -EIO;
633 					}
634 				}
635 #endif
636 				ncp_finish_request(server, req, req->datalen);
637 			nextreq:;
638 				__ncp_next_request(server);
639 			case 2:
640 			next:;
641 				server->rcv.ptr = (unsigned char*)&server->rcv.buf;
642 				server->rcv.len = 10;
643 				server->rcv.state = 0;
644 				break;
645 			case 3:
646 				ncp_finish_request(server, server->rcv.creq, -EIO);
647 				goto nextreq;
648 			case 5:
649 				info_server(server, 0, server->unexpected_packet.data, server->unexpected_packet.len);
650 				goto next;
651 		}
652 	}
653 }
654 
ncp_tcp_rcv_proc(struct work_struct * work)655 void ncp_tcp_rcv_proc(struct work_struct *work)
656 {
657 	struct ncp_server *server =
658 		container_of(work, struct ncp_server, rcv.tq);
659 
660 	mutex_lock(&server->rcv.creq_mutex);
661 	__ncptcp_rcv_proc(server);
662 	mutex_unlock(&server->rcv.creq_mutex);
663 }
664 
ncp_tcp_tx_proc(struct work_struct * work)665 void ncp_tcp_tx_proc(struct work_struct *work)
666 {
667 	struct ncp_server *server =
668 		container_of(work, struct ncp_server, tx.tq);
669 
670 	mutex_lock(&server->rcv.creq_mutex);
671 	__ncptcp_try_send(server);
672 	mutex_unlock(&server->rcv.creq_mutex);
673 }
674 
do_ncp_rpc_call(struct ncp_server * server,int size,unsigned char * reply_buf,int max_reply_size)675 static int do_ncp_rpc_call(struct ncp_server *server, int size,
676 		unsigned char* reply_buf, int max_reply_size)
677 {
678 	int result;
679 	struct ncp_request_reply *req;
680 
681 	req = ncp_alloc_req();
682 	if (!req)
683 		return -ENOMEM;
684 
685 	req->reply_buf = reply_buf;
686 	req->datalen = max_reply_size;
687 	req->tx_iov[1].iov_base = server->packet;
688 	req->tx_iov[1].iov_len = size;
689 	req->tx_type = *(u_int16_t*)server->packet;
690 
691 	result = ncp_add_request(server, req);
692 	if (result < 0)
693 		goto out;
694 
695 	if (wait_event_interruptible(req->wq, req->status == RQ_DONE)) {
696 		ncp_abort_request(server, req, -EINTR);
697 		result = -EINTR;
698 		goto out;
699 	}
700 
701 	result = req->result;
702 
703 out:
704 	ncp_req_put(req);
705 
706 	return result;
707 }
708 
709 /*
710  * We need the server to be locked here, so check!
711  */
712 
ncp_do_request(struct ncp_server * server,int size,void * reply,int max_reply_size)713 static int ncp_do_request(struct ncp_server *server, int size,
714 		void* reply, int max_reply_size)
715 {
716 	int result;
717 
718 	if (server->lock == 0) {
719 		pr_err("Server not locked!\n");
720 		return -EIO;
721 	}
722 	if (!ncp_conn_valid(server)) {
723 		return -EIO;
724 	}
725 	{
726 		sigset_t old_set;
727 		unsigned long mask, flags;
728 
729 		spin_lock_irqsave(&current->sighand->siglock, flags);
730 		old_set = current->blocked;
731 		if (current->flags & PF_EXITING)
732 			mask = 0;
733 		else
734 			mask = sigmask(SIGKILL);
735 		if (server->m.flags & NCP_MOUNT_INTR) {
736 			/* FIXME: This doesn't seem right at all.  So, like,
737 			   we can't handle SIGINT and get whatever to stop?
738 			   What if we've blocked it ourselves?  What about
739 			   alarms?  Why, in fact, are we mucking with the
740 			   sigmask at all? -- r~ */
741 			if (current->sighand->action[SIGINT - 1].sa.sa_handler == SIG_DFL)
742 				mask |= sigmask(SIGINT);
743 			if (current->sighand->action[SIGQUIT - 1].sa.sa_handler == SIG_DFL)
744 				mask |= sigmask(SIGQUIT);
745 		}
746 		siginitsetinv(&current->blocked, mask);
747 		recalc_sigpending();
748 		spin_unlock_irqrestore(&current->sighand->siglock, flags);
749 
750 		result = do_ncp_rpc_call(server, size, reply, max_reply_size);
751 
752 		spin_lock_irqsave(&current->sighand->siglock, flags);
753 		current->blocked = old_set;
754 		recalc_sigpending();
755 		spin_unlock_irqrestore(&current->sighand->siglock, flags);
756 	}
757 
758 	ncp_dbg(2, "do_ncp_rpc_call returned %d\n", result);
759 
760 	return result;
761 }
762 
763 /* ncp_do_request assures that at least a complete reply header is
764  * received. It assumes that server->current_size contains the ncp
765  * request size
766  */
ncp_request2(struct ncp_server * server,int function,void * rpl,int size)767 int ncp_request2(struct ncp_server *server, int function,
768 		void* rpl, int size)
769 {
770 	struct ncp_request_header *h;
771 	struct ncp_reply_header* reply = rpl;
772 	int result;
773 
774 	h = (struct ncp_request_header *) (server->packet);
775 	if (server->has_subfunction != 0) {
776 		*(__u16 *) & (h->data[0]) = htons(server->current_size - sizeof(*h) - 2);
777 	}
778 	h->type = NCP_REQUEST;
779 	/*
780 	 * The server shouldn't know or care what task is making a
781 	 * request, so we always use the same task number.
782 	 */
783 	h->task = 2; /* (current->pid) & 0xff; */
784 	h->function = function;
785 
786 	result = ncp_do_request(server, server->current_size, reply, size);
787 	if (result < 0) {
788 		ncp_dbg(1, "ncp_request_error: %d\n", result);
789 		goto out;
790 	}
791 	server->completion = reply->completion_code;
792 	server->conn_status = reply->connection_state;
793 	server->reply_size = result;
794 	server->ncp_reply_size = result - sizeof(struct ncp_reply_header);
795 
796 	result = reply->completion_code;
797 
798 	if (result != 0)
799 		ncp_vdbg("completion code=%x\n", result);
800 out:
801 	return result;
802 }
803 
ncp_connect(struct ncp_server * server)804 int ncp_connect(struct ncp_server *server)
805 {
806 	struct ncp_request_header *h;
807 	int result;
808 
809 	server->connection = 0xFFFF;
810 	server->sequence = 255;
811 
812 	h = (struct ncp_request_header *) (server->packet);
813 	h->type = NCP_ALLOC_SLOT_REQUEST;
814 	h->task		= 2; /* see above */
815 	h->function	= 0;
816 
817 	result = ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
818 	if (result < 0)
819 		goto out;
820 	server->connection = h->conn_low + (h->conn_high * 256);
821 	result = 0;
822 out:
823 	return result;
824 }
825 
ncp_disconnect(struct ncp_server * server)826 int ncp_disconnect(struct ncp_server *server)
827 {
828 	struct ncp_request_header *h;
829 
830 	h = (struct ncp_request_header *) (server->packet);
831 	h->type = NCP_DEALLOC_SLOT_REQUEST;
832 	h->task		= 2; /* see above */
833 	h->function	= 0;
834 
835 	return ncp_do_request(server, sizeof(*h), server->packet, server->packet_size);
836 }
837 
ncp_lock_server(struct ncp_server * server)838 void ncp_lock_server(struct ncp_server *server)
839 {
840 	mutex_lock(&server->mutex);
841 	if (server->lock)
842 		pr_warn("%s: was locked!\n", __func__);
843 	server->lock = 1;
844 }
845 
ncp_unlock_server(struct ncp_server * server)846 void ncp_unlock_server(struct ncp_server *server)
847 {
848 	if (!server->lock) {
849 		pr_warn("%s: was not locked!\n", __func__);
850 		return;
851 	}
852 	server->lock = 0;
853 	mutex_unlock(&server->mutex);
854 }
855