Rev 2471 | Rev 2556 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
| Rev 2471 | Rev 2494 | ||
|---|---|---|---|
| Line 47... | Line 47... | ||
| 47 | #include <syscall/copy.h> |
47 | #include <syscall/copy.h> |
| 48 | #include <security/cap.h> |
48 | #include <security/cap.h> |
| 49 | #include <mm/as.h> |
49 | #include <mm/as.h> |
| 50 | #include <print.h> |
50 | #include <print.h> |
| 51 | 51 | ||
| - | 52 | /** Maximum buffer size allowed for IPC_M_DATA_SEND requests. */ |
|
| - | 53 | #define DATA_SEND_LIMIT (64 * 1024) |
|
| - | 54 | ||
| 52 | #define GET_CHECK_PHONE(phone, phoneid, err) \ |
55 | #define GET_CHECK_PHONE(phone, phoneid, err) \ |
| 53 | { \ |
56 | { \ |
| 54 | if (phoneid > IPC_MAX_PHONES) { \ |
57 | if (phoneid > IPC_MAX_PHONES) { \ |
| 55 | err; \ |
58 | err; \ |
| 56 | } \ |
59 | } \ |
| Line 83... | Line 86... | ||
| 83 | * @return Return 1 if the method is forwardable. |
86 | * @return Return 1 if the method is forwardable. |
| 84 | * Otherwise return 0. |
87 | * Otherwise return 0. |
| 85 | */ |
88 | */ |
| 86 | static inline int is_forwardable(unative_t method) |
89 | static inline int is_forwardable(unative_t method) |
| 87 | { |
90 | { |
| - | 91 | switch (method) { |
|
| - | 92 | case IPC_M_PHONE_HUNGUP: |
|
| 88 | if (method == IPC_M_PHONE_HUNGUP || method == IPC_M_AS_AREA_SEND || |
93 | case IPC_M_AS_AREA_SEND: |
| 89 | method == IPC_M_AS_AREA_RECV) |
94 | case IPC_M_AS_AREA_RECV: |
| - | 95 | case IPC_M_DATA_SEND: |
|
| 90 | return 0; /* This message is meant only for the receiver */ |
96 | /* This message is meant only for the original recipient. */ |
| - | 97 | return 0; |
|
| - | 98 | default: |
|
| 91 | return 1; |
99 | return 1; |
| - | 100 | } |
|
| 92 | } |
101 | } |
| 93 | 102 | ||
| 94 | 103 | ||
| 95 | /*********************************************************************** |
104 | /*********************************************************************** |
| 96 | * Functions that preprocess answer before sending it to the recepient. |
105 | * Functions that preprocess answer before sending it to the recepient. |
| Line 104... | Line 113... | ||
| 104 | * @return Return 1 if the old call contents should be saved. |
113 | * @return Return 1 if the old call contents should be saved. |
| 105 | * Return 0 otherwise. |
114 | * Return 0 otherwise. |
| 106 | */ |
115 | */ |
| 107 | static inline int answer_need_old(call_t *call) |
116 | static inline int answer_need_old(call_t *call) |
| 108 | { |
117 | { |
| 109 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_TO_ME) |
118 | switch (IPC_GET_METHOD(call->data)) { |
| 110 | return 1; |
119 | case IPC_M_CONNECT_TO_ME: |
| 111 | if (IPC_GET_METHOD(call->data) == IPC_M_CONNECT_ME_TO) |
120 | case IPC_M_CONNECT_ME_TO: |
| 112 | return 1; |
- | |
| 113 | if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_SEND) |
121 | case IPC_M_AS_AREA_SEND: |
| 114 | return 1; |
122 | case IPC_M_AS_AREA_RECV: |
| 115 | if (IPC_GET_METHOD(call->data) == IPC_M_AS_AREA_RECV) |
123 | case IPC_M_DATA_SEND: |
| 116 | return 1; |
124 | return 1; |
| - | 125 | default: |
|
| 117 | return 0; |
126 | return 0; |
| - | 127 | } |
|
| 118 | } |
128 | } |
| 119 | 129 | ||
| 120 | /** Interpret process answer as control information. |
130 | /** Interpret process answer as control information. |
| 121 | * |
131 | * |
| 122 | * This function is called directly after sys_ipc_answer(). |
132 | * This function is called directly after sys_ipc_answer(). |
| Line 199... | Line 209... | ||
| 199 | rc = as_area_share(AS, IPC_GET_ARG1(answer->data), |
209 | rc = as_area_share(AS, IPC_GET_ARG1(answer->data), |
| 200 | IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata), |
210 | IPC_GET_ARG2(*olddata), as, IPC_GET_ARG1(*olddata), |
| 201 | IPC_GET_ARG2(answer->data)); |
211 | IPC_GET_ARG2(answer->data)); |
| 202 | IPC_SET_RETVAL(answer->data, rc); |
212 | IPC_SET_RETVAL(answer->data, rc); |
| 203 | } |
213 | } |
| - | 214 | } else if (IPC_GET_METHOD(*olddata) == IPC_M_DATA_SEND) { |
|
| - | 215 | if (!IPC_GET_RETVAL(answer->data)) { |
|
| - | 216 | int rc; |
|
| - | 217 | uintptr_t dst; |
|
| - | 218 | uintptr_t size; |
|
| - | 219 | ||
| - | 220 | ASSERT(answer->buffer); |
|
| - | 221 | ||
| - | 222 | dst = IPC_GET_ARG1(answer->data); |
|
| - | 223 | size = IPC_GET_ARG3(answer->data); |
|
| - | 224 | ||
| - | 225 | rc = copy_to_uspace((void *) dst, answer->buffer, size); |
|
| - | 226 | if (rc != 0) |
|
| - | 227 | IPC_SET_RETVAL(answer->data, rc); |
|
| - | 228 | free(answer->buffer); |
|
| - | 229 | answer->buffer = NULL; |
|
| - | 230 | } |
|
| 204 | } |
231 | } |
| 205 | return 0; |
232 | return 0; |
| 206 | } |
233 | } |
| 207 | 234 | ||
| 208 | /** Called before the request is sent. |
235 | /** Called before the request is sent. |
| Line 213... | Line 240... | ||
| 213 | */ |
240 | */ |
| 214 | static int request_preprocess(call_t *call) |
241 | static int request_preprocess(call_t *call) |
| 215 | { |
242 | { |
| 216 | int newphid; |
243 | int newphid; |
| 217 | size_t size; |
244 | size_t size; |
| - | 245 | uintptr_t src; |
|
| - | 246 | int rc; |
|
| 218 | 247 | ||
| 219 | switch (IPC_GET_METHOD(call->data)) { |
248 | switch (IPC_GET_METHOD(call->data)) { |
| 220 | case IPC_M_CONNECT_ME_TO: |
249 | case IPC_M_CONNECT_ME_TO: |
| 221 | newphid = phone_alloc(); |
250 | newphid = phone_alloc(); |
| 222 | if (newphid < 0) |
251 | if (newphid < 0) |
| Line 230... | Line 259... | ||
| 230 | size = as_get_size(IPC_GET_ARG1(call->data)); |
259 | size = as_get_size(IPC_GET_ARG1(call->data)); |
| 231 | if (!size) |
260 | if (!size) |
| 232 | return EPERM; |
261 | return EPERM; |
| 233 | IPC_SET_ARG2(call->data, size); |
262 | IPC_SET_ARG2(call->data, size); |
| 234 | break; |
263 | break; |
| - | 264 | case IPC_M_DATA_SEND: |
|
| - | 265 | src = IPC_GET_ARG2(call->data); |
|
| - | 266 | size = IPC_GET_ARG3(call->data); |
|
| - | 267 | ||
| - | 268 | if ((size <= 0) || (size > DATA_SEND_LIMIT)) |
|
| - | 269 | return ELIMIT; |
|
| - | 270 | ||
| - | 271 | call->buffer = (uint8_t *) malloc(size, 0); |
|
| - | 272 | rc = copy_from_uspace(call->buffer, (void *) src, size); |
|
| - | 273 | if (rc != 0) { |
|
| - | 274 | free(call->buffer); |
|
| - | 275 | return rc; |
|
| - | 276 | } |
|
| - | 277 | break; |
|
| 235 | default: |
278 | default: |
| 236 | break; |
279 | break; |
| 237 | } |
280 | } |
| 238 | return 0; |
281 | return 0; |
| 239 | } |
282 | } |
| Line 324... | Line 367... | ||
| 324 | 367 | ||
| 325 | /** Make a synchronous IPC call allowing to transmit the entire payload. |
368 | /** Make a synchronous IPC call allowing to transmit the entire payload. |
| 326 | * |
369 | * |
| 327 | * @param phoneid Phone handle for the call. |
370 | * @param phoneid Phone handle for the call. |
| 328 | * @param question Userspace address of call data with the request. |
371 | * @param question Userspace address of call data with the request. |
| 329 | * @param reply Userspace address of call data where to store the answer. |
372 | * @param reply Userspace address of call data where to store the |
| - | 373 | * answer. |
|
| 330 | * |
374 | * |
| 331 | * @return Zero on success or an error code. |
375 | * @return Zero on success or an error code. |
| 332 | */ |
376 | */ |
| 333 | unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question, |
377 | unative_t sys_ipc_call_sync(unative_t phoneid, ipc_data_t *question, |
| 334 | ipc_data_t *reply) |
378 | ipc_data_t *reply) |