(root)/
tar-1.35/
gnu/
getfilecon.c
       1  /* wrap getfilecon, lgetfilecon, and fgetfilecon
       2     Copyright (C) 2009-2023 Free Software Foundation, Inc.
       3  
       4     This file is free software: you can redistribute it and/or modify
       5     it under the terms of the GNU Lesser General Public License as
       6     published by the Free Software Foundation; either version 2.1 of the
       7     License, or (at your option) any later version.
       8  
       9     This file is distributed in the hope that it will be useful,
      10     but WITHOUT ANY WARRANTY; without even the implied warranty of
      11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12     GNU Lesser General Public License for more details.
      13  
      14     You should have received a copy of the GNU Lesser General Public License
      15     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      16  
      17  /* written by Jim Meyering */
      18  
      19  #include <config.h>
      20  
      21  #include <selinux/selinux.h>
      22  
      23  #include <sys/types.h>
      24  #include <errno.h>
      25  #include <string.h>
      26  
      27  /* FIXME: remove this once there is an errno-gnu module
      28     that guarantees the definition of ENODATA.  */
      29  #ifndef ENODATA
      30  # define ENODATA ENOTSUP
      31  #endif
      32  
      33  #undef getfilecon
      34  #undef lgetfilecon
      35  #undef fgetfilecon
      36  int getfilecon (char const *file, char **con);
      37  int lgetfilecon (char const *file, char **con);
      38  int fgetfilecon (int fd, char **con);
      39  
      40  /* getfilecon, lgetfilecon, and fgetfilecon can all misbehave, be it
      41     via an old version of libselinux where these would return 0 and set the
      42     result context to NULL, or via a modern kernel+lib operating on a file
      43     from a disk whose attributes were set by a kernel from around 2006.
      44     In that latter case, the functions return a length of 10 for the
      45     "unlabeled" context.  Map both failures to a return value of -1, and
      46     set errno to ENOTSUP in the first case, and ENODATA in the latter.  */
      47  
      48  static int
      49  map_to_failure (int ret, char **con)
      50  {
      51    if (ret == 0)
      52      {
      53        errno = ENOTSUP;
      54        return -1;
      55      }
      56  
      57    if (ret == 10 && strcmp (*con, "unlabeled") == 0)
      58      {
      59        freecon (*con);
      60        *con = NULL;
      61        errno = ENODATA;
      62        return -1;
      63      }
      64  
      65    return ret;
      66  }
      67  
      68  int
      69  rpl_getfilecon (char const *file, char **con)
      70  {
      71    int ret = getfilecon (file, con);
      72    return map_to_failure (ret, con);
      73  }
      74  
      75  int
      76  rpl_lgetfilecon (char const *file, char **con)
      77  {
      78    int ret = lgetfilecon (file, con);
      79    return map_to_failure (ret, con);
      80  }
      81  
      82  int
      83  rpl_fgetfilecon (int fd, char**con)
      84  {
      85    int ret = fgetfilecon (fd, con);
      86    return map_to_failure (ret, con);
      87  }