This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix mq_unlink (?), some testsuite changes


Hi!

POSIX only lists EACCES error if mq_unlink fails because of permission
problems (current kernels have the mqueue directory with rwxrwxrwt
permissions, unlink is allowed to return both EPERM and EACCESS in that
case and returns EPERM).  So I think we need something like this.
If so, we also should change sem_unlink and shm_unlink in the same way.

2004-04-19  Jakub Jelinek  <jakub@redhat.com>

	* sysdeps/unix/sysv/linux/mq_unlink.c (mq_unlink): Change EPERM into
	EACCES.
	* rt/Makefile (tests): Add tst-mqueue9.
	* rt/tst-mqueue9.c: New test.
	* rt/tst-mqueue4.c (do_test): Add test for mq_unlink of a too long
	name component.
	* rt/tst-mqueue7.c (do_test): Make newargv const char *[] to shut up
	warnings.

--- libc/sysdeps/unix/sysv/linux/mq_unlink.c.jj	2004-04-13 04:13:56.000000000 +0200
+++ libc/sysdeps/unix/sysv/linux/mq_unlink.c	2004-04-19 11:26:46.436052520 +0200
@@ -31,7 +31,15 @@ mq_unlink (const char *name)
       __set_errno (EINVAL);
       return -1;
     }
-  return INLINE_SYSCALL (mq_unlink, 1, name + 1);
+
+  int ret = INLINE_SYSCALL (mq_unlink, 1, name + 1);
+
+  /* While unlink can return either EPERM or EACCES, mq_unlink should
+     return just EACCES.  */
+  if (ret < 0 && errno == EPERM)
+    __set_errno (EACCES);
+
+  return ret;
 }
 
 #else
--- libc/rt/Makefile.jj	2004-04-19 11:20:12.000000000 +0200
+++ libc/rt/Makefile	2004-04-19 11:20:27.234010463 +0200
@@ -44,7 +44,7 @@ librt-routines = $(aio-routines) \
 tests := tst-shm tst-clock tst-clock_nanosleep tst-timer tst-timer2 \
 	 tst-aio tst-aio64 tst-aio2 tst-aio3 tst-aio4 tst-aio5 tst-aio6 \
 	 tst-aio7 tst-mqueue1 tst-mqueue2 tst-mqueue3 tst-mqueue4 \
-	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 \
+	 tst-mqueue5 tst-mqueue6 tst-mqueue7 tst-mqueue8 tst-mqueue9 \
 	 tst-timer3 tst-timer4
 
 extra-libs := librt
--- libc/rt/tst-mqueue9.c.jj	2004-04-19 11:07:29.436401922 +0200
+++ libc/rt/tst-mqueue9.c	2004-04-19 11:21:32.526309233 +0200
@@ -0,0 +1,92 @@
+/* Copyright (C) 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Jakub Jelinek <jakub@redhat.com>, 2004.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <errno.h>
+#include <mqueue.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "tst-mqueue.h"
+
+#define TEST_FUNCTION do_test ()
+static int
+do_test (void)
+{
+  if (geteuid () != 0)
+    {
+      puts ("this test requires root");
+      return 0;
+    }
+
+  char name[sizeof "/tst-mqueue9-" + sizeof (pid_t) * 3];
+  snprintf (name, sizeof (name), "/tst-mqueue9-%u", getpid ());
+
+  struct mq_attr attr = { .mq_maxmsg = 1, .mq_msgsize = 1 };
+  mqd_t q = mq_open (name, O_CREAT | O_EXCL | O_RDWR, 0600, &attr);
+
+  if (q == (mqd_t) -1)
+    {
+      printf ("mq_open failed with: %m\n");
+      return 0;
+    }
+  else
+    add_temp_mq (name);
+
+  if (seteuid (1) != 0)
+    {
+      printf ("failed to seteuid (1): %m\n");
+      mq_unlink (name);
+      return 0;
+    }
+
+  int result;
+  if (mq_unlink (name) == 0)
+    {
+      puts ("mq_unlink unexpectedly succeeded");
+      result = 1;
+    }
+  else if (errno != EACCES)
+    {
+      printf ("mq_unlink did not fail with EACCES: %m\n");
+      result = 1;;
+    }
+
+  if (seteuid (0) != 0)
+    {
+      printf ("failed to seteuid (0): %m\n");
+      result = 1;
+    }
+
+  if (mq_unlink (name) != 0)
+    {
+      printf ("mq_unlink failed with: %m\n");
+      result = 1;
+    }
+
+  if (mq_close (q) != 0)
+    {
+      printf ("mq_close failed with: %m\n");
+      result = 1;
+    }
+
+  return result;
+}
+
+#include "../test-skeleton.c"
--- libc/rt/tst-mqueue4.c.jj	2004-04-13 04:06:21.000000000 +0200
+++ libc/rt/tst-mqueue4.c	2004-04-19 11:11:33.448671746 +0200
@@ -93,6 +93,18 @@ do_test (void)
       result = 1;
     }
 
+  if (mq_unlink (name) == 0)
+    {
+      puts ("mq_unlink with too long name component unexpectedly succeeded");
+      result = 1;
+    }
+  else if (errno != ENAMETOOLONG)
+    {
+      printf ("mq_unlink with too long name component did not fail with "
+	      "ENAMETOOLONG: %m\n");
+      result = 1;
+    }
+
   *p = '\0';
   attr.mq_maxmsg = 1;
   attr.mq_msgsize = 3;
--- libc/rt/tst-mqueue7.c.jj	2004-04-19 11:05:40.022010405 +0200
+++ libc/rt/tst-mqueue7.c	2004-04-19 11:05:40.022010405 +0200
@@ -93,7 +93,7 @@ do_test (int argc, char **argv)
   snprintf (after_exec_arg, sizeof (after_exec_arg),
 	    "--after-exec=0x%lx", (long) q);
 
-  char *newargv[argc + 2];
+  const char *newargv[argc + 2];
   for (int i = 1; i < argc; ++i)
     newargv[i - 1] = argv[i];
   newargv[argc - 1] = "--direct";

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]