5 |
* |
* |
6 |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
* Copyright (C) 2005-2007 NTT DATA CORPORATION |
7 |
* |
* |
8 |
* Version: 1.5.0 2007/09/20 |
* Version: 1.5.3-pre 2007/12/18 |
9 |
* |
* |
10 |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
* This file is applicable to both 2.4.30 and 2.6.11 and later. |
11 |
* See README.ccs for ChangeLog. |
* See README.ccs for ChangeLog. |
51 |
/***** The structure for mount restrictions. *****/ |
/***** The structure for mount restrictions. *****/ |
52 |
|
|
53 |
struct mount_entry { |
struct mount_entry { |
54 |
struct mount_entry *next; |
struct list1_head list; |
55 |
const struct path_info *dev_name; |
const struct path_info *dev_name; |
56 |
const struct path_info *dir_name; |
const struct path_info *dir_name; |
57 |
const struct path_info *fs_type; |
const struct path_info *fs_type; |
58 |
unsigned long flags; |
unsigned long flags; |
59 |
u8 is_deleted; |
bool is_deleted; |
60 |
}; |
}; |
61 |
|
|
62 |
/************************* MOUNT RESTRICTION HANDLER *************************/ |
/************************* MOUNT RESTRICTION HANDLER *************************/ |
63 |
|
|
64 |
|
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,24) |
65 |
static void put_filesystem(struct file_system_type *fs) |
static void put_filesystem(struct file_system_type *fs) |
66 |
{ |
{ |
67 |
module_put(fs->owner); |
module_put(fs->owner); |
68 |
} |
} |
69 |
|
#endif |
70 |
|
|
71 |
static struct mount_entry *mount_list = NULL; |
static LIST1_HEAD(mount_list); |
72 |
|
|
73 |
static int AddMountACL(const char *dev_name, const char *dir_name, const char *fs_type, const unsigned long flags, const u8 is_delete) |
static int AddMountACL(const char *dev_name, const char *dir_name, const char *fs_type, const unsigned long flags, const bool is_delete) |
74 |
{ |
{ |
75 |
struct mount_entry *new_entry, *ptr; |
struct mount_entry *new_entry, *ptr; |
76 |
const struct path_info *fs, *dev, *dir; |
const struct path_info *fs, *dev, *dir; |
77 |
static DECLARE_MUTEX(lock); |
static DEFINE_MUTEX(lock); |
78 |
int error = -ENOMEM; |
int error = -ENOMEM; |
79 |
if ((fs = SaveName(fs_type)) == NULL) return -EINVAL; |
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. */ |
if (!dev_name) dev_name = "<NULL>"; /* Map dev_name to "<NULL>" for if no dev_name given. */ |
83 |
strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
strcmp(fs->name, MOUNT_MAKE_PRIVATE_KEYWORD) == 0 || |
84 |
strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
strcmp(fs->name, MOUNT_MAKE_SLAVE_KEYWORD) == 0 || |
85 |
strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0) dev_name = "any"; |
strcmp(fs->name, MOUNT_MAKE_SHARED_KEYWORD) == 0) dev_name = "any"; |
86 |
if (!IsCorrectPath(dev_name, 0, 0, 0, __FUNCTION__) || !IsCorrectPath(dir_name, 1, 0, 1, __FUNCTION__)) return -EINVAL; |
if (!IsCorrectPath(dev_name, 0, 0, 0, __FUNCTION__) || !IsCorrectPath(dir_name, 0, 0, 0, __FUNCTION__)) return -EINVAL; |
87 |
if ((dev = SaveName(dev_name)) == NULL || (dir = SaveName(dir_name)) == NULL) return -ENOMEM; |
if ((dev = SaveName(dev_name)) == NULL || (dir = SaveName(dir_name)) == NULL) return -ENOMEM; |
88 |
down(&lock); |
mutex_lock(&lock); |
89 |
for (ptr = mount_list; ptr; ptr = ptr->next) { |
list1_for_each_entry(ptr, &mount_list, list) { |
90 |
if (ptr->flags != flags || pathcmp(ptr->dev_name, dev) || pathcmp(ptr->dir_name, dir) || pathcmp(ptr->fs_type, fs)) continue; |
if (ptr->flags != flags || pathcmp(ptr->dev_name, dev) || pathcmp(ptr->dir_name, dir) || pathcmp(ptr->fs_type, fs)) continue; |
91 |
error = 0; |
error = 0; |
92 |
if (is_delete) { |
if (is_delete) { |
109 |
new_entry->dir_name = dir; |
new_entry->dir_name = dir; |
110 |
new_entry->fs_type = fs; |
new_entry->fs_type = fs; |
111 |
new_entry->flags = flags; |
new_entry->flags = flags; |
112 |
mb(); /* Instead of using spinlock. */ |
list1_add_tail_mb(&new_entry->list, &mount_list); |
|
if ((ptr = mount_list) != NULL) { |
|
|
while (ptr->next) ptr = ptr->next; ptr->next = new_entry; |
|
|
} else { |
|
|
mount_list = new_entry; |
|
|
} |
|
113 |
error = 0; |
error = 0; |
114 |
ptr = new_entry; |
ptr = new_entry; |
115 |
update: |
update: |
132 |
if (type) put_filesystem(type); |
if (type) put_filesystem(type); |
133 |
} |
} |
134 |
out: |
out: |
135 |
up(&lock); |
mutex_unlock(&lock); |
136 |
return error; |
return error; |
137 |
} |
} |
138 |
|
|
139 |
static int CheckMountPermission2(char *dev_name, char *dir_name, char *type, unsigned long flags) |
static int CheckMountPermission2(char *dev_name, char *dir_name, char *type, unsigned long flags) |
140 |
{ |
{ |
141 |
const u8 is_enforce = CheckCCSEnforce(CCS_SAKURA_RESTRICT_MOUNT); |
const bool is_enforce = CheckCCSEnforce(CCS_SAKURA_RESTRICT_MOUNT); |
142 |
int error = -EPERM; |
int error = -EPERM; |
143 |
if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_MOUNT)) return 0; |
if (!CheckCCSFlags(CCS_SAKURA_RESTRICT_MOUNT)) return 0; |
144 |
if (!type) type = "<NULL>"; |
if (!type) type = "<NULL>"; |
230 |
error = -ENODEV; |
error = -ENODEV; |
231 |
goto cleanup; |
goto cleanup; |
232 |
} |
} |
233 |
for (ptr = mount_list; ptr; ptr = ptr->next) { |
list1_for_each_entry(ptr, &mount_list, list) { |
234 |
if (ptr->is_deleted) continue; |
if (ptr->is_deleted) continue; |
235 |
|
|
236 |
/* Compare options */ |
/* Compare options */ |
304 |
{ |
{ |
305 |
return CheckMountPermission2(dev_name, dir_name, type, *flags); |
return CheckMountPermission2(dev_name, dir_name, type, *flags); |
306 |
} |
} |
|
EXPORT_SYMBOL(CheckMountPermission); |
|
307 |
|
|
308 |
int AddMountPolicy(char *data, const u8 is_delete) |
int AddMountPolicy(char *data, const bool is_delete) |
309 |
{ |
{ |
310 |
char *cp, *cp2; |
char *cp, *cp2; |
311 |
const char *fs, *dev, *dir; |
const char *fs, *dev, *dir; |
319 |
|
|
320 |
int ReadMountPolicy(struct io_buffer *head) |
int ReadMountPolicy(struct io_buffer *head) |
321 |
{ |
{ |
322 |
struct mount_entry *ptr = head->read_var2; |
struct list1_head *pos; |
323 |
if (!ptr) ptr = mount_list; |
list1_for_each_cookie(pos, head->read_var2, &mount_list) { |
324 |
while (ptr) { |
struct mount_entry *ptr; |
325 |
head->read_var2 = ptr; |
ptr = list1_entry(pos, struct mount_entry, list); |
326 |
if (ptr->is_deleted == 0 && 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)) break; |
if (ptr->is_deleted) continue; |
327 |
ptr = ptr->next; |
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; |
328 |
} |
} |
329 |
return ptr ? -ENOMEM : 0; |
return 0; |
330 |
} |
} |
331 |
|
|
332 |
/***** SAKURA Linux end. *****/ |
/***** SAKURA Linux end. *****/ |