aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Huang2017-10-20 13:40:04 -0500
committerDavid Huang2017-10-20 13:40:04 -0500
commitc5c77cf449d2af7ae9fa63240d1375641dff9d66 (patch)
tree9a0409421c26c2e2cad3de21d776ea4af6547a72
parentb30abf4c412308c95b73df6b286aebc77d28ff6f (diff)
parent0e6593b00e987f9c900b7aba36a03f295b04996a (diff)
downloadkernel-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.c6
-rw-r--r--drivers/rpmsg/virtio_rpmsg_bus.c12
-rw-r--r--include/linux/rpmsg.h30
-rw-r--r--net/rpmsg/rpmsg_proto.c17
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:
323struct rpmsg_endpoint *rpmsg_create_ept(struct rpmsg_channel *rpdev, 323struct 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}
328EXPORT_SYMBOL(rpmsg_create_ept); 331EXPORT_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 */
363void rpmsg_destroy_ept(struct rpmsg_endpoint *ept) 367void 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}
367EXPORT_SYMBOL(rpmsg_destroy_ept); 372EXPORT_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 */
228static inline int rpmsg_send(struct rpmsg_channel *rpdev, void *data, int len) 228static 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)
253static inline 255static inline
254int rpmsg_sendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) 256int 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
282int rpmsg_send_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, 286int 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,
304static inline 311static inline
305int rpmsg_trysend(struct rpmsg_channel *rpdev, void *data, int len) 312int 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)
329static inline 338static inline
330int rpmsg_trysendto(struct rpmsg_channel *rpdev, void *data, int len, u32 dst) 339int 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
357int rpmsg_trysend_offchannel(struct rpmsg_channel *rpdev, u32 src, u32 dst, 368int 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);