Blame sysdeps/unix/sysv/linux/tst-ofdlocks-compat.c

Packit Service 82fcde
/* Check non representable OFD locks regions in non-LFS mode for compat
Packit Service 82fcde
   mode (BZ #20251)
Packit Service 82fcde
   Copyright (C) 2018 Free Software Foundation, Inc.
Packit Service 82fcde
Packit Service 82fcde
   This program is free software; you can redistribute it and/or
Packit Service 82fcde
   modify it under the terms of the GNU General Public License
Packit Service 82fcde
   as published by the Free Software Foundation; either version 2
Packit Service 82fcde
   of the License, or (at your option) any later version.
Packit Service 82fcde
Packit Service 82fcde
   This program is distributed in the hope that it will be useful,
Packit Service 82fcde
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 82fcde
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 82fcde
   GNU General Public License for more details.
Packit Service 82fcde
Packit Service 82fcde
   You should have received a copy of the GNU General Public License
Packit Service 82fcde
   along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit Service 82fcde
*/
Packit Service 82fcde
Packit Service 82fcde
#include <unistd.h>
Packit Service 82fcde
#include <fcntl.h>
Packit Service 82fcde
#include <stdint.h>
Packit Service 82fcde
#include <errno.h>
Packit Service 82fcde
Packit Service 82fcde
#include <support/temp_file.h>
Packit Service 82fcde
#include <support/check.h>
Packit Service 82fcde
Packit Service 82fcde
#include <shlib-compat.h>
Packit Service 82fcde
#if TEST_COMPAT (libc, GLIBC_2_0, GLIBC_2_28)
Packit Service 82fcde
compat_symbol_reference (libc, fcntl, fcntl, GLIBC_2_0);
Packit Service 82fcde
Packit Service 82fcde
static char *temp_filename;
Packit Service 82fcde
static int temp_fd;
Packit Service 82fcde
Packit Service 82fcde
static void
Packit Service 82fcde
do_prepare (int argc, char **argv)
Packit Service 82fcde
{
Packit Service 82fcde
  temp_fd = create_temp_file ("tst-ofdlocks-compat.", &temp_filename);
Packit Service 82fcde
  TEST_VERIFY_EXIT (temp_fd != -1);
Packit Service 82fcde
}
Packit Service 82fcde
Packit Service 82fcde
#define PREPARE do_prepare
Packit Service 82fcde
Packit Service 82fcde
/* Linux between 4.13 and 4.15 return EOVERFLOW for LFS OFD locks usage
Packit Service 82fcde
   in compat mode (non-LFS ABI running on a LFS default kernel, such as
Packit Service 82fcde
   i386 on a x86_64 kernel or s390-32 on a s390-64 kernel) [1].  This is
Packit Service 82fcde
   a kernel issue because __NR_fcntl64 is the expected way to use OFD locks
Packit Service 82fcde
   (used on GLIBC for both fcntl and fcntl64).
Packit Service 82fcde
Packit Service 82fcde
   [1] https://sourceware.org/ml/libc-alpha/2018-07/msg00243.html  */
Packit Service 82fcde
Packit Service 82fcde
static int
Packit Service 82fcde
do_test (void)
Packit Service 82fcde
{
Packit Service 82fcde
  /* The compat fcntl version for architectures which support non-LFS
Packit Service 82fcde
     operations does not wrap the flock OFD argument, so the struct is passed
Packit Service 82fcde
     unmodified to kernel.  It means no EOVERFLOW is returned, so operations
Packit Service 82fcde
     with LFS should not incur in failure.  */
Packit Service 82fcde
Packit Service 82fcde
  struct flock64 lck64 = {
Packit Service 82fcde
    .l_type   = F_WRLCK,
Packit Service 82fcde
    .l_whence = SEEK_SET,
Packit Service 82fcde
    .l_start  = (off64_t)INT32_MAX + 1024,
Packit Service 82fcde
    .l_len    = 1024,
Packit Service 82fcde
  };
Packit Service 82fcde
  int ret = fcntl (temp_fd, F_OFD_SETLKW, &lck64);
Packit Service 82fcde
  if (ret == -1 && errno == EINVAL)
Packit Service 82fcde
    /* OFD locks are only available on Linux 3.15.  */
Packit Service 82fcde
    FAIL_UNSUPPORTED ("fcntl (F_OFD_SETLKW) not supported");
Packit Service 82fcde
Packit Service 82fcde
  TEST_VERIFY_EXIT (ret == 0);
Packit Service 82fcde
Packit Service 82fcde
  /* Open file description locks placed through the same open file description
Packit Service 82fcde
     (either by same file descriptor or a duplicated one created by fork,
Packit Service 82fcde
     dup, fcntl F_DUPFD, etc.) overwrites then old lock.  To force a
Packit Service 82fcde
     conflicting lock combination, it creates a new file descriptor.  */
Packit Service 82fcde
  int fd = open64 (temp_filename, O_RDWR, 0666);
Packit Service 82fcde
  TEST_VERIFY_EXIT (fd != -1);
Packit Service 82fcde
Packit Service 82fcde
  struct flock64 lck = {
Packit Service 82fcde
    .l_type   = F_WRLCK,
Packit Service 82fcde
    .l_whence = SEEK_SET,
Packit Service 82fcde
    .l_start  = INT32_MAX - 1024,
Packit Service 82fcde
    .l_len    = 4 * 1024,
Packit Service 82fcde
  };
Packit Service 82fcde
  TEST_VERIFY (fcntl (fd, F_OFD_GETLK, &lck) == 0);
Packit Service 82fcde
Packit Service 82fcde
  return 0;
Packit Service 82fcde
}
Packit Service 82fcde
#else
Packit Service 82fcde
static int
Packit Service 82fcde
do_test (void)
Packit Service 82fcde
{
Packit Service 82fcde
  return 77;
Packit Service 82fcde
}
Packit Service 82fcde
#endif
Packit Service 82fcde
Packit Service 82fcde
#include <support/test-driver.c>