LCOV - code coverage report
Current view: top level - basic - smack-util.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 10 122 8.2 %
Date: 2019-08-23 13:36:53 Functions: 2 12 16.7 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 4 126 3.2 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: LGPL-2.1+ */
       2                 :            : /***
       3                 :            :   Copyright © 2013 Intel Corporation
       4                 :            : 
       5                 :            :   Author: Auke Kok <auke-jan.h.kok@intel.com>
       6                 :            : ***/
       7                 :            : 
       8                 :            : #include <errno.h>
       9                 :            : #include <fcntl.h>
      10                 :            : #include <string.h>
      11                 :            : #include <sys/stat.h>
      12                 :            : #include <sys/xattr.h>
      13                 :            : #include <unistd.h>
      14                 :            : 
      15                 :            : #include "alloc-util.h"
      16                 :            : #include "fd-util.h"
      17                 :            : #include "fileio.h"
      18                 :            : #include "log.h"
      19                 :            : #include "macro.h"
      20                 :            : #include "path-util.h"
      21                 :            : #include "process-util.h"
      22                 :            : #include "smack-util.h"
      23                 :            : #include "stdio-util.h"
      24                 :            : #include "string-table.h"
      25                 :            : #include "xattr-util.h"
      26                 :            : 
      27                 :            : #if ENABLE_SMACK
      28                 :        248 : bool mac_smack_use(void) {
      29                 :            :         static int cached_use = -1;
      30                 :            : 
      31         [ +  + ]:        248 :         if (cached_use < 0)
      32                 :        184 :                 cached_use = access("/sys/fs/smackfs/", F_OK) >= 0;
      33                 :            : 
      34                 :        248 :         return cached_use;
      35                 :            : }
      36                 :            : 
      37                 :            : static const char* const smack_attr_table[_SMACK_ATTR_MAX] = {
      38                 :            :         [SMACK_ATTR_ACCESS]     = "security.SMACK64",
      39                 :            :         [SMACK_ATTR_EXEC]       = "security.SMACK64EXEC",
      40                 :            :         [SMACK_ATTR_MMAP]       = "security.SMACK64MMAP",
      41                 :            :         [SMACK_ATTR_TRANSMUTE]  = "security.SMACK64TRANSMUTE",
      42                 :            :         [SMACK_ATTR_IPIN]       = "security.SMACK64IPIN",
      43                 :            :         [SMACK_ATTR_IPOUT]      = "security.SMACK64IPOUT",
      44                 :            : };
      45                 :            : 
      46   [ #  #  #  # ]:          0 : DEFINE_STRING_TABLE_LOOKUP(smack_attr, SmackAttr);
      47                 :            : 
      48                 :          0 : int mac_smack_read(const char *path, SmackAttr attr, char **label) {
      49         [ #  # ]:          0 :         assert(path);
      50   [ #  #  #  # ]:          0 :         assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
      51         [ #  # ]:          0 :         assert(label);
      52                 :            : 
      53         [ #  # ]:          0 :         if (!mac_smack_use())
      54                 :          0 :                 return 0;
      55                 :            : 
      56                 :          0 :         return getxattr_malloc(path, smack_attr_to_string(attr), label, true);
      57                 :            : }
      58                 :            : 
      59                 :          0 : int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
      60         [ #  # ]:          0 :         assert(fd >= 0);
      61   [ #  #  #  # ]:          0 :         assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
      62         [ #  # ]:          0 :         assert(label);
      63                 :            : 
      64         [ #  # ]:          0 :         if (!mac_smack_use())
      65                 :          0 :                 return 0;
      66                 :            : 
      67                 :          0 :         return fgetxattr_malloc(fd, smack_attr_to_string(attr), label);
      68                 :            : }
      69                 :            : 
      70                 :          0 : int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
      71                 :            :         int r;
      72                 :            : 
      73         [ #  # ]:          0 :         assert(path);
      74   [ #  #  #  # ]:          0 :         assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
      75                 :            : 
      76         [ #  # ]:          0 :         if (!mac_smack_use())
      77                 :          0 :                 return 0;
      78                 :            : 
      79         [ #  # ]:          0 :         if (label)
      80                 :          0 :                 r = lsetxattr(path, smack_attr_to_string(attr), label, strlen(label), 0);
      81                 :            :         else
      82                 :          0 :                 r = lremovexattr(path, smack_attr_to_string(attr));
      83         [ #  # ]:          0 :         if (r < 0)
      84                 :          0 :                 return -errno;
      85                 :            : 
      86                 :          0 :         return 0;
      87                 :            : }
      88                 :            : 
      89                 :          0 : int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
      90                 :            :         int r;
      91                 :            : 
      92         [ #  # ]:          0 :         assert(fd >= 0);
      93   [ #  #  #  # ]:          0 :         assert(attr >= 0 && attr < _SMACK_ATTR_MAX);
      94                 :            : 
      95         [ #  # ]:          0 :         if (!mac_smack_use())
      96                 :          0 :                 return 0;
      97                 :            : 
      98         [ #  # ]:          0 :         if (label)
      99                 :          0 :                 r = fsetxattr(fd, smack_attr_to_string(attr), label, strlen(label), 0);
     100                 :            :         else
     101                 :          0 :                 r = fremovexattr(fd, smack_attr_to_string(attr));
     102         [ #  # ]:          0 :         if (r < 0)
     103                 :          0 :                 return -errno;
     104                 :            : 
     105                 :          0 :         return 0;
     106                 :            : }
     107                 :            : 
     108                 :          0 : int mac_smack_apply_pid(pid_t pid, const char *label) {
     109                 :            :         const char *p;
     110                 :          0 :         int r = 0;
     111                 :            : 
     112         [ #  # ]:          0 :         assert(label);
     113                 :            : 
     114         [ #  # ]:          0 :         if (!mac_smack_use())
     115                 :          0 :                 return 0;
     116                 :            : 
     117   [ #  #  #  #  :          0 :         p = procfs_file_alloca(pid, "attr/current");
                   #  # ]
     118                 :          0 :         r = write_string_file(p, label, WRITE_STRING_FILE_DISABLE_BUFFER);
     119         [ #  # ]:          0 :         if (r < 0)
     120                 :          0 :                 return r;
     121                 :            : 
     122                 :          0 :         return r;
     123                 :            : }
     124                 :            : 
     125                 :          0 : static int smack_fix_fd(int fd , const char *abspath, LabelFixFlags flags) {
     126                 :            :         char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)];
     127                 :            :         const char *label;
     128                 :            :         struct stat st;
     129                 :            :         int r;
     130                 :            : 
     131                 :            :         /* The caller should have done the sanity checks. */
     132         [ #  # ]:          0 :         assert(abspath);
     133         [ #  # ]:          0 :         assert(path_is_absolute(abspath));
     134                 :            : 
     135                 :            :         /* Path must be in /dev. */
     136         [ #  # ]:          0 :         if (!path_startswith(abspath, "/dev"))
     137                 :          0 :                 return 0;
     138                 :            : 
     139         [ #  # ]:          0 :         if (fstat(fd, &st) < 0)
     140                 :          0 :                 return -errno;
     141                 :            : 
     142                 :            :         /*
     143                 :            :          * Label directories and character devices "*".
     144                 :            :          * Label symlinks "_".
     145                 :            :          * Don't change anything else.
     146                 :            :          */
     147                 :            : 
     148         [ #  # ]:          0 :         if (S_ISDIR(st.st_mode))
     149                 :          0 :                 label = SMACK_STAR_LABEL;
     150         [ #  # ]:          0 :         else if (S_ISLNK(st.st_mode))
     151                 :          0 :                 label = SMACK_FLOOR_LABEL;
     152         [ #  # ]:          0 :         else if (S_ISCHR(st.st_mode))
     153                 :          0 :                 label = SMACK_STAR_LABEL;
     154                 :            :         else
     155                 :          0 :                 return 0;
     156                 :            : 
     157         [ #  # ]:          0 :         xsprintf(procfs_path, "/proc/self/fd/%i", fd);
     158         [ #  # ]:          0 :         if (setxattr(procfs_path, "security.SMACK64", label, strlen(label), 0) < 0) {
     159                 :          0 :                 _cleanup_free_ char *old_label = NULL;
     160                 :            : 
     161                 :          0 :                 r = -errno;
     162                 :            : 
     163                 :            :                 /* If the FS doesn't support labels, then exit without warning */
     164         [ #  # ]:          0 :                 if (r == -EOPNOTSUPP)
     165                 :          0 :                         return 0;
     166                 :            : 
     167                 :            :                 /* It the FS is read-only and we were told to ignore failures caused by that, suppress error */
     168   [ #  #  #  # ]:          0 :                 if (r == -EROFS && (flags & LABEL_IGNORE_EROFS))
     169                 :          0 :                         return 0;
     170                 :            : 
     171                 :            :                 /* If the old label is identical to the new one, suppress any kind of error */
     172         [ #  # ]:          0 :                 if (getxattr_malloc(procfs_path, "security.SMACK64", &old_label, false) >= 0 &&
     173         [ #  # ]:          0 :                     streq(old_label, label))
     174                 :          0 :                         return 0;
     175                 :            : 
     176         [ #  # ]:          0 :                 return log_debug_errno(r, "Unable to fix SMACK label of %s: %m", abspath);
     177                 :            :         }
     178                 :            : 
     179                 :          0 :         return 0;
     180                 :            : }
     181                 :            : 
     182                 :          0 : int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
     183                 :          0 :         _cleanup_free_ char *p = NULL;
     184                 :          0 :         _cleanup_close_ int fd = -1;
     185                 :            :         int r;
     186                 :            : 
     187         [ #  # ]:          0 :         assert(path);
     188                 :            : 
     189         [ #  # ]:          0 :         if (!mac_smack_use())
     190                 :          0 :                 return 0;
     191                 :            : 
     192                 :          0 :         fd = openat(dirfd, path, O_NOFOLLOW|O_CLOEXEC|O_PATH);
     193         [ #  # ]:          0 :         if (fd < 0) {
     194   [ #  #  #  # ]:          0 :                 if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT)
     195                 :          0 :                         return 0;
     196                 :            : 
     197                 :          0 :                 return -errno;
     198                 :            :         }
     199                 :            : 
     200         [ #  # ]:          0 :         if (!path_is_absolute(path)) {
     201                 :          0 :                 r = fd_get_path(fd, &p);
     202         [ #  # ]:          0 :                 if (r < 0)
     203                 :          0 :                         return r;
     204                 :          0 :                 path = p;
     205                 :            :         }
     206                 :            : 
     207                 :          0 :         return smack_fix_fd(fd, path, flags);
     208                 :            : }
     209                 :            : 
     210                 :        236 : int mac_smack_fix(const char *path, LabelFixFlags flags) {
     211                 :        236 :         _cleanup_free_ char *abspath = NULL;
     212                 :        236 :         _cleanup_close_ int fd = -1;
     213                 :            :         int r;
     214                 :            : 
     215         [ -  + ]:        236 :         assert(path);
     216                 :            : 
     217         [ +  - ]:        236 :         if (!mac_smack_use())
     218                 :        236 :                 return 0;
     219                 :            : 
     220                 :          0 :         r = path_make_absolute_cwd(path, &abspath);
     221         [ #  # ]:          0 :         if (r < 0)
     222                 :          0 :                 return r;
     223                 :            : 
     224                 :          0 :         fd = open(abspath, O_NOFOLLOW|O_CLOEXEC|O_PATH);
     225         [ #  # ]:          0 :         if (fd < 0) {
     226   [ #  #  #  # ]:          0 :                 if ((flags & LABEL_IGNORE_ENOENT) && errno == ENOENT)
     227                 :          0 :                         return 0;
     228                 :            : 
     229                 :          0 :                 return -errno;
     230                 :            :         }
     231                 :            : 
     232                 :          0 :         return smack_fix_fd(fd, abspath, flags);
     233                 :            : }
     234                 :            : 
     235                 :          0 : int mac_smack_copy(const char *dest, const char *src) {
     236                 :          0 :         int r = 0;
     237                 :          0 :         _cleanup_free_ char *label = NULL;
     238                 :            : 
     239         [ #  # ]:          0 :         assert(dest);
     240         [ #  # ]:          0 :         assert(src);
     241                 :            : 
     242                 :          0 :         r = mac_smack_read(src, SMACK_ATTR_ACCESS, &label);
     243         [ #  # ]:          0 :         if (r < 0)
     244                 :          0 :                 return r;
     245                 :            : 
     246                 :          0 :         r = mac_smack_apply(dest, SMACK_ATTR_ACCESS, label);
     247         [ #  # ]:          0 :         if (r < 0)
     248                 :          0 :                 return r;
     249                 :            : 
     250                 :          0 :         return r;
     251                 :            : }
     252                 :            : 
     253                 :            : #else
     254                 :            : bool mac_smack_use(void) {
     255                 :            :         return false;
     256                 :            : }
     257                 :            : 
     258                 :            : int mac_smack_read(const char *path, SmackAttr attr, char **label) {
     259                 :            :         return -EOPNOTSUPP;
     260                 :            : }
     261                 :            : 
     262                 :            : int mac_smack_read_fd(int fd, SmackAttr attr, char **label) {
     263                 :            :         return -EOPNOTSUPP;
     264                 :            : }
     265                 :            : 
     266                 :            : int mac_smack_apply(const char *path, SmackAttr attr, const char *label) {
     267                 :            :         return 0;
     268                 :            : }
     269                 :            : 
     270                 :            : int mac_smack_apply_fd(int fd, SmackAttr attr, const char *label) {
     271                 :            :         return 0;
     272                 :            : }
     273                 :            : 
     274                 :            : int mac_smack_apply_pid(pid_t pid, const char *label) {
     275                 :            :         return 0;
     276                 :            : }
     277                 :            : 
     278                 :            : int mac_smack_fix(const char *path, LabelFixFlags flags) {
     279                 :            :         return 0;
     280                 :            : }
     281                 :            : 
     282                 :            : int mac_smack_fix_at(int dirfd, const char *path, LabelFixFlags flags) {
     283                 :            :         return 0;
     284                 :            : }
     285                 :            : 
     286                 :            : int mac_smack_copy(const char *dest, const char *src) {
     287                 :            :         return 0;
     288                 :            : }
     289                 :            : #endif

Generated by: LCOV version 1.14