blob: c9e94363f10bab5ec1256f5ac9edc81ece75cce8 [file] [log] [blame]
George Burgess IVb97049c2017-07-24 15:05:05 -07001/*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#ifndef _SYS_SOCKET_H_
30#error "Never include this file directly; instead, include <sys/socket.h>"
31#endif
32
33extern ssize_t __sendto_chk(int, const void*, size_t, size_t, int, const struct sockaddr*,
34 socklen_t) __INTRODUCED_IN(26);
35ssize_t __recvfrom_chk(int, void*, size_t, size_t, int, struct sockaddr*,
36 socklen_t*) __INTRODUCED_IN(21);
37
38#if defined(__BIONIC_FORTIFY)
39
40#define __recvfrom_bad_size "recvfrom called with size bigger than buffer"
41#define __sendto_bad_size "sendto called with size bigger than buffer"
42#if defined(__clang__)
43#if __ANDROID_API__ >= __ANDROID_API_N__
44__BIONIC_ERROR_FUNCTION_VISIBILITY
45ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
46 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
47 __overloadable
48 __enable_if(__bos(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
49 __bos(buf) < len, "selected when the buffer is too small")
50 __errorattr(__recvfrom_bad_size);
51
52__BIONIC_FORTIFY_INLINE
53ssize_t recvfrom(int fd, void* const buf __pass_object_size0, size_t len,
54 int flags, struct sockaddr* src_addr, socklen_t* addr_len)
55 __overloadable {
56 size_t bos = __bos0(buf);
57
58 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
59 return __call_bypassing_fortify(recvfrom)(fd, buf, len, flags, src_addr,
60 addr_len);
61 }
62
63 return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
64}
65#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
66
67#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
68__BIONIC_ERROR_FUNCTION_VISIBILITY
69ssize_t sendto(int fd, const void* buf, size_t len, int flags,
70 const struct sockaddr* dest_addr, socklen_t addr_len)
71 __overloadable
72 __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
73 __bos0(buf) < len, "selected when the buffer is too small")
74 __errorattr(__sendto_bad_size);
75
76__BIONIC_FORTIFY_INLINE
77ssize_t sendto(int fd, const void* const buf __pass_object_size0, size_t len,
78 int flags, const struct sockaddr* dest_addr, socklen_t addr_len)
79 __overloadable {
80 size_t bos = __bos0(buf);
81
82 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
83 return __call_bypassing_fortify(sendto)(fd, buf, len, flags, dest_addr,
84 addr_len);
85 }
86
87 return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
88}
89
90__BIONIC_ERROR_FUNCTION_VISIBILITY
91ssize_t send(int socket, const void* buf, size_t len, int flags)
92 __overloadable
93 __enable_if(__bos0(buf) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
94 __bos0(buf) < len, "selected when the buffer is too small")
95 __errorattr("send called with size bigger than buffer");
96#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
97
98#else /* defined(__clang__) */
99ssize_t __recvfrom_real(int, void*, size_t, int, struct sockaddr*, socklen_t*) __RENAME(recvfrom);
100__errordecl(__recvfrom_error, __recvfrom_bad_size);
101
102extern ssize_t __sendto_real(int, const void*, size_t, int, const struct sockaddr*, socklen_t)
103 __RENAME(sendto);
104__errordecl(__sendto_error, __sendto_bad_size);
105
106#if __ANDROID_API__ >= __ANDROID_API_N__
107__BIONIC_FORTIFY_INLINE
108ssize_t recvfrom(int fd, void* buf, size_t len, int flags,
109 struct sockaddr* src_addr, socklen_t* addr_len) {
110 size_t bos = __bos0(buf);
111
112 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
113 return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
114 }
115
116 if (__builtin_constant_p(len) && (len <= bos)) {
117 return __recvfrom_real(fd, buf, len, flags, src_addr, addr_len);
118 }
119
120 if (__builtin_constant_p(len) && (len > bos)) {
121 __recvfrom_error();
122 }
123
124 return __recvfrom_chk(fd, buf, len, bos, flags, src_addr, addr_len);
125}
126#endif /* __ANDROID_API__ >= __ANDROID_API_N__ */
127
128#if __ANDROID_API__ >= __ANDROID_API_N_MR1__
129__BIONIC_FORTIFY_INLINE
130ssize_t sendto(int fd, const void* buf, size_t len, int flags,
131 const struct sockaddr* dest_addr, socklen_t addr_len) {
132 size_t bos = __bos0(buf);
133
134 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
135 return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
136 }
137
138 if (__builtin_constant_p(len) && (len <= bos)) {
139 return __sendto_real(fd, buf, len, flags, dest_addr, addr_len);
140 }
141
142 if (__builtin_constant_p(len) && (len > bos)) {
143 __sendto_error();
144 }
145
146 return __sendto_chk(fd, buf, len, bos, flags, dest_addr, addr_len);
147}
148#endif /* __ANDROID_API__ >= __ANDROID_API_N_MR1__ */
149
150#endif /* defined(__clang__) */
151#undef __recvfrom_bad_size
152#undef __sendto_bad_size
153
154__BIONIC_FORTIFY_INLINE
155ssize_t recv(int socket, void* const buf __pass_object_size0, size_t len,
156 int flags) __overloadable {
157 return recvfrom(socket, buf, len, flags, NULL, 0);
158}
159
160__BIONIC_FORTIFY_INLINE
161ssize_t send(int socket, const void* const buf __pass_object_size0, size_t len, int flags)
162 __overloadable {
163 return sendto(socket, buf, len, flags, NULL, 0);
164}
165
166#endif /* __BIONIC_FORTIFY */