diff options
Diffstat (limited to 'ipc/msg.c')
-rw-r--r-- | ipc/msg.c | 20 |
1 files changed, 14 insertions, 6 deletions
@@ -476,9 +476,9 @@ static int msgctl_info(struct ipc_namespace *ns, int msqid, | |||
476 | static int msgctl_stat(struct ipc_namespace *ns, int msqid, | 476 | static int msgctl_stat(struct ipc_namespace *ns, int msqid, |
477 | int cmd, struct msqid64_ds *p) | 477 | int cmd, struct msqid64_ds *p) |
478 | { | 478 | { |
479 | int err; | ||
480 | struct msg_queue *msq; | 479 | struct msg_queue *msq; |
481 | int success_return; | 480 | int id = 0; |
481 | int err; | ||
482 | 482 | ||
483 | memset(p, 0, sizeof(*p)); | 483 | memset(p, 0, sizeof(*p)); |
484 | 484 | ||
@@ -489,14 +489,13 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, | |||
489 | err = PTR_ERR(msq); | 489 | err = PTR_ERR(msq); |
490 | goto out_unlock; | 490 | goto out_unlock; |
491 | } | 491 | } |
492 | success_return = msq->q_perm.id; | 492 | id = msq->q_perm.id; |
493 | } else { | 493 | } else { |
494 | msq = msq_obtain_object_check(ns, msqid); | 494 | msq = msq_obtain_object_check(ns, msqid); |
495 | if (IS_ERR(msq)) { | 495 | if (IS_ERR(msq)) { |
496 | err = PTR_ERR(msq); | 496 | err = PTR_ERR(msq); |
497 | goto out_unlock; | 497 | goto out_unlock; |
498 | } | 498 | } |
499 | success_return = 0; | ||
500 | } | 499 | } |
501 | 500 | ||
502 | err = -EACCES; | 501 | err = -EACCES; |
@@ -507,6 +506,14 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, | |||
507 | if (err) | 506 | if (err) |
508 | goto out_unlock; | 507 | goto out_unlock; |
509 | 508 | ||
509 | ipc_lock_object(&msq->q_perm); | ||
510 | |||
511 | if (!ipc_valid_object(&msq->q_perm)) { | ||
512 | ipc_unlock_object(&msq->q_perm); | ||
513 | err = -EIDRM; | ||
514 | goto out_unlock; | ||
515 | } | ||
516 | |||
510 | kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm); | 517 | kernel_to_ipc64_perm(&msq->q_perm, &p->msg_perm); |
511 | p->msg_stime = msq->q_stime; | 518 | p->msg_stime = msq->q_stime; |
512 | p->msg_rtime = msq->q_rtime; | 519 | p->msg_rtime = msq->q_rtime; |
@@ -516,9 +523,10 @@ static int msgctl_stat(struct ipc_namespace *ns, int msqid, | |||
516 | p->msg_qbytes = msq->q_qbytes; | 523 | p->msg_qbytes = msq->q_qbytes; |
517 | p->msg_lspid = msq->q_lspid; | 524 | p->msg_lspid = msq->q_lspid; |
518 | p->msg_lrpid = msq->q_lrpid; | 525 | p->msg_lrpid = msq->q_lrpid; |
519 | rcu_read_unlock(); | ||
520 | 526 | ||
521 | return success_return; | 527 | ipc_unlock_object(&msq->q_perm); |
528 | rcu_read_unlock(); | ||
529 | return id; | ||
522 | 530 | ||
523 | out_unlock: | 531 | out_unlock: |
524 | rcu_read_unlock(); | 532 | rcu_read_unlock(); |