Prex Home / Browse Source - Prex Version: 0.9.0

root/usr/server/fs/vfs/vfs_security.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. capable
  2. sec_file_permission
  3. sec_vnode_permission

   1 /*-
   2  * Copyright (c) 2007, Kohsuke Ohtani All rights reserved.
   3  *
   4  * Redistribution and use in source and binary forms, with or without
   5  * modification, are permitted provided that the following conditions
   6  * are met:
   7  * 1. Redistributions of source code must retain the above copyright
   8  *    notice, this list of conditions and the following disclaimer.
   9  * 2. Redistributions in binary form must reproduce the above copyright
  10  *    notice, this list of conditions and the following disclaimer in the
  11  *    documentation and/or other materials provided with the distribution.
  12  * 3. Neither the name of the author nor the names of any co-contributors
  13  *    may be used to endorse or promote products derived from this software
  14  *    without specific prior written permission.
  15  *
  16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
  17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
  20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  26  * SUCH DAMAGE.
  27  */
  28 
  29 /*
  30  * vfs_security.c - Routines to check security permission.
  31  */
  32 
  33 /**
  34  * General Design:
  35  *
  36  * Prex supports the file access permission based on the path
  37  * name. It means that the applications can access to only
  38  * certain area of the file system.
  39  *
  40  * The file system has the following structure:
  41  *
  42  * /boot
  43  *
  44  *   This directory contains the server executable files and
  45  *   the system files required for OS boot. Reading this
  46  *   directory is allowed only to the server process which has
  47  *   CAP_SYSFILES capability.  Nobody can write to this
  48  *   directory at any time.
  49  *
  50  * /bin
  51  *
  52  *   This directory contains the trusted applications.  This
  53  *   is read-only directory for normal processes, and
  54  *   CAP_SYSFILES is required to write files to it. In typical
  55  *   case, a software installer has right to copy the
  56  *   executable files to this directory.
  57  *
  58  * /etc
  59  *
  60  *   This directory contains the various configuration files.
  61  *   This is read-only for normal processes, and CAP_SYSFILES
  62  *   is required to modify /etc. The system configurator has
  63  *   responsible to modify the contents in /etc.
  64  *
  65  * /private
  66  *
  67  *   This is the restricted system area and is inaccessible to
  68  *   the normal processes. It contains private user data like
  69  *   address book or calendar entries. CAP_USERFILES
  70  *   capability is required to access to the /private
  71  *   contents. The PIM application will have CAP_USERFILES.
  72  *
  73  * /all the rest
  74  *
  75  *   Access to all the other directories is unrestricted.
  76  *
  77  *
  78  * <Directories and required capabilities>
  79  *
  80  *  Directory  Read           Write          Execute
  81  *  ---------  -------------  -------------  --------------
  82  *  /boot      CAP_SYSFILES   Not Allowed    Any
  83  *
  84  *  /bin       Any            CAP_SYSFILES   Any
  85  *
  86  *  /etc       Any            CAP_SYSFILES   Not Allowed
  87  *
  88  *  /private   CAP_USERFILES  CAP_USERFILES  Not Allowed
  89  *
  90  *  /other     Any            Any            Not Allowed
  91  *
  92  */
  93 
  94 #include <sys/prex.h>
  95 #include <sys/list.h>
  96 #include <sys/fcntl.h>
  97 
  98 #include <limits.h>
  99 #include <stdlib.h>
 100 #include <string.h>
 101 #include <stdio.h>
 102 #include <errno.h>
 103 
 104 #include "vfs.h"
 105 
 106 #define ACC_NG          -1              /* access is not allowed */
 107 #define ACC_OK          0               /* access is allowed */
 108 
 109 /*
 110  * Capability mapping for path and file access
 111  */
 112 struct fscap_map {
 113         char    *path;                  /* directory name */
 114         size_t  len;                    /* length of directory name */
 115         int     cap_read;               /* required capability to read */
 116         int     cap_write;              /* required capability to write */
 117         int     cap_exec;               /* required capability to execute */
 118 };
 119 
 120 /*
 121  * Capability mapping table
 122  */
 123 static const struct fscap_map fscap_table[] =
 124 {
 125         /* path        len read           write          execute       */
 126         /* ----------- --- -------------- -------------- ------------- */
 127         { "/boot/",     6, CAP_SYSFILES,  ACC_NG,        ACC_OK       },
 128         { "/bin/",      5, ACC_OK,        CAP_SYSFILES,  ACC_OK       },
 129         { "/etc/",      5, ACC_OK,        CAP_SYSFILES,  ACC_NG       },
 130         { "/private/",  9, CAP_USERFILES, CAP_USERFILES, ACC_NG       },
 131         { NULL,         0, 0,             0,             0            },
 132 };
 133 
 134 
 135 /*
 136  * Return true if the task has specified capability.
 137  */
 138 static int
 139 capable(task_t task, cap_t cap)
 140 {
 141 
 142         if (cap == ACC_OK)
 143                 return 1;
 144 
 145         if (cap == ACC_NG)
 146                 return 0;
 147 
 148         if (task_chkcap(task, cap) != 0) {
 149                 /* No capability */
 150                 return 0;
 151         }
 152         return 1;
 153 }
 154 
 155 /*
 156  * Check if the task has capability to access the file.
 157  * Return 0 if it has capability.
 158  */
 159 int
 160 sec_file_permission(task_t task, char *path, int acc)
 161 {
 162         const struct fscap_map *map;
 163         int found = 0;
 164         int error = 0;
 165 
 166         if (acc == 0)
 167                 return 0;
 168 
 169         /*
 170          * Look up capability mapping table.
 171          */
 172         map = &fscap_table[0];
 173         while (map->path != NULL) {
 174                 if (!strncmp(path, map->path, map->len)) {
 175                         found = 1;
 176                         break;
 177                 }
 178                 map++;
 179         }
 180 
 181         if (found) {
 182                 /*
 183                  * File under known directory.
 184                  */
 185                 if (acc & VREAD) {
 186                         if (!capable(task, map->cap_read))
 187                                 error = EACCES;
 188                 }
 189                 if (acc & VWRITE) {
 190                         if (!capable(task, map->cap_write))
 191                                 error = EACCES;
 192                 }
 193                 DPRINTF(VFSDB_CAP,
 194                         ("sec_file_permission: known directory "
 195                          "path=%s read=%x write=%x execute=%d\n",
 196                          path, map->cap_read, map->cap_write, map->cap_exec));
 197         }
 198 
 199         if (error != 0) {
 200                 DPRINTF(VFSDB_CAP,
 201                         ("sec_file_permission: no capability for %02x "
 202                          "task=%08x path=%s\n",
 203                          acc, task, path));
 204         }
 205         return error;
 206 }
 207 
 208 /*
 209  * Check if the file is executable.
 210  */
 211 int
 212 sec_vnode_permission(char *path)
 213 {
 214         const struct fscap_map *map;
 215         int found = 0;
 216 
 217         /*
 218          * Look up capability mapping table.
 219          */
 220         map = &fscap_table[0];
 221         while (map->path != NULL) {
 222                 if (!strncmp(path, map->path, map->len)) {
 223                         found = 1;
 224                         break;
 225                 }
 226                 map++;
 227         }
 228 
 229         /*
 230          * We allow the file execution only with the file
 231          * under specific directories.
 232          */
 233         if ((found == 1) && (map->cap_exec == ACC_OK)) {
 234                 return 0;
 235         }
 236         return EACCES;
 237 }

/* [<][>][^][v][top][bottom][index][help] */