diff options
author | David Huang | 2017-10-20 13:40:04 -0500 |
---|---|---|
committer | David Huang | 2017-10-20 13:40:04 -0500 |
commit | c5c77cf449d2af7ae9fa63240d1375641dff9d66 (patch) | |
tree | 9a0409421c26c2e2cad3de21d776ea4af6547a72 | |
parent | b30abf4c412308c95b73df6b286aebc77d28ff6f (diff) | |
parent | 0e6593b00e987f9c900b7aba36a03f295b04996a (diff) | |
download | kernel-omap-c5c77cf449d2af7ae9fa63240d1375641dff9d66.tar.gz kernel-omap-c5c77cf449d2af7ae9fa63240d1375641dff9d66.tar.xz kernel-omap-c5c77cf449d2af7ae9fa63240d1375641dff9d66.zip |
Merge branch 'p-ti-lsk-linux-4.4.y-next' of git://git.omapzoom.org/kernel/omap into p-ti-android-linux-4.4.y
Auto Merge of:
TI-Feature: linux-4.4.y-next_android-4.4.y
TI-Tree: git://git.omapzoom.org/kernel/omap.git
TI-Branch: p-ti-lsk-linux-4.4.y-next
* 'p-ti-lsk-linux-4.4.y-next' of git://git.omapzoom.org/kernel/omap:
net/rpmsg: fix a potential NULL pointer dereference in bind()
net/rpmsg: fix possible kernel crash in callback for deleted sockets
net/rpmsg: fix error status marking of new Rx sockets during recovery
net/rpmsg: skip announcement of rpmsg devices created in bind()
rpmsg: rpc: fix suspicious rcu_dereference_check() usage
rpmsg: check for invalid parameters in couple of public API
rpmsg: add input argument sanity checks to rpmsg_send functions
Signed-off-by: David Huang <d-huang@ti.com>
-rw-r--r-- | drivers/rpmsg/rpmsg_rpc.c | 6 | ||||
-rw-r--r-- | drivers/rpmsg/virtio_rpmsg_bus.c | 12 | ||||
-rw-r--r-- | include/linux/rpmsg.h | 30 | ||||
-rw-r--r-- | net/rpmsg/rpmsg_proto.c | 17 |
4 files changed, 50 insertions, 15 deletions
diff --git a/drivers/rpmsg/rpmsg_rpc.c b/drivers/rpmsg/rpmsg_rpc.c index 009416f2cf6b..a335fe0cb1c8 100644 --- a/drivers/rpmsg/rpmsg_rpc.c +++ b/drivers/rpmsg/rpmsg_rpc.c | |||
@@ -441,10 +441,13 @@ static int rppc_register_buffers(struct rppc_instance *rpc, | |||
441 | } | 441 | } |
442 | 442 | ||
443 | for (i = 0; i < data.num; i++) { | 443 | for (i = 0; i < data.num; i++) { |
444 | rcu_read_lock(); | ||
444 | if (!fcheck(fds[i])) { | 445 | if (!fcheck(fds[i])) { |
446 | rcu_read_unlock(); | ||
445 | ret = -EBADF; | 447 | ret = -EBADF; |
446 | goto free_fds; | 448 | goto free_fds; |
447 | } | 449 | } |
450 | rcu_read_unlock(); | ||
448 | 451 | ||
449 | tmp = rppc_find_dmabuf(rpc, fds[i]); | 452 | tmp = rppc_find_dmabuf(rpc, fds[i]); |
450 | if (!IS_ERR_OR_NULL(tmp)) { | 453 | if (!IS_ERR_OR_NULL(tmp)) { |
@@ -511,10 +514,13 @@ static int rppc_unregister_buffers(struct rppc_instance *rpc, | |||
511 | } | 514 | } |
512 | 515 | ||
513 | for (i = 0; i < data.num; i++) { | 516 | for (i = 0; i < data.num; i++) { |
517 | rcu_read_lock(); | ||
514 | if (!fcheck(fds[i])) { | 518 | if (!fcheck(fds[i])) { |
519 | rcu_read_unlock(); | ||
515 | ret = -EBADF; | 520 | ret = -EBADF; |
516 | goto free_bufs; | 521 | goto free_bufs; |
517 | } | 522 | } |
523 | rcu_read_unlock(); | ||
518 | 524 | ||
519 | bufs[i] = rppc_find_dmabuf(rpc, fds[i]); | 525 | bufs[i] = rppc_find_dmabuf(rpc, fds[i]); |
520 | if (IS_ERR_OR_NULL(bufs[i])) { | 526 | if (IS_ERR_OR_NULL(bufs[i])) { |
diff --git a/drivers/rpmsg/virtio_rpmsg_bus.c b/drivers/rpmsg/virtio_rpmsg_bus.c index a9c8ffdb1407..d1735c83b1ae 100644 --- a/drivers/rpmsg/virtio_rpmsg_bus.c +++ b/drivers/rpmsg/virtio_rpmsg_bus.c | |||
@@ -323,6 +323,9 @@ free_ept: | |||
323 | struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, | 323 | struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, |
324 | rpmsg_rx_cb_t cb, void *priv, u32 addr) | 324 | rpmsg_rx_cb_t cb, void *priv, u32 addr) |
325 | { | 325 | { |
326 | if (WARN_ON(!rpdev)) | ||
327 | return NULL; | ||
328 | |||
326 | return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, addr); | 329 | return __rpmsg_create_ept(rpdev->vrp, rpdev, cb, priv, addr); |
327 | } | 330 | } |
328 | EXPORT_SYMBOL(rpmsg_create_ept); | 331 | EXPORT_SYMBOL(rpmsg_create_ept); |
@@ -358,11 +361,13 @@ __rpmsg_destroy_ept(struct virtproc_info *vrp, struct rpmsg_endpoint *ept) | |||
358 | * @ept: endpoing to destroy | 361 | * @ept: endpoing to destroy |
359 | * | 362 | * |
360 | * Should be used by drivers to destroy an rpmsg endpoint previously | 363 | * Should be used by drivers to destroy an rpmsg endpoint previously |
361 | * created with rpmsg_create_ept(). | 364 | * created with rpmsg_create_ept(). As with other types of "free" NULL |
365 | * is a valid parameter. | ||
362 | */ | 366 | */ |
363 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) | 367 | void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) |
364 | { | 368 | { |
365 | __rpmsg_destroy_ept(ept->rpdev->vrp, ept); | 369 | if (ept) |
370 | __rpmsg_destroy_ept(ept->rpdev->vrp, ept); | ||
366 | } | 371 | } |
367 | EXPORT_SYMBOL(rpmsg_destroy_ept); | 372 | EXPORT_SYMBOL(rpmsg_destroy_ept); |
368 | 373 | ||
@@ -599,6 +604,9 @@ struct rpmsg_channel *rpmsg_create_channel(struct virtproc_info *vrp, | |||
599 | { | 604 | { |
600 | struct rpmsg_channel_info chinfo; | 605 | struct rpmsg_channel_info chinfo; |
601 | 606 | ||
607 | if (!vrp || !name || !desc) | ||
608 | return NULL; | ||
609 | |||
602 | strncpy(chinfo.name, name, sizeof(chinfo.name)); | 610 | strncpy(chinfo.name, name, sizeof(chinfo.name)); |
603 | strncpy(chinfo.desc, desc, sizeof(chinfo.desc)); | 611 | strncpy(chinfo.desc, desc, sizeof(chinfo.desc)); |
604 | chinfo.src = src; | 612 | chinfo.src = src; |
diff --git a/include/linux/rpmsg.h b/include/linux/rpmsg.h index 1dcbca1232cc..1a163429d57e 100644 --- a/include/linux/rpmsg.h +++ b/include/linux/rpmsg.h | |||
@@ -227,9 +227,11 @@ int rpmsg_destroy_channel(struct rpmsg_channel *rpdev); | |||
227 | */ | 227 | */ |
228 | static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) | 228 | static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) |
229 | { | 229 | { |
230 | u32 src = rpdev->src, dst = rpdev->dst; | 230 | if (WARN_ON(!rpdev)) |
231 | return -EINVAL; | ||
231 | 232 | ||
232 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | 233 | return rpmsg_send_offchannel_raw(rpdev, rpdev->src, rpdev->dst, data, |
234 | len, true); | ||
233 | } | 235 | } |
234 | 236 | ||
235 | /** | 237 | /** |
@@ -253,9 +255,11 @@ static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) | |||
253 | static inline | 255 | static inline |
254 | int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) | 256 | int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) |
255 | { | 257 | { |
256 | u32 src = rpdev->src; | 258 | if (WARN_ON(!rpdev)) |
259 | return -EINVAL; | ||
257 | 260 | ||
258 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | 261 | return rpmsg_send_offchannel_raw(rpdev, rpdev->src, dst, data, |
262 | len, true); | ||
259 | } | 263 | } |
260 | 264 | ||
261 | /** | 265 | /** |
@@ -282,6 +286,9 @@ static inline | |||
282 | int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | 286 | int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, |
283 | void *data, int len) | 287 | void *data, int len) |
284 | { | 288 | { |
289 | if (WARN_ON(!rpdev)) | ||
290 | return -EINVAL; | ||
291 | |||
285 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); | 292 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, true); |
286 | } | 293 | } |
287 | 294 | ||
@@ -304,9 +311,11 @@ int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | |||
304 | static inline | 311 | static inline |
305 | int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) | 312 | int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) |
306 | { | 313 | { |
307 | u32 src = rpdev->src, dst = rpdev->dst; | 314 | if (WARN_ON(!rpdev)) |
315 | return -EINVAL; | ||
308 | 316 | ||
309 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | 317 | return rpmsg_send_offchannel_raw(rpdev, rpdev->src, rpdev->dst, data, |
318 | len, false); | ||
310 | } | 319 | } |
311 | 320 | ||
312 | /** | 321 | /** |
@@ -329,9 +338,11 @@ int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) | |||
329 | static inline | 338 | static inline |
330 | int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) | 339 | int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) |
331 | { | 340 | { |
332 | u32 src = rpdev->src; | 341 | if (WARN_ON(!rpdev)) |
342 | return -EINVAL; | ||
333 | 343 | ||
334 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | 344 | return rpmsg_send_offchannel_raw(rpdev, rpdev->src, dst, data, |
345 | len, false); | ||
335 | } | 346 | } |
336 | 347 | ||
337 | /** | 348 | /** |
@@ -357,6 +368,9 @@ static inline | |||
357 | int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, | 368 | int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, |
358 | void *data, int len) | 369 | void *data, int len) |
359 | { | 370 | { |
371 | if (WARN_ON(!rpdev)) | ||
372 | return -EINVAL; | ||
373 | |||
360 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); | 374 | return rpmsg_send_offchannel_raw(rpdev, src, dst, data, len, false); |
361 | } | 375 | } |
362 | 376 | ||
diff --git a/net/rpmsg/rpmsg_proto.c b/net/rpmsg/rpmsg_proto.c index 010a9aed6dbf..60032195f2e4 100644 --- a/net/rpmsg/rpmsg_proto.c +++ b/net/rpmsg/rpmsg_proto.c | |||
@@ -440,6 +440,10 @@ rpmsg_sock_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
440 | if (sa->family != AF_RPMSG) | 440 | if (sa->family != AF_RPMSG) |
441 | return -EINVAL; | 441 | return -EINVAL; |
442 | 442 | ||
443 | /* do not allow fixed addresses above the dynamically allocated range */ | ||
444 | if (sa->addr >= RPMSG_RESERVED_ADDRESSES) | ||
445 | return -EINVAL; | ||
446 | |||
443 | if (rpsk->rpdev) | 447 | if (rpsk->rpdev) |
444 | return -EBUSY; | 448 | return -EBUSY; |
445 | 449 | ||
@@ -455,6 +459,11 @@ rpmsg_sock_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) | |||
455 | if (!rpdev) | 459 | if (!rpdev) |
456 | return -EINVAL; | 460 | return -EINVAL; |
457 | 461 | ||
462 | if (!rpdev->ept) { | ||
463 | rpmsg_destroy_channel(rpdev); | ||
464 | return -EINVAL; | ||
465 | } | ||
466 | |||
458 | rpsk->rpdev = rpdev; | 467 | rpsk->rpdev = rpdev; |
459 | rpsk->unregister_rpdev = true; | 468 | rpsk->unregister_rpdev = true; |
460 | rpsk->rproc_id = sa->vproc_id; | 469 | rpsk->rproc_id = sa->vproc_id; |
@@ -544,7 +553,8 @@ static void __rpmsg_proto_cb(struct device *dev, int from_vproc_id, void *data, | |||
544 | #endif | 553 | #endif |
545 | 554 | ||
546 | if (!sk) { | 555 | if (!sk) { |
547 | dev_warn(dev, "callback for deleted socket (from %d)\n", src); | 556 | dev_warn(dev, "callback received for deleted socket (from %d)\n", |
557 | src); | ||
548 | return; | 558 | return; |
549 | } | 559 | } |
550 | 560 | ||
@@ -624,7 +634,7 @@ static int rpmsg_proto_probe(struct rpmsg_channel *rpdev) | |||
624 | id); | 634 | id); |
625 | 635 | ||
626 | if (dst == RPMSG_ADDR_ANY) { | 636 | if (dst == RPMSG_ADDR_ANY) { |
627 | /* Set announce to false and avoid extra delay when binding. */ | 637 | /* do not announce bound sockets to remote processor */ |
628 | rpdev->announce = false; | 638 | rpdev->announce = false; |
629 | return 0; | 639 | return 0; |
630 | } | 640 | } |
@@ -696,9 +706,6 @@ static void rpmsg_proto_remove(struct rpmsg_channel *rpdev) | |||
696 | struct rpmsg_socket *rpsk, *tmp; | 706 | struct rpmsg_socket *rpsk, *tmp; |
697 | struct sock *sk; | 707 | struct sock *sk; |
698 | 708 | ||
699 | if (dst == RPMSG_ADDR_ANY) | ||
700 | return; | ||
701 | |||
702 | id = rpmsg_sock_get_proc_id(rpdev); | 709 | id = rpmsg_sock_get_proc_id(rpdev); |
703 | 710 | ||
704 | mutex_lock(&rpmsg_channels_lock); | 711 | mutex_lock(&rpmsg_channels_lock); |