Statistics
| Branch: | Revision:

root / prex-0.9.0 / usr / server / fs / vfs / vfs_security.c @ 03e9c04a

History | View | Annotate | Download (6.25 KB)

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
}