Tue Jul 21 00:23:01 2009 UTC ()
Pull up following revision(s) (requested by rmind in ticket #857):
	sys/kern/sys_mqueue.c: revision 1.21 via patch
mq_send/mq_receive: while permission may allow that, return EBADF if sending
to read-only queue, or receiving from write-only queue.
From Stathis Kamperis, thanks!


(snj)
diff -r1.12.4.3 -r1.12.4.4 src/sys/kern/sys_mqueue.c

cvs diff -r1.12.4.3 -r1.12.4.4 src/sys/kern/sys_mqueue.c (expand / switch to unified diff)

--- src/sys/kern/sys_mqueue.c 2009/05/27 21:32:05 1.12.4.3
+++ src/sys/kern/sys_mqueue.c 2009/07/21 00:23:01 1.12.4.4
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: sys_mqueue.c,v 1.12.4.3 2009/05/27 21:32:05 snj Exp $ */ 1/* $NetBSD: sys_mqueue.c,v 1.12.4.4 2009/07/21 00:23:01 snj Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org> 4 * Copyright (c) 2007, 2008 Mindaugas Rasiukevicius <rmind at NetBSD org>
5 * All rights reserved. 5 * All rights reserved.
6 *  6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -32,27 +32,27 @@ @@ -32,27 +32,27 @@
32 * 32 *
33 * Locking 33 * Locking
34 *  34 *
35 * Global list of message queues (mqueue_head) and proc_t::p_mqueue_cnt 35 * Global list of message queues (mqueue_head) and proc_t::p_mqueue_cnt
36 * counter are protected by mqlist_mtx lock. The very message queue and 36 * counter are protected by mqlist_mtx lock. The very message queue and
37 * its members are protected by mqueue::mq_mtx. 37 * its members are protected by mqueue::mq_mtx.
38 *  38 *
39 * Lock order: 39 * Lock order:
40 * mqlist_mtx 40 * mqlist_mtx
41 * -> mqueue::mq_mtx 41 * -> mqueue::mq_mtx
42 */ 42 */
43 43
44#include <sys/cdefs.h> 44#include <sys/cdefs.h>
45__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.12.4.3 2009/05/27 21:32:05 snj Exp $"); 45__KERNEL_RCSID(0, "$NetBSD: sys_mqueue.c,v 1.12.4.4 2009/07/21 00:23:01 snj Exp $");
46 46
47#include <sys/param.h> 47#include <sys/param.h>
48#include <sys/types.h> 48#include <sys/types.h>
49#include <sys/condvar.h> 49#include <sys/condvar.h>
50#include <sys/errno.h> 50#include <sys/errno.h>
51#include <sys/fcntl.h> 51#include <sys/fcntl.h>
52#include <sys/file.h> 52#include <sys/file.h>
53#include <sys/filedesc.h> 53#include <sys/filedesc.h>
54#include <sys/kauth.h> 54#include <sys/kauth.h>
55#include <sys/kernel.h> 55#include <sys/kernel.h>
56#include <sys/kmem.h> 56#include <sys/kmem.h>
57#include <sys/lwp.h> 57#include <sys/lwp.h>
58#include <sys/mqueue.h> 58#include <sys/mqueue.h>
@@ -472,29 +472,34 @@ sys_mq_close(struct lwp *l, const struct @@ -472,29 +472,34 @@ sys_mq_close(struct lwp *l, const struct
472 * Primary mq_receive1() function. 472 * Primary mq_receive1() function.
473 */ 473 */
474static int 474static int
475mq_receive1(struct lwp *l, mqd_t mqdes, void *msg_ptr, size_t msg_len, 475mq_receive1(struct lwp *l, mqd_t mqdes, void *msg_ptr, size_t msg_len,
476 unsigned *msg_prio, int t, ssize_t *mlen) 476 unsigned *msg_prio, int t, ssize_t *mlen)
477{ 477{
478 file_t *fp = NULL; 478 file_t *fp = NULL;
479 struct mqueue *mq; 479 struct mqueue *mq;
480 struct mq_msg *msg = NULL; 480 struct mq_msg *msg = NULL;
481 int error; 481 int error;
482 482
483 /* Get the message queue */ 483 /* Get the message queue */
484 error = mqueue_get(mqdes, &fp); 484 error = mqueue_get(mqdes, &fp);
485 if (error) 485 if (error) {
486 return error; 486 return error;
 487 }
487 mq = fp->f_data; 488 mq = fp->f_data;
 489 if ((fp->f_flag & FREAD) == 0) {
 490 error = EBADF;
 491 goto error;
 492 }
488 493
489 /* Check the message size limits */ 494 /* Check the message size limits */
490 if (msg_len < mq->mq_attrib.mq_msgsize) { 495 if (msg_len < mq->mq_attrib.mq_msgsize) {
491 error = EMSGSIZE; 496 error = EMSGSIZE;
492 goto error; 497 goto error;
493 } 498 }
494 499
495 /* Check if queue is empty */ 500 /* Check if queue is empty */
496 while (TAILQ_EMPTY(&mq->mq_head)) { 501 while (TAILQ_EMPTY(&mq->mq_head)) {
497 if (mq->mq_attrib.mq_flags & O_NONBLOCK) { 502 if (mq->mq_attrib.mq_flags & O_NONBLOCK) {
498 error = EAGAIN; 503 error = EAGAIN;
499 goto error; 504 goto error;
500 } 505 }
@@ -632,26 +637,30 @@ mq_send1(struct lwp *l, mqd_t mqdes, con @@ -632,26 +637,30 @@ mq_send1(struct lwp *l, mqd_t mqdes, con
632 mqueue_freemsg(msg, size); 637 mqueue_freemsg(msg, size);
633 return error; 638 return error;
634 } 639 }
635 msg->msg_len = msg_len; 640 msg->msg_len = msg_len;
636 msg->msg_prio = msg_prio; 641 msg->msg_prio = msg_prio;
637 642
638 /* Get the mqueue */ 643 /* Get the mqueue */
639 error = mqueue_get(mqdes, &fp); 644 error = mqueue_get(mqdes, &fp);
640 if (error) { 645 if (error) {
641 mqueue_freemsg(msg, size); 646 mqueue_freemsg(msg, size);
642 return error; 647 return error;
643 } 648 }
644 mq = fp->f_data; 649 mq = fp->f_data;
 650 if ((fp->f_flag & FWRITE) == 0) {
 651 error = EBADF;
 652 goto error;
 653 }
645 654
646 /* Check the message size limit */ 655 /* Check the message size limit */
647 if (msg_len <= 0 || msg_len > mq->mq_attrib.mq_msgsize) { 656 if (msg_len <= 0 || msg_len > mq->mq_attrib.mq_msgsize) {
648 error = EMSGSIZE; 657 error = EMSGSIZE;
649 goto error; 658 goto error;
650 } 659 }
651 660
652 /* Check if queue is full */ 661 /* Check if queue is full */
653 while (mq->mq_attrib.mq_curmsgs >= mq->mq_attrib.mq_maxmsg) { 662 while (mq->mq_attrib.mq_curmsgs >= mq->mq_attrib.mq_maxmsg) {
654 if (mq->mq_attrib.mq_flags & O_NONBLOCK) { 663 if (mq->mq_attrib.mq_flags & O_NONBLOCK) {
655 error = EAGAIN; 664 error = EAGAIN;
656 goto error; 665 goto error;
657 } 666 }