Home | History | Annotate | Download | only in mq_unlink
      1 /*
      2  * Copyright (c) Crackerjack Project., 2007-2008 ,Hitachi, Ltd
      3  *          Author(s): Takahiro Yasui <takahiro.yasui.mp (at) hitachi.com>,
      4  *		       Yumiko Sugita <yumiko.sugita.yf (at) hitachi.com>,
      5  *		       Satoshi Fujiwara <sa-fuji (at) sdl.hitachi.co.jp>
      6  * Copyright (c) 2016 Linux Test Project
      7  *
      8  * This program is free software; you can redistribute it and/or
      9  * modify it under the terms of the GNU General Public License as
     10  * published by the Free Software Foundation; either version 2 of
     11  * the License, or (at your option) any later version.
     12  *
     13  * This program is distributed in the hope that it would be useful,
     14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  * GNU General Public License for more details.
     17  *
     18  * You should have received a copy of the GNU General Public License
     19  * along with this program; if not, write the Free Software Foundation,
     20  * Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
     21  */
     22 
     23 #include <errno.h>
     24 #include <pwd.h>
     25 #include <mqueue.h>
     26 
     27 #include "tst_test.h"
     28 #include "tst_safe_posix_ipc.h"
     29 
     30 #define QUEUE_NAME	"/test_mqueue"
     31 
     32 static uid_t euid;
     33 static struct passwd *pw;
     34 
     35 struct test_case {
     36 	int as_nobody;
     37 	char *qname;
     38 	int ret;
     39 	int err;
     40 };
     41 
     42 static struct test_case tcase[] = {
     43 	{
     44 		.qname = QUEUE_NAME,
     45 		.ret = 0,
     46 		.err = 0,
     47 	},
     48 	{
     49 		.as_nobody = 1,
     50 		.qname = QUEUE_NAME,
     51 		.ret = -1,
     52 		.err = EACCES,
     53 	},
     54 	{
     55 		.qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     56 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     57 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     58 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     59 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     60 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     61 			"aaaaaaaaaaaaaaa",
     62 		.ret = -1,
     63 		.err = ENOENT,
     64 	},
     65 	{
     66 		.qname = "/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     67 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     68 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     69 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     70 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     71 			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
     72 			"aaaaaaaaaaaaaaaa",
     73 		.ret = -1,
     74 		.err = ENAMETOOLONG,
     75 	},
     76 };
     77 
     78 void setup(void)
     79 {
     80 	euid = geteuid();
     81 	pw = SAFE_GETPWNAM("nobody");
     82 }
     83 
     84 static void do_test(unsigned int i)
     85 {
     86 	struct test_case *tc = &tcase[i];
     87 	mqd_t fd;
     88 
     89 	tst_res(TINFO, "queue name %s", tc->qname);
     90 
     91 	/*
     92 	 * When test ended with SIGTERM etc, mq descriptor is left remains.
     93 	 * So we delete it first.
     94 	 */
     95 	mq_unlink(QUEUE_NAME);
     96 
     97 	/* prepare */
     98 	fd = SAFE_MQ_OPEN(QUEUE_NAME, O_CREAT | O_EXCL | O_RDWR, S_IRWXU, NULL);
     99 
    100 	if (tc->as_nobody && seteuid(pw->pw_uid)) {
    101 		tst_res(TBROK | TERRNO, "seteuid failed");
    102 		goto EXIT;
    103 	}
    104 
    105 	/* test */
    106 	TEST(mq_unlink(tc->qname));
    107 	if (TEST_ERRNO != tc->err || TEST_RETURN != tc->ret) {
    108 		tst_res(TFAIL | TTERRNO, "mq_unlink returned %ld, expected %d,"
    109 			" expected errno %s (%d)", TEST_RETURN,
    110 			tc->ret, tst_strerrno(tc->err), tc->err);
    111 	} else {
    112 		tst_res(TPASS | TTERRNO, "mq_unlink returned %ld", TEST_RETURN);
    113 	}
    114 
    115 EXIT:
    116 	/* cleanup */
    117 	if (tc->as_nobody && seteuid(euid) == -1)
    118 		tst_res(TWARN | TERRNO, "seteuid back to %d failed", euid);
    119 
    120 	if (fd > 0 && close(fd))
    121 		tst_res(TWARN | TERRNO, "close(fd) failed");
    122 
    123 	mq_unlink(QUEUE_NAME);
    124 }
    125 
    126 static struct tst_test test = {
    127 	.tcnt = ARRAY_SIZE(tcase),
    128 	.test = do_test,
    129 	.needs_root = 1,
    130 	.setup = setup,
    131 };
    132