Revert "ANDROID: dm verity: add minimum prefetch size"
[GitHub/exynos8895/android_kernel_samsung_universal8895.git] / fs / sdcardfs_v60000 / packagelist.c
CommitLineData
1cac41cb
MB
1/*
2 * fs/sdcardfs/packagelist.c
3 *
4 * Copyright (c) 2013 Samsung Electronics Co. Ltd
5 * Authors: Daeho Jeong, Woojoong Lee, Seunghwan Hyun,
6 * Sunghwan Yun, Sungjong Seo
7 *
8 * This program has been developed as a stackable file system based on
9 * the WrapFS which written by
10 *
11 * Copyright (c) 1998-2011 Erez Zadok
12 * Copyright (c) 2009 Shrikar Archak
13 * Copyright (c) 2003-2011 Stony Brook University
14 * Copyright (c) 2003-2011 The Research Foundation of SUNY
15 *
16 * This file is dual licensed. It may be redistributed and/or modified
17 * under the terms of the Apache 2.0 License OR version 2 of the GNU
18 * General Public License.
19 */
20
21#include "sdcardfs.h"
22#include <linux/syscalls.h>
23#include <linux/kthread.h>
24#include <linux/inotify.h>
25#include <linux/delay.h>
26
27struct hashtable_entry {
28 struct hlist_node hlist;
29 void *key;
30 unsigned int value;
31};
32
33static struct kmem_cache *hashtable_entry_cachep;
34
35/* Path to system-provided mapping of package name to appIds */
36static const char *const kpackageslist_file = "/data/system/packages.list";
37/* Supplementary groups to execute with */
38static const gid_t kgroups[1] = { AID_PACKAGE_INFO };
39
40static unsigned int str_hash(void *key)
41{
42 int i;
43 unsigned int h = strlen(key);
44 char *data = (char *)key;
45
46 for (i = 0; i < strlen(key); i++) {
47 h = h * 31 + *data;
48 data++;
49 }
50 return h;
51}
52
53appid_t get_appid(void *pkgl_id, const char *app_name)
54{
55 struct packagelist_data *pkgl_dat = (struct packagelist_data *)pkgl_id;
56 struct hashtable_entry *hash_cur;
57 unsigned int hash = str_hash((void *)app_name);
58 appid_t ret_id;
59
60 //printk(KERN_INFO "sdcardfs: %s: %s, %u\n", __func__, (char *)app_name, hash);
61 mutex_lock(&pkgl_dat->hashtable_lock);
62 hash_for_each_possible(pkgl_dat->package_to_appid, hash_cur, hlist, hash) {
63 //printk(KERN_INFO "sdcardfs: %s: %s\n", __func__, (char *)hash_cur->key);
64 if (!strcasecmp(app_name, hash_cur->key)) {
65 ret_id = (appid_t)hash_cur->value;
66 mutex_unlock(&pkgl_dat->hashtable_lock);
67 //printk(KERN_INFO "=> app_id: %d\n", (int)ret_id);
68 return ret_id;
69 }
70 }
71 mutex_unlock(&pkgl_dat->hashtable_lock);
72 //printk(KERN_INFO "=> app_id: %d\n", 0);
73 return 0;
74}
75
76/* Kernel has already enforced everything we returned through
77 * derive_permissions_locked(), so this is used to lock down access
78 * even further, such as enforcing that apps hold sdcard_rw. */
79int check_caller_access_to_name(struct inode *parent_node, const char *name)
80{
81 /* Always block security-sensitive files at root */
82 if (parent_node && SDCARDFS_I(parent_node)->perm == PERM_ROOT) {
83 if (!strcasecmp(name, "autorun.inf")
84 || !strcasecmp(name, ".android_secure")
85 || !strcasecmp(name, "android_secure")) {
86 return 0;
87 }
88 }
89
90 /* Root always has access; access for any other UIDs should always
91 * be controlled through packages.list. */
92 if (uid_eq(current_fsuid(), make_kuid(current_user_ns(), 0))) {
93 return 1;
94 }
95
96 /* No extra permissions to enforce */
97 return 1;
98}
99
100/* This function is used when file opening. The open flags must be
101 * checked before calling check_caller_access_to_name() */
102int open_flags_to_access_mode(int open_flags)
103{
104 if ((open_flags & O_ACCMODE) == O_RDONLY) {
105 return 0; /* R_OK */
106 } else if ((open_flags & O_ACCMODE) == O_WRONLY) {
107 return 1; /* W_OK */
108 } else {
109 /* Probably O_RDRW, but treat as default to be safe */
110 return 1; /* R_OK | W_OK */
111 }
112}
113
114static int insert_str_to_int(struct packagelist_data *pkgl_dat, void *key, int value)
115{
116 struct hashtable_entry *hash_cur;
117 struct hashtable_entry *new_entry;
118 unsigned int hash = str_hash(key);
119
120 //printk(KERN_INFO "sdcardfs: %s: %s: %d, %u\n", __func__, (char *)key, value, hash);
121 hash_for_each_possible(pkgl_dat->package_to_appid, hash_cur, hlist, hash) {
122 if (!strcasecmp(key, hash_cur->key)) {
123 hash_cur->value = value;
124 return 0;
125 }
126 }
127 new_entry = kmem_cache_alloc(hashtable_entry_cachep, GFP_KERNEL);
128 if (!new_entry)
129 return -ENOMEM;
130 new_entry->key = kstrdup(key, GFP_KERNEL);
131 new_entry->value = value;
132 hash_add(pkgl_dat->package_to_appid, &new_entry->hlist, hash);
133 return 0;
134}
135
136static void remove_str_to_int(struct hashtable_entry *h_entry)
137{
138 //printk(KERN_INFO "sdcardfs: %s: %s: %d\n", __func__, (char *)h_entry->key, h_entry->value);
139 kfree(h_entry->key);
140 kmem_cache_free(hashtable_entry_cachep, h_entry);
141}
142
143/*static void remove_int_to_null(struct hashtable_entry *h_entry) {
144 //printk(KERN_INFO "sdcardfs: %s: %d: %d\n", __func__, (int)h_entry->key, h_entry->value);
145 kmem_cache_free(hashtable_entry_cachep, h_entry);
146}*/
147
148static void remove_all_hashentrys(struct packagelist_data *pkgl_dat)
149{
150 struct hashtable_entry *hash_cur;
151 struct hlist_node *h_t;
152 int i;
153
154 hash_for_each_safe(pkgl_dat->package_to_appid, i, h_t, hash_cur, hlist)
155 remove_str_to_int(hash_cur);
156
157 hash_init(pkgl_dat->package_to_appid);
158}
159
160static int read_package_list(struct packagelist_data *pkgl_dat)
161{
162 int ret;
163 int fd;
164 int read_amount;
165
166 printk(KERN_INFO "sdcardfs: read_package_list\n");
167
168 mutex_lock(&pkgl_dat->hashtable_lock);
169
170 remove_all_hashentrys(pkgl_dat);
171
172 fd = sys_open(kpackageslist_file, O_RDONLY, 0);
173 if (fd < 0) {
174 printk(KERN_ERR "sdcardfs: failed to open package list\n");
175 mutex_unlock(&pkgl_dat->hashtable_lock);
176 return fd;
177 }
178
179 while ((read_amount = sys_read(fd, pkgl_dat->read_buf,
180 sizeof(pkgl_dat->read_buf))) > 0) {
181 int appid;
182 int one_line_len = 0;
183 int additional_read;
184
185 while (one_line_len < read_amount) {
186 if (pkgl_dat->read_buf[one_line_len] == '\n') {
187 one_line_len++;
188 break;
189 }
190 one_line_len++;
191 }
192 additional_read = read_amount - one_line_len;
193 if (additional_read > 0)
194 sys_lseek(fd, -additional_read, SEEK_CUR);
195
196 if (sscanf(pkgl_dat->read_buf, "%s %d %*d %*s %*s %s",
197 pkgl_dat->app_name_buf, &appid,
198 pkgl_dat->gids_buf) == 3) {
199 ret = insert_str_to_int(pkgl_dat, pkgl_dat->app_name_buf, appid);
200 if (ret) {
201 sys_close(fd);
202 mutex_unlock(&pkgl_dat->hashtable_lock);
203 return ret;
204 }
205 }
206 }
207
208 sys_close(fd);
209 mutex_unlock(&pkgl_dat->hashtable_lock);
210 return 0;
211}
212
213static int packagelist_reader(void *thread_data)
214{
215 struct packagelist_data *pkgl_dat = (struct packagelist_data *)thread_data;
216 struct inotify_event *event;
217 bool active = false;
218 int event_pos;
219 int event_size;
220 int res = 0;
221 int nfd;
222
223 allow_signal(SIGINT);
224
225 nfd = sys_inotify_init();
226 if (nfd < 0) {
227 printk(KERN_ERR "sdcardfs: inotify_init failed: %d\n", nfd);
228 return nfd;
229 }
230
231 while (!kthread_should_stop()) {
232 if (signal_pending(current)) {
233 msleep(100);
234 continue;
235 }
236
237 if (!active) {
238 res = sys_inotify_add_watch(nfd, kpackageslist_file, IN_DELETE_SELF);
239 if (res < 0) {
240 if (res == -ENOENT || res == -EACCES) {
241 /* Framework may not have created yet, sleep and retry */
242 printk(KERN_ERR "sdcardfs: missing packages.list; retrying\n");
243 ssleep(2);
244 printk(KERN_ERR "sdcardfs: missing packages.list_end; retrying\n");
245 continue;
246 } else {
247 printk(KERN_ERR "sdcardfs: inotify_add_watch failed: %d\n", res);
248 goto interruptable_sleep;
249 }
250 }
251 /* Watch above will tell us about any future changes, so
252 * read the current state. */
253 res = read_package_list(pkgl_dat);
254 if (res) {
255 printk(KERN_ERR "sdcardfs: read_package_list failed: %d\n", res);
256 goto interruptable_sleep;
257 }
258 active = true;
259 atomic_set(&pkgl_dat->newly_created, 1);
260 }
261
262 event_pos = 0;
263 res = sys_read(nfd, pkgl_dat->event_buf, sizeof(pkgl_dat->event_buf));
264 if (res < (int) sizeof(*event)) {
265 if (res == -EINTR)
266 continue;
267 printk(KERN_ERR "sdcardfs: failed to read inotify event: %d\n", res);
268 goto interruptable_sleep;
269 }
270
271 while (res >= (int) sizeof(*event)) {
272 event = (struct inotify_event *) (pkgl_dat->event_buf + event_pos);
273
274 printk(KERN_INFO "sdcardfs: inotify event: %08x\n", event->mask);
275 if ((event->mask & IN_IGNORED) == IN_IGNORED) {
276 /* Previously watched file was deleted, probably due to move
277 * that swapped in new data; re-arm the watch and read. */
278 active = false;
279 }
280
281 event_size = sizeof(*event) + event->len;
282 res -= event_size;
283 event_pos += event_size;
284 }
285 continue;
286
287interruptable_sleep:
288 set_current_state(TASK_INTERRUPTIBLE);
289 schedule();
290 }
291 flush_signals(current);
292 sys_close(nfd);
293 return res;
294}
295
296void *packagelist_create(void)
297{
298 struct packagelist_data *pkgl_dat;
299 struct task_struct *packagelist_thread;
300
301 pkgl_dat = kmalloc(sizeof(*pkgl_dat), GFP_KERNEL | __GFP_ZERO);
302 if (!pkgl_dat) {
303 printk(KERN_ERR "sdcardfs: creating kthread failed\n");
304 return ERR_PTR(-ENOMEM);
305 }
306
307 mutex_init(&pkgl_dat->hashtable_lock);
308 hash_init(pkgl_dat->package_to_appid);
309
310 packagelist_thread = kthread_run(packagelist_reader, (void *)pkgl_dat, "pkgld");
311 if (IS_ERR(packagelist_thread)) {
312 printk(KERN_ERR "sdcardfs: creating kthread failed\n");
313 kfree(pkgl_dat);
314 return packagelist_thread;
315 }
316 pkgl_dat->thread_id = packagelist_thread;
317
318 printk(KERN_INFO "sdcardfs: created packagelist pkgld/%d\n",
319 (int)pkgl_dat->thread_id->pid);
320
321 return (void *)pkgl_dat;
322}
323
324void packagelist_destroy(void *pkgl_id)
325{
326 struct packagelist_data *pkgl_dat = (struct packagelist_data *)pkgl_id;
327 pid_t pkgl_pid = pkgl_dat->thread_id->pid;
328
329 force_sig_info(SIGINT, SEND_SIG_PRIV, pkgl_dat->thread_id);
330 kthread_stop(pkgl_dat->thread_id);
331 remove_all_hashentrys(pkgl_dat);
332 printk(KERN_INFO "sdcardfs: destroyed packagelist pkgld/%d\n", (int)pkgl_pid);
333 kfree(pkgl_dat);
334}
335
336int packagelist_init(void)
337{
338 hashtable_entry_cachep =
339 kmem_cache_create("packagelist_hashtable_entry",
340 sizeof(struct hashtable_entry), 0, 0, NULL);
341 if (!hashtable_entry_cachep) {
342 printk(KERN_ERR "sdcardfs: failed creating pkgl_hashtable entry slab cache\n");
343 return -ENOMEM;
344 }
345
346 return 0;
347}
348
349void packagelist_exit(void)
350{
351 if (hashtable_entry_cachep)
352 kmem_cache_destroy(hashtable_entry_cachep);
353}