test-errno-linux: quotactl can fail with EPERM in containers
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
This commit is contained in:
parent
d10b132bf5
commit
ef11081fed
12
ChangeLog
12
ChangeLog
|
@ -1,3 +1,15 @@
|
||||||
|
2017-11-02 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
|
test-errno-linux: quotactl can fail with EPERM in containers.
|
||||||
|
* sysdeps/unix/sysv/linux/test-errno-linux.c
|
||||||
|
(LIST, LIST_FORWARD): New macros.
|
||||||
|
(check_error_in_list): New function.
|
||||||
|
(test_wrp_rv): Accept list of permitted error codes.
|
||||||
|
(test_wrp_rv2): Remove.
|
||||||
|
(test_wrp): Call test_wrp_rv with list of error codes.
|
||||||
|
(test_wrp2): Accept list of error codes.
|
||||||
|
(do_test): Adjust. Allow EPERM for quotactl.
|
||||||
|
|
||||||
2017-11-02 Florian Weimer <fweimer@redhat.com>
|
2017-11-02 Florian Weimer <fweimer@redhat.com>
|
||||||
|
|
||||||
* stdio-common/bug16.c (do_test): Use array_length.
|
* stdio-common/bug16.c (do_test): Use array_length.
|
||||||
|
|
|
@ -18,11 +18,13 @@
|
||||||
License along with the GNU C Library; if not, see
|
License along with the GNU C Library; if not, see
|
||||||
<http://www.gnu.org/licenses/>. */
|
<http://www.gnu.org/licenses/>. */
|
||||||
|
|
||||||
|
#include <array_length.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <mqueue.h>
|
#include <mqueue.h>
|
||||||
#include <sched.h>
|
#include <sched.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
|
#include <stdbool.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
@ -67,13 +69,34 @@
|
||||||
Some tests assume "/bin/sh" names a file that exists and is not a
|
Some tests assume "/bin/sh" names a file that exists and is not a
|
||||||
directory. */
|
directory. */
|
||||||
|
|
||||||
#define test_wrp_rv(rtype, prtype, experr, syscall, ...) \
|
/* Evalutes to the arguments in a list initializer which can be used
|
||||||
|
as a single macro argument. */
|
||||||
|
#define LIST(...) { __VA_ARGS__ }
|
||||||
|
|
||||||
|
/* This macro is necessary to forward the output of LIST as a macro
|
||||||
|
argument. */
|
||||||
|
#define LIST_FORWARD(...) __VA_ARGS__
|
||||||
|
|
||||||
|
/* Return true if CODE is contained in the array [CODES, CODES +
|
||||||
|
COUNT]. */
|
||||||
|
static bool
|
||||||
|
check_error_in_list (int code, int *codes, size_t count)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < count; ++i)
|
||||||
|
if (codes[i] == code)
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define test_wrp_rv(rtype, prtype, experr_list, syscall, ...) \
|
||||||
(__extension__ ({ \
|
(__extension__ ({ \
|
||||||
errno = 0xdead; \
|
errno = 0xdead; \
|
||||||
|
int experr[] = experr_list; \
|
||||||
rtype ret = syscall (__VA_ARGS__); \
|
rtype ret = syscall (__VA_ARGS__); \
|
||||||
int err = errno; \
|
int err = errno; \
|
||||||
int fail; \
|
int fail; \
|
||||||
if ((ret == (rtype) -1) && (err == experr)) \
|
if ((ret == (rtype) -1) \
|
||||||
|
&& check_error_in_list (err, experr, array_length (experr))) \
|
||||||
fail = 0; \
|
fail = 0; \
|
||||||
else \
|
else \
|
||||||
{ \
|
{ \
|
||||||
|
@ -83,44 +106,19 @@
|
||||||
" (return "prtype")\n", ret); \
|
" (return "prtype")\n", ret); \
|
||||||
else if (err == 0xdead) \
|
else if (err == 0xdead) \
|
||||||
puts ("FAIL: " #syscall ": didn't update errno"); \
|
puts ("FAIL: " #syscall ": didn't update errno"); \
|
||||||
else if (err != experr) \
|
else \
|
||||||
printf ("FAIL: " #syscall \
|
printf ("FAIL: " #syscall \
|
||||||
": errno is: %d (%s) expected: %d (%s)\n", \
|
": errno is: %d (%s) expected one of %s\n", \
|
||||||
err, strerror (err), experr, strerror (experr));\
|
err, strerror (err), #experr_list); \
|
||||||
} \
|
} \
|
||||||
fail; \
|
fail; \
|
||||||
}))
|
}))
|
||||||
|
|
||||||
#define test_wrp_rv2(rtype, prtype, experr1, experr2, syscall, ...) \
|
|
||||||
(__extension__ ({ \
|
|
||||||
errno = 0xdead; \
|
|
||||||
rtype ret = syscall (__VA_ARGS__); \
|
|
||||||
int err = errno; \
|
|
||||||
int fail; \
|
|
||||||
if ((ret == (rtype) -1) && ((err == experr1) || (err == experr2))) \
|
|
||||||
fail = 0; \
|
|
||||||
else \
|
|
||||||
{ \
|
|
||||||
fail = 1; \
|
|
||||||
if (ret != (rtype) -1) \
|
|
||||||
printf ("FAIL: " #syscall ": didn't fail as expected" \
|
|
||||||
" (return "prtype")\n", ret); \
|
|
||||||
else if (err == 0xdead) \
|
|
||||||
puts ("FAIL: " #syscall ": didn't update errno"); \
|
|
||||||
else if (err != experr1 && err != experr2) \
|
|
||||||
printf ("FAIL: " #syscall \
|
|
||||||
": errno is: %d (%s) expected: %d (%s) or %d (%s)\n", \
|
|
||||||
err, strerror (err), experr1, strerror (experr1), \
|
|
||||||
experr2, strerror (experr2)); \
|
|
||||||
} \
|
|
||||||
fail; \
|
|
||||||
}))
|
|
||||||
|
|
||||||
#define test_wrp(experr, syscall, ...) \
|
#define test_wrp(experr, syscall, ...) \
|
||||||
test_wrp_rv(int, "%d", experr, syscall, __VA_ARGS__)
|
test_wrp_rv(int, "%d", LIST (experr), syscall, __VA_ARGS__)
|
||||||
|
|
||||||
#define test_wrp2(experr1, experr2, syscall, ...) \
|
#define test_wrp2(experr, syscall, ...) \
|
||||||
test_wrp_rv2(int, "%d", experr1, experr2, syscall, __VA_ARGS__)
|
test_wrp_rv(int, "%d", LIST_FORWARD (experr), syscall, __VA_ARGS__)
|
||||||
|
|
||||||
static int
|
static int
|
||||||
do_test (void)
|
do_test (void)
|
||||||
|
@ -150,19 +148,21 @@ do_test (void)
|
||||||
/* Linux v3.8 (676a0675c) removed the test to check at least one valid
|
/* Linux v3.8 (676a0675c) removed the test to check at least one valid
|
||||||
bit in flags (to return EINVAL). It was later added back in v3.9
|
bit in flags (to return EINVAL). It was later added back in v3.9
|
||||||
(04df32fa1). */
|
(04df32fa1). */
|
||||||
fails |= test_wrp2 (EINVAL, EBADF, inotify_add_watch, -1, "/", 0);
|
fails |= test_wrp2 (LIST (EINVAL, EBADF), inotify_add_watch, -1, "/", 0);
|
||||||
fails |= test_wrp (EINVAL, mincore, (void *) -1, 0, vec);
|
fails |= test_wrp (EINVAL, mincore, (void *) -1, 0, vec);
|
||||||
/* mlock fails if the result of the addition addr+len was less than addr
|
/* mlock fails if the result of the addition addr+len was less than addr
|
||||||
(which indicates final address overflow), however on 32 bits binaries
|
(which indicates final address overflow), however on 32 bits binaries
|
||||||
running on 64 bits kernels, internal syscall address check won't result
|
running on 64 bits kernels, internal syscall address check won't result
|
||||||
in an invalid address and thus syscalls fails later in vma
|
in an invalid address and thus syscalls fails later in vma
|
||||||
allocation. */
|
allocation. */
|
||||||
fails |= test_wrp2 (EINVAL, ENOMEM, mlock, (void *) -1, 1);
|
fails |= test_wrp2 (LIST (EINVAL, ENOMEM), mlock, (void *) -1, 1);
|
||||||
fails |= test_wrp (EINVAL, nanosleep, &ts, &ts);
|
fails |= test_wrp (EINVAL, nanosleep, &ts, &ts);
|
||||||
fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0);
|
fails |= test_wrp (EINVAL, poll, &pollfd, -1, 0);
|
||||||
/* quotactl returns ENOSYS for kernels not configured with CONFIG_QUOTA. */
|
/* quotactl returns ENOSYS for kernels not configured with
|
||||||
fails |= test_wrp2 (ENODEV, ENOSYS, quotactl, Q_GETINFO, NULL, -1,
|
CONFIG_QUOTA, and may return EPERM if called within certain types
|
||||||
(caddr_t) &dqblk);
|
of containers. */
|
||||||
|
fails |= test_wrp2 (LIST (ENODEV, ENOSYS, EPERM),
|
||||||
|
quotactl, Q_GETINFO, NULL, -1, (caddr_t) &dqblk);
|
||||||
fails |= test_wrp (EINVAL, sched_getparam, -1, &sch_param);
|
fails |= test_wrp (EINVAL, sched_getparam, -1, &sch_param);
|
||||||
fails |= test_wrp (EINVAL, sched_getscheduler, -1);
|
fails |= test_wrp (EINVAL, sched_getscheduler, -1);
|
||||||
fails |= test_wrp (EINVAL, sched_get_priority_max, -1);
|
fails |= test_wrp (EINVAL, sched_get_priority_max, -1);
|
||||||
|
|
Loading…
Reference in New Issue