Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:15

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  *  @file
0005  *
0006  *  @brief RTEMS File System Permissions Check Support
0007  *  @ingroup LibIOInternal
0008  */
0009 
0010 /*
0011  * Copyright (c) 2012 embedded brains GmbH & Co. KG
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  * 1. Redistributions of source code must retain the above copyright
0017  *    notice, this list of conditions and the following disclaimer.
0018  * 2. Redistributions in binary form must reproduce the above copyright
0019  *    notice, this list of conditions and the following disclaimer in the
0020  *    documentation and/or other materials provided with the distribution.
0021  *
0022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0023  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0024  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0025  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0026  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0027  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0028  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0029  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0030  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0031  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0032  * POSSIBILITY OF SUCH DAMAGE.
0033  */
0034 
0035 #ifdef HAVE_CONFIG_H
0036 #include "config.h"
0037 #endif
0038 
0039 #include <sys/stat.h>
0040 
0041 #include <rtems/libio_.h>
0042 
0043 #define RTEMS_FS_USR_SHIFT 6
0044 #define RTEMS_FS_GRP_SHIFT 3
0045 #define RTEMS_FS_OTH_SHIFT 0
0046 
0047 RTEMS_STATIC_ASSERT(
0048   (RTEMS_FS_PERMS_READ << RTEMS_FS_USR_SHIFT) == S_IRUSR,
0049   S_IRUSR
0050 );
0051 RTEMS_STATIC_ASSERT(
0052   (RTEMS_FS_PERMS_READ << RTEMS_FS_GRP_SHIFT) == S_IRGRP,
0053   S_IRGRP
0054 );
0055 RTEMS_STATIC_ASSERT(
0056   (RTEMS_FS_PERMS_READ << RTEMS_FS_OTH_SHIFT) == S_IROTH,
0057   S_IROTH
0058 );
0059 
0060 RTEMS_STATIC_ASSERT(
0061   (RTEMS_FS_PERMS_WRITE << RTEMS_FS_USR_SHIFT) == S_IWUSR,
0062   S_IWUSR
0063 );
0064 RTEMS_STATIC_ASSERT(
0065   (RTEMS_FS_PERMS_WRITE << RTEMS_FS_GRP_SHIFT) == S_IWGRP,
0066   S_IWGRP
0067 );
0068 RTEMS_STATIC_ASSERT(
0069   (RTEMS_FS_PERMS_WRITE << RTEMS_FS_OTH_SHIFT) == S_IWOTH,
0070   S_IWOTH
0071 );
0072 
0073 RTEMS_STATIC_ASSERT(
0074   (RTEMS_FS_PERMS_EXEC << RTEMS_FS_USR_SHIFT) == S_IXUSR,
0075   S_IXUSR
0076 );
0077 RTEMS_STATIC_ASSERT(
0078   (RTEMS_FS_PERMS_EXEC << RTEMS_FS_GRP_SHIFT) == S_IXGRP,
0079   S_IXGRP
0080 );
0081 RTEMS_STATIC_ASSERT(
0082   (RTEMS_FS_PERMS_EXEC << RTEMS_FS_OTH_SHIFT) == S_IXOTH,
0083   S_IXOTH
0084 );
0085 
0086 static bool equals_supplementary_group(
0087   const rtems_user_env_t *uenv,
0088   gid_t object_gid
0089 )
0090 {
0091   size_t i;
0092 
0093   for (i = 0; i < uenv->ngroups; ++i) {
0094     if (uenv->groups[i] == object_gid) {
0095       return true;
0096     }
0097   }
0098 
0099   return false;
0100 }
0101 
0102 bool rtems_filesystem_check_access(
0103   int flags,
0104   mode_t object_mode,
0105   uid_t object_uid,
0106   gid_t object_gid
0107 )
0108 {
0109   const rtems_user_env_t *uenv = rtems_current_user_env_get();
0110   mode_t access_flags = flags & RTEMS_FS_PERMS_RWX;
0111   uid_t task_uid = uenv->euid;
0112 
0113   if (task_uid == 0 || task_uid == object_uid) {
0114     access_flags <<= RTEMS_FS_USR_SHIFT;
0115   } else {
0116     gid_t task_gid = uenv->egid;
0117 
0118     if (
0119       task_gid == 0
0120         || task_gid == object_gid
0121         || equals_supplementary_group(uenv, object_gid)
0122     ) {
0123       access_flags <<= RTEMS_FS_GRP_SHIFT;
0124     } else {
0125       access_flags <<= RTEMS_FS_OTH_SHIFT;
0126     }
0127   }
0128 
0129   return (access_flags & object_mode) == access_flags;
0130 }
0131 
0132 bool rtems_filesystem_eval_path_check_access(
0133   rtems_filesystem_eval_path_context_t *ctx,
0134   int eval_flags,
0135   mode_t node_mode,
0136   uid_t node_uid,
0137   gid_t node_gid
0138 )
0139 {
0140   bool access_ok = rtems_filesystem_check_access(
0141     eval_flags,
0142     node_mode,
0143     node_uid,
0144     node_gid
0145   );
0146 
0147   if (!access_ok) {
0148     rtems_filesystem_eval_path_error(ctx, EACCES);
0149   }
0150 
0151   return access_ok;
0152 }