1 |
kumaneko |
111 |
/* |
2 |
|
|
* fs/sakura_mount.c |
3 |
|
|
* |
4 |
|
|
* Implementation of the Domain-Free Mandatory Access Control. |
5 |
|
|
* |
6 |
|
|
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
7 |
|
|
* |
8 |
kumaneko |
746 |
* Version: 1.5.3-pre 2007/12/03 |
9 |
kumaneko |
111 |
* |
10 |
|
|
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
|
|
* See README.ccs for ChangeLog. |
12 |
|
|
* |
13 |
|
|
*/ |
14 |
|
|
/***** SAKURA Linux start. *****/ |
15 |
|
|
|
16 |
|
|
#include <linux/ccs_common.h> |
17 |
|
|
#include <linux/sakura.h> |
18 |
|
|
#include <linux/realpath.h> |
19 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,20) |
20 |
|
|
#include <linux/namespace.h> |
21 |
|
|
#endif |
22 |
|
|
|
23 |
|
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,15) |
24 |
|
|
#define MS_UNBINDABLE (1<<17) /* change to unbindable */ |
25 |
|
|
#define MS_PRIVATE (1<<18) /* change to private */ |
26 |
|
|
#define MS_SLAVE (1<<19) /* change to slave */ |
27 |
|
|
#define MS_SHARED (1<<20) /* change to shared */ |
28 |
|
|
#endif |
29 |
|
|
|
30 |
|
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0) |
31 |
|
|
#include <linux/namei.h> |
32 |
|
|
#else |
33 |
|
|
static inline void module_put(struct module *module) |
34 |
|
|
{ |
35 |
|
|
if (module) __MOD_DEC_USE_COUNT(module); |
36 |
|
|
} |
37 |
|
|
#endif |
38 |
|
|
|
39 |
|
|
extern const char *ccs_log_level; |
40 |
|
|
|
41 |
|
|
/***** KEYWORDS for mount restrictions. *****/ |
42 |
|
|
|
43 |
|
|
#define MOUNT_BIND_KEYWORD "--bind" /* Allow to call 'mount --bind /source_dir /dest_dir' */ |
44 |
|
|
#define MOUNT_MOVE_KEYWORD "--move" /* Allow to call 'mount --move /old_dir /new_dir ' */ |
45 |
|
|
#define MOUNT_REMOUNT_KEYWORD "--remount" /* Allow to call 'mount -o remount /dir ' */ |
46 |
|
|
#define MOUNT_MAKE_UNBINDABLE_KEYWORD "--make-unbindable" /* Allow to call 'mount --make-unbindable /dir' */ |
47 |
|
|
#define MOUNT_MAKE_PRIVATE_KEYWORD "--make-private" /* Allow to call 'mount --make-private /dir' */ |
48 |
|
|
#define MOUNT_MAKE_SLAVE_KEYWORD "--make-slave" /* Allow to call 'mount --make-slave /dir' */ |
49 |
|
|
#define MOUNT_MAKE_SHARED_KEYWORD "--make-shared" /* Allow to call 'mount --make-shared /dir' */ |
50 |
|
|
|
51 |
|
|
/***** The structure for mount restrictions. *****/ |
52 |
|
|
|
53 |
kumaneko |
214 |
struct mount_entry { |
54 |
kumaneko |
722 |
struct list1_head list; |
55 |
kumaneko |
111 |
const struct path_info *dev_name; |
56 |
|
|
const struct path_info *dir_name; |
57 |
|
|
const struct path_info *fs_type; |
58 |
kumaneko |
325 |
unsigned long flags; |
59 |
kumaneko |
621 |
bool is_deleted; |
60 |
kumaneko |
214 |
}; |
61 |
kumaneko |
111 |
|
62 |
|
|
/************************* MOUNT RESTRICTION HANDLER *************************/ |
63 |
|
|
|
64 |
kumaneko |
614 |
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) |
65 |
kumaneko |
111 |
static void put_filesystem(struct file_system_type *fs) |
66 |
|
|
{ |
67 |
|
|
module_put(fs->owner); |
68 |
|
|
} |
69 |
kumaneko |
614 |
#endif |
70 |
kumaneko |
111 |
|
71 |
kumaneko |
722 |
static LIST1_HEAD(mount_list); |
72 |
kumaneko |
111 |
|
73 |
kumaneko |
621 |
static int AddMountACL(const char *dev_name, const char *dir_name, const char *fs_type, const unsigned long flags, const bool is_delete) |
74 |
kumaneko |
111 |
{ |
75 |
kumaneko |
214 |
struct mount_entry *new_entry, *ptr; |
76 |
kumaneko |
111 |
const struct path_info *fs, *dev, *dir; |
77 |
kumaneko |
652 |
static DEFINE_MUTEX(lock); |
78 |
kumaneko |
111 |
int error = -ENOMEM; |
79 |
|
|
if ((fs = SaveName(fs_type)) == NULL) return -EINVAL; |
80 |
|
|
if (!dev_name) dev_name = "<NULL>"; /* Map dev_name to "<NULL>" for if no dev_name given. */ |
81 |
|
|
if (strcmp(fs->name, MOUNT_REMOUNT_KEYWORD) == 0) dev_name = "any"; /* Fix dev_name to "any" for remount permission. */ |
82 |
|
|
if (strcmp(fs->name, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 || |
83 |
|
|
strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
84 |
|
|
strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
85 |
|
|
strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0) dev_name = "any"; |
86 |
kumaneko |
708 |
if (!IsCorrectPath(dev_name, 0, 0, 0, __FUNCTION__) || !IsCorrectPath(dir_name, 1, 0, 1, __FUNCTION__)) return -EINVAL; |
87 |
kumaneko |
111 |
if ((dev = SaveName(dev_name)) == NULL || (dir = SaveName(dir_name)) == NULL) return -ENOMEM; |
88 |
kumaneko |
652 |
mutex_lock(&lock); |
89 |
kumaneko |
722 |
list1_for_each_entry(ptr, &mount_list, list) { |
90 |
kumaneko |
325 |
if (ptr->flags != flags || pathcmp(ptr->dev_name, dev) || pathcmp(ptr->dir_name, dir) || pathcmp(ptr->fs_type, fs)) continue; |
91 |
|
|
error = 0; |
92 |
kumaneko |
111 |
if (is_delete) { |
93 |
|
|
ptr->is_deleted = 1; |
94 |
|
|
goto out; |
95 |
|
|
} else { |
96 |
|
|
if (ptr->is_deleted) { |
97 |
|
|
ptr->is_deleted = 0; |
98 |
kumaneko |
325 |
goto update; |
99 |
kumaneko |
111 |
} |
100 |
kumaneko |
325 |
goto out; /* No changes. */ |
101 |
kumaneko |
111 |
} |
102 |
|
|
} |
103 |
|
|
if (is_delete) { |
104 |
|
|
error = -ENOENT; |
105 |
|
|
goto out; |
106 |
|
|
} |
107 |
kumaneko |
214 |
if ((new_entry = alloc_element(sizeof(*new_entry))) == NULL) goto out; |
108 |
kumaneko |
111 |
new_entry->dev_name = dev; |
109 |
|
|
new_entry->dir_name = dir; |
110 |
|
|
new_entry->fs_type = fs; |
111 |
kumaneko |
325 |
new_entry->flags = flags; |
112 |
kumaneko |
722 |
list1_add_tail_mb(&new_entry->list, &mount_list); |
113 |
kumaneko |
111 |
error = 0; |
114 |
|
|
ptr = new_entry; |
115 |
|
|
update: |
116 |
|
|
{ |
117 |
|
|
struct file_system_type *type = NULL; |
118 |
|
|
if (strcmp(fs->name, MOUNT_REMOUNT_KEYWORD) == 0) { |
119 |
kumaneko |
325 |
printk("%sAllow remount %s with options 0x%lX.\n", ccs_log_level, dir->name, ptr->flags); |
120 |
kumaneko |
111 |
} else if (strcmp(fs->name, MOUNT_BIND_KEYWORD) == 0 || strcmp(fs->name, MOUNT_MOVE_KEYWORD) == 0) { |
121 |
kumaneko |
325 |
printk("%sAllow mount %s %s %s with options 0x%lX\n", ccs_log_level, fs->name, dev->name, dir->name, ptr->flags); |
122 |
kumaneko |
111 |
} else if (strcmp(fs->name, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 || |
123 |
|
|
strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
124 |
|
|
strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
125 |
|
|
strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0) { |
126 |
kumaneko |
325 |
printk("%sAllow mount %s %s with options 0x%lX.\n", ccs_log_level, fs->name, dir->name, ptr->flags); |
127 |
kumaneko |
111 |
} else if ((type = get_fs_type(fs->name)) != NULL && (type->fs_flags & FS_REQUIRES_DEV) != 0) { |
128 |
kumaneko |
325 |
printk("%sAllow mount -t %s %s %s with options 0x%lX.\n", ccs_log_level, fs->name, dev->name, dir->name, ptr->flags); |
129 |
kumaneko |
111 |
} else { |
130 |
kumaneko |
325 |
printk("%sAllow mount %s on %s with options 0x%lX.\n", ccs_log_level, fs->name, dir->name, ptr->flags); |
131 |
kumaneko |
111 |
} |
132 |
|
|
if (type) put_filesystem(type); |
133 |
|
|
} |
134 |
|
|
out: |
135 |
kumaneko |
652 |
mutex_unlock(&lock); |
136 |
kumaneko |
111 |
return error; |
137 |
|
|
} |
138 |
|
|
|
139 |
kumaneko |
448 |
static int CheckMountPermission2(char *dev_name, char *dir_name, char *type, unsigned long flags) |
140 |
kumaneko |
111 |
{ |
141 |
kumaneko |
621 |
const bool is_enforce = CheckCCSEnforce(CCS_SAKURA_RESTRICT_MOUNT); |
142 |
kumaneko |
357 |
int error = -EPERM; |
143 |
kumaneko |
111 |
if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_MOUNT)) return 0; |
144 |
|
|
if (!type) type = "<NULL>"; |
145 |
kumaneko |
325 |
if ((flags & MS_MGC_MSK) == MS_MGC_VAL) flags &= ~MS_MGC_MSK; |
146 |
|
|
switch (flags & (MS_REMOUNT | MS_MOVE | MS_BIND)) { |
147 |
kumaneko |
111 |
case MS_REMOUNT: |
148 |
|
|
case MS_MOVE: |
149 |
|
|
case MS_BIND: |
150 |
|
|
case 0: |
151 |
|
|
break; |
152 |
|
|
default: |
153 |
|
|
printk("SAKURA-ERROR: %s%s%sare given for single mount operation.\n", |
154 |
kumaneko |
357 |
flags & MS_REMOUNT ? "'remount' " : "", |
155 |
|
|
flags & MS_MOVE ? "'move' " : "", |
156 |
|
|
flags & MS_BIND ? "'bind' " : ""); |
157 |
kumaneko |
111 |
return -EINVAL; |
158 |
|
|
} |
159 |
kumaneko |
325 |
switch (flags & (MS_UNBINDABLE | MS_PRIVATE | MS_SLAVE | MS_SHARED)) { |
160 |
kumaneko |
111 |
case MS_UNBINDABLE: |
161 |
|
|
case MS_PRIVATE: |
162 |
|
|
case MS_SLAVE: |
163 |
|
|
case MS_SHARED: |
164 |
|
|
case 0: |
165 |
|
|
break; |
166 |
|
|
default: |
167 |
|
|
printk("SAKURA-ERROR: %s%s%s%sare given for single mount operation.\n", |
168 |
kumaneko |
357 |
flags & MS_UNBINDABLE ? "'unbindable' " : "", |
169 |
|
|
flags & MS_PRIVATE ? "'private' " : "", |
170 |
|
|
flags & MS_SLAVE ? "'slave' " : "", |
171 |
|
|
flags & MS_SHARED ? "'shared' " : ""); |
172 |
kumaneko |
111 |
return -EINVAL; |
173 |
|
|
} |
174 |
kumaneko |
325 |
if (flags & MS_REMOUNT) { |
175 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_REMOUNT_KEYWORD, flags & ~MS_REMOUNT); |
176 |
kumaneko |
325 |
} else if (flags & MS_MOVE) { |
177 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_MOVE_KEYWORD, flags & ~MS_MOVE); |
178 |
kumaneko |
325 |
} else if (flags & MS_BIND) { |
179 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_BIND_KEYWORD, flags & ~MS_BIND); |
180 |
kumaneko |
325 |
} else if (flags & MS_UNBINDABLE) { |
181 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_MAKE_UNBINDABLE_KEYWORD, flags & ~MS_UNBINDABLE); |
182 |
kumaneko |
325 |
} else if (flags & MS_PRIVATE) { |
183 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_MAKE_PRIVATE_KEYWORD, flags & ~MS_PRIVATE); |
184 |
kumaneko |
325 |
} else if (flags & MS_SLAVE) { |
185 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_MAKE_SLAVE_KEYWORD, flags & ~MS_SLAVE); |
186 |
kumaneko |
325 |
} else if (flags & MS_SHARED) { |
187 |
kumaneko |
448 |
error = CheckMountPermission2(dev_name, dir_name, MOUNT_MAKE_SHARED_KEYWORD, flags & ~MS_SHARED); |
188 |
kumaneko |
111 |
} else { |
189 |
kumaneko |
214 |
struct mount_entry *ptr; |
190 |
kumaneko |
111 |
struct file_system_type *fstype = NULL; |
191 |
|
|
const char *requested_dir_name = NULL; |
192 |
|
|
const char *requested_dev_name = NULL; |
193 |
|
|
struct path_info rdev, rdir; |
194 |
|
|
int need_dev = 0; |
195 |
|
|
|
196 |
kumaneko |
357 |
if ((requested_dir_name = realpath(dir_name)) == NULL) { |
197 |
|
|
error = -ENOENT; |
198 |
|
|
goto cleanup; |
199 |
|
|
} |
200 |
kumaneko |
111 |
rdir.name = requested_dir_name; |
201 |
|
|
fill_path_info(&rdir); |
202 |
kumaneko |
357 |
|
203 |
kumaneko |
111 |
/* Compare fs name. */ |
204 |
|
|
if (strcmp(type, MOUNT_REMOUNT_KEYWORD) == 0) { |
205 |
|
|
/* Needn't to resolve dev_name */ |
206 |
|
|
} else if (strcmp(type, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 || |
207 |
kumaneko |
357 |
strcmp(type, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
208 |
|
|
strcmp(type, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
209 |
|
|
strcmp(type, MOUNT_MAKE_SHARED_KEYWORD) == 0) { |
210 |
kumaneko |
111 |
/* Needn't to resolve dev_name */ |
211 |
|
|
} else if (strcmp(type, MOUNT_BIND_KEYWORD) == 0 || strcmp(type, MOUNT_MOVE_KEYWORD) == 0) { |
212 |
kumaneko |
357 |
if ((requested_dev_name = realpath(dev_name)) == NULL) { |
213 |
|
|
error = -ENOENT; |
214 |
|
|
goto cleanup; |
215 |
|
|
} |
216 |
kumaneko |
111 |
rdev.name = requested_dev_name; |
217 |
|
|
fill_path_info(&rdev); |
218 |
kumaneko |
357 |
need_dev = -1; /* dev_name is a directory */ |
219 |
kumaneko |
111 |
} else if ((fstype = get_fs_type(type)) != NULL) { |
220 |
|
|
if (fstype->fs_flags & FS_REQUIRES_DEV) { |
221 |
kumaneko |
357 |
if ((requested_dev_name = realpath(dev_name)) == NULL) { |
222 |
|
|
error = -ENOENT; |
223 |
|
|
goto cleanup; |
224 |
|
|
} |
225 |
kumaneko |
111 |
rdev.name = requested_dev_name; |
226 |
|
|
fill_path_info(&rdev); |
227 |
kumaneko |
357 |
need_dev = 1; /* dev_name is a block device file */ |
228 |
kumaneko |
111 |
} |
229 |
|
|
} else { |
230 |
kumaneko |
357 |
error = -ENODEV; |
231 |
kumaneko |
111 |
goto cleanup; |
232 |
|
|
} |
233 |
kumaneko |
722 |
list1_for_each_entry(ptr, &mount_list, list) { |
234 |
kumaneko |
111 |
if (ptr->is_deleted) continue; |
235 |
|
|
|
236 |
kumaneko |
325 |
/* Compare options */ |
237 |
|
|
if (ptr->flags != flags) continue; |
238 |
kumaneko |
357 |
|
239 |
kumaneko |
111 |
/* Compare fs name. */ |
240 |
|
|
if (strcmp(type, ptr->fs_type->name)) continue; |
241 |
|
|
|
242 |
|
|
/* Compare mount point. */ |
243 |
|
|
if (PathMatchesToPattern(&rdir, ptr->dir_name) == 0) continue; |
244 |
|
|
|
245 |
|
|
/* Compare device name. */ |
246 |
|
|
if (requested_dev_name && PathMatchesToPattern(&rdev, ptr->dev_name) == 0) continue; |
247 |
|
|
|
248 |
|
|
/* OK. */ |
249 |
kumaneko |
357 |
error = 0; |
250 |
|
|
|
251 |
kumaneko |
111 |
if (need_dev > 0) { |
252 |
kumaneko |
325 |
printk(KERN_DEBUG "SAKURA-NOTICE: 'mount -t %s %s %s 0x%lX' accepted.\n", type, requested_dev_name, requested_dir_name, flags); |
253 |
kumaneko |
111 |
} else if (need_dev < 0) { |
254 |
kumaneko |
325 |
printk(KERN_DEBUG "SAKURA-NOTICE: 'mount %s %s %s 0x%lX' accepted.\n", type, requested_dev_name, requested_dir_name, flags); |
255 |
kumaneko |
111 |
} else if (strcmp(type, MOUNT_REMOUNT_KEYWORD) == 0) { |
256 |
kumaneko |
325 |
printk(KERN_DEBUG "SAKURA-NOTICE: 'mount -o remount %s 0x%lX' accepted.\n", requested_dir_name, flags); |
257 |
kumaneko |
111 |
} else if (strcmp(type, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 || |
258 |
kumaneko |
357 |
strcmp(type, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
259 |
|
|
strcmp(type, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
260 |
|
|
strcmp(type, MOUNT_MAKE_SHARED_KEYWORD) == 0) { |
261 |
kumaneko |
325 |
printk(KERN_DEBUG "SAKURA-NOTICE: 'mount %s %s 0x%lX' accepted.\n", type, requested_dir_name, flags); |
262 |
kumaneko |
111 |
} else { |
263 |
kumaneko |
325 |
printk(KERN_DEBUG "SAKURA-NOTICE: 'mount %s on %s 0x%lX' accepted.\n", type, requested_dir_name, flags); |
264 |
kumaneko |
111 |
} |
265 |
|
|
break; |
266 |
|
|
} |
267 |
kumaneko |
357 |
if (error) { |
268 |
|
|
const char *realname1 = realpath(dev_name), *realname2 = realpath(dir_name), *exename = GetEXE(); |
269 |
|
|
if (strcmp(type, MOUNT_REMOUNT_KEYWORD) == 0) { |
270 |
|
|
printk("SAKURA-%s: mount -o remount %s 0x%lX (pid=%d:exe=%s): Permission denied.\n", GetMSG(is_enforce), realname2 ? realname2 : dir_name, flags, current->pid, exename); |
271 |
|
|
if (is_enforce && CheckSupervisor("# %s is requesting\nmount -o remount %s 0x%lX\n", exename, realname2 ? realname2 : dir_name, flags) == 0) error = 0; |
272 |
|
|
} else if (strcmp(type, MOUNT_BIND_KEYWORD) == 0 || strcmp(type, MOUNT_MOVE_KEYWORD) == 0) { |
273 |
|
|
printk("SAKURA-%s: mount %s %s %s 0x%lX (pid=%d:exe=%s): Permission denied.\n", GetMSG(is_enforce), type, realname1 ? realname1 : dev_name, realname2 ? realname2 : dir_name, flags, current->pid, exename); |
274 |
|
|
if (is_enforce && CheckSupervisor("# %s is requesting\nmount %s %s %s 0x%lX\n", exename, type, realname1 ? realname1 : dev_name, realname2 ? realname2 : dir_name, flags) == 0) error = 0; |
275 |
|
|
} else if (strcmp(type, MOUNT_MAKE_UNBINDABLE_KEYWORD) == 0 || |
276 |
|
|
strcmp(type, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
277 |
|
|
strcmp(type, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
278 |
|
|
strcmp(type, MOUNT_MAKE_SHARED_KEYWORD) == 0) { |
279 |
|
|
printk("SAKURA-%s: mount %s %s 0x%lX (pid=%d:exe=%s): Permission denied.\n", GetMSG(is_enforce), type, realname2 ? realname2 : dir_name, flags, current->pid, exename); |
280 |
|
|
if (is_enforce && CheckSupervisor("# %s is requesting\nmount %s %s 0x%lX", exename, type, realname2 ? realname2 : dir_name, flags) == 0) error = 0; |
281 |
|
|
} else { |
282 |
|
|
printk("SAKURA-%s: mount -t %s %s %s 0x%lX (pid=%d:exe=%s): Permission denied.\n", GetMSG(is_enforce), type, realname1 ? realname1 : dev_name, realname2 ? realname2 : dir_name, flags, current->pid, exename); |
283 |
|
|
if (is_enforce && CheckSupervisor("# %s is requesting\nmount -t %s %s %s 0x%lX\n", exename, type, realname1 ? realname1 : dev_name, realname2 ? realname2 : dir_name, flags) == 0) error = 0; |
284 |
|
|
} |
285 |
|
|
ccs_free(exename); |
286 |
|
|
ccs_free(realname2); |
287 |
|
|
ccs_free(realname1); |
288 |
|
|
} |
289 |
kumaneko |
512 |
if (error && !is_enforce && CheckCCSAccept(CCS_SAKURA_RESTRICT_MOUNT, NULL)) { |
290 |
kumaneko |
325 |
AddMountACL(need_dev ? requested_dev_name : dev_name, requested_dir_name, type, flags, 0); |
291 |
kumaneko |
111 |
UpdateCounter(CCS_UPDATES_COUNTER_SYSTEM_POLICY); |
292 |
|
|
} |
293 |
|
|
cleanup: |
294 |
kumaneko |
357 |
ccs_free(requested_dev_name); |
295 |
|
|
ccs_free(requested_dir_name); |
296 |
kumaneko |
111 |
if (fstype) put_filesystem(fstype); |
297 |
|
|
} |
298 |
kumaneko |
357 |
if (!is_enforce) error = 0; |
299 |
|
|
return error; |
300 |
kumaneko |
111 |
} |
301 |
kumaneko |
448 |
|
302 |
|
|
/* This is a wrapper to allow use of 1.4.x patch for 1.5.x . */ |
303 |
|
|
int CheckMountPermission(char *dev_name, char *dir_name, char *type, const unsigned long *flags) |
304 |
|
|
{ |
305 |
|
|
return CheckMountPermission2(dev_name, dir_name, type, *flags); |
306 |
|
|
} |
307 |
kumaneko |
223 |
EXPORT_SYMBOL(CheckMountPermission); |
308 |
kumaneko |
111 |
|
309 |
kumaneko |
621 |
int AddMountPolicy(char *data, const bool is_delete) |
310 |
kumaneko |
111 |
{ |
311 |
|
|
char *cp, *cp2; |
312 |
|
|
const char *fs, *dev, *dir; |
313 |
kumaneko |
325 |
unsigned long flags = 0; |
314 |
kumaneko |
111 |
cp2 = data; if ((cp = strchr(cp2, ' ')) == NULL) return -EINVAL; *cp = '\0'; dev = cp2; |
315 |
|
|
cp2 = cp + 1; if ((cp = strchr(cp2, ' ')) == NULL) return -EINVAL; *cp = '\0'; dir = cp2; |
316 |
kumaneko |
325 |
cp2 = cp + 1; if ((cp = strchr(cp2, ' ')) == NULL) return -EINVAL; *cp = '\0'; fs = cp2; |
317 |
|
|
flags = simple_strtoul(cp + 1, NULL, 0); |
318 |
|
|
return AddMountACL(dev, dir, fs, flags, is_delete); |
319 |
kumaneko |
111 |
} |
320 |
|
|
|
321 |
kumaneko |
214 |
int ReadMountPolicy(struct io_buffer *head) |
322 |
kumaneko |
111 |
{ |
323 |
kumaneko |
722 |
struct list1_head *pos; |
324 |
|
|
list1_for_each_cookie(pos, head->read_var2, &mount_list) { |
325 |
kumaneko |
708 |
struct mount_entry *ptr; |
326 |
kumaneko |
722 |
ptr = list1_entry(pos, struct mount_entry, list); |
327 |
kumaneko |
708 |
if (ptr->is_deleted) continue; |
328 |
|
|
if (io_printf(head, KEYWORD_ALLOW_MOUNT "%s %s %s 0x%lX\n", ptr->dev_name->name, ptr->dir_name->name, ptr->fs_type->name, ptr->flags)) return -ENOMEM; |
329 |
kumaneko |
111 |
} |
330 |
kumaneko |
708 |
return 0; |
331 |
kumaneko |
111 |
} |
332 |
|
|
|
333 |
|
|
/***** SAKURA Linux end. *****/ |