X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/8f6c56a50524aa785f7e596d52dddfb331e18961..9d749ea394c01276fa19e397e70f46858e849c76:/bsd/nfs/krpc_subr.c diff --git a/bsd/nfs/krpc_subr.c b/bsd/nfs/krpc_subr.c index f342ae476..7ae7758e0 100644 --- a/bsd/nfs/krpc_subr.c +++ b/bsd/nfs/krpc_subr.c @@ -1,8 +1,8 @@ /* - * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,12 +22,12 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ /* - * Copyright (c) 1994 Gordon Ross, Adam Glass + * Copyright (c) 1994 Gordon Ross, Adam Glass * Copyright (c) 1992 Regents of the University of California. * All rights reserved. * @@ -76,7 +76,6 @@ #include #include #include -#include #include #include @@ -127,6 +126,7 @@ struct rpc_reply { }; #define MIN_REPLY_HDR 16 /* xid, dir, astat, errno */ +#define REPLY_SIZE 24 /* xid, dir, astat, rpu_ok */ /* * What is the longest we will wait before re-sending a request? @@ -147,10 +147,10 @@ struct rpc_reply { * Returns non-zero error on failure. */ int -krpc_portmap(sin, prog, vers, proto, portp) - struct sockaddr_in *sin; /* server address */ - u_int prog, vers, proto; /* host order */ - u_int16_t *portp; /* network order */ +krpc_portmap( + struct sockaddr_in *sin, /* server address */ + u_int prog, u_int vers, u_int proto, /* host order */ + u_int16_t *portp) /* network order */ { struct sdata { u_int32_t prog; /* call program */ @@ -190,9 +190,12 @@ krpc_portmap(sin, prog, vers, proto, portp) return error; rdata = mbuf_data(m); - *portp = rdata->port; - if (!rdata->port) + if (mbuf_len(m) >= sizeof(*rdata)) { + *portp = rdata->port; + } + + if (mbuf_len(m) < sizeof(*rdata) || !rdata->port) error = EPROGUNAVAIL; mbuf_freem(m); @@ -205,21 +208,22 @@ krpc_portmap(sin, prog, vers, proto, portp) * the address from whence the response came is saved there. */ int -krpc_call(sa, sotype, prog, vers, func, data, from_p) - struct sockaddr_in *sa; - u_int sotype, prog, vers, func; - mbuf_t *data; /* input/output */ - struct sockaddr_in *from_p; /* output */ +krpc_call( + struct sockaddr_in *sa, + u_int sotype, u_int prog, u_int vers, u_int func, + mbuf_t *data, /* input/output */ + struct sockaddr_in *from_p) /* output */ { socket_t so; struct sockaddr_in *sin; mbuf_t m, nam, mhead; struct rpc_call *call; struct rpc_reply *reply; - int error, timo, secs, len; + int error, timo, secs; + size_t len; static u_int32_t xid = ~0xFF; u_int16_t tport; - int maxpacket = 1<<16; + size_t maxpacket = 1<<16; /* * Validate address family. @@ -235,7 +239,7 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) * Create socket and set its recieve timeout. */ if ((error = sock_socket(AF_INET, sotype, 0, 0, 0, &so))) - goto out; + goto out1; { struct timeval tv; @@ -335,7 +339,7 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) */ if (sotype == SOCK_STREAM) { /* first, fill in RPC record marker */ - u_long *recmark = mbuf_data(mhead); + u_int32_t *recmark = mbuf_data(mhead); *recmark = htonl(0x80000000 | (mbuf_pkthdr_len(mhead) - 4)); call = (struct rpc_call *)(recmark + 1); } else { @@ -400,11 +404,11 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) } if (sotype == SOCK_STREAM) { int maxretries = 60; - struct iovec_32 aio; - aio.iov_base = (uintptr_t) &len; - aio.iov_len = sizeof(u_long); + struct iovec aio; + aio.iov_base = &len; + aio.iov_len = sizeof(u_int32_t); bzero(&msg, sizeof(msg)); - msg.msg_iov = (struct iovec *) &aio; + msg.msg_iov = &aio; msg.msg_iovlen = 1; do { error = sock_receive(so, &msg, MSG_WAITALL, &readlen); @@ -414,8 +418,8 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) if (!error && readlen < aio.iov_len) { /* only log a message if we got a partial word */ if (readlen != 0) - printf("short receive (%d/%d) from server " IP_FORMAT "\n", - readlen, sizeof(u_long), IP_LIST(&(sin->sin_addr.s_addr))); + printf("short receive (%ld/%ld) from server " IP_FORMAT "\n", + readlen, sizeof(u_int32_t), IP_LIST(&(sin->sin_addr.s_addr))); error = EPIPE; } if (error) @@ -426,7 +430,7 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) * and forcing a disconnect/reconnect is all I can do. */ if (len > maxpacket) { - printf("impossible packet length (%d) from server %s\n", + printf("impossible packet length (%ld) from server " IP_FORMAT "\n", len, IP_LIST(&(sin->sin_addr.s_addr))); error = EFBIG; goto out; @@ -437,8 +441,8 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) error = sock_receivembuf(so, NULL, &m, MSG_WAITALL, &readlen); } while (error == EWOULDBLOCK); - if (!error && (len > (int)readlen)) { - printf("short receive (%d/%d) from server %s\n", + if (!error && (len > readlen)) { + printf("short receive (%ld/%ld) from server " IP_FORMAT "\n", readlen, len, IP_LIST(&(sin->sin_addr.s_addr))); error = EPIPE; } @@ -489,8 +493,16 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) goto out; } + + if (mbuf_len(m) < REPLY_SIZE) { + error = RPC_SYSTEM_ERR; + } + else { + error = ntohl(reply->rp_u.rpu_ok.rp_rstatus); + } + /* Did the call succeed? */ - if ((error = ntohl(reply->rp_u.rpu_ok.rp_rstatus)) != 0) { + if (error != 0) { printf("rpc status=%d\n", error); /* convert rpc error to errno */ switch (error) { @@ -556,8 +568,9 @@ krpc_call(sa, sotype, prog, vers, func, data, from_p) /* result */ *data = m; out: + sock_close(so); +out1: if (nam) mbuf_freem(nam); if (mhead) mbuf_freem(mhead); - sock_close(so); return error; }