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/hashtable.h>
23 #include <linux/ctype.h>
24 #include <linux/delay.h>
25 #include <linux/radix-tree.h>
26 #include <linux/dcache.h>
27
28 #include <linux/init.h>
29 #include <linux/module.h>
30 #include <linux/slab.h>
31
32 #include <linux/configfs.h>
33
34 struct hashtable_entry {
35 struct hlist_node hlist;
36 struct hlist_node dlist; /* for deletion cleanup */
37 struct qstr key;
38 atomic_t value;
39 };
40
41 static DEFINE_HASHTABLE(package_to_appid, 8);
42 static DEFINE_HASHTABLE(package_to_userid, 8);
43 static DEFINE_HASHTABLE(ext_to_groupid, 8);
44
45
46 static struct kmem_cache *hashtable_entry_cachep;
47
full_name_case_hash(const unsigned char * name,unsigned int len)48 static unsigned int full_name_case_hash(const unsigned char *name, unsigned int len)
49 {
50 unsigned long hash = init_name_hash();
51
52 while (len--)
53 hash = partial_name_hash(tolower(*name++), hash);
54 return end_name_hash(hash);
55 }
56
qstr_init(struct qstr * q,const char * name)57 static inline void qstr_init(struct qstr *q, const char *name)
58 {
59 q->name = name;
60 q->len = strlen(q->name);
61 q->hash = full_name_case_hash(q->name, q->len);
62 }
63
qstr_copy(const struct qstr * src,struct qstr * dest)64 static inline int qstr_copy(const struct qstr *src, struct qstr *dest)
65 {
66 dest->name = kstrdup(src->name, GFP_KERNEL);
67 dest->hash_len = src->hash_len;
68 return !!dest->name;
69 }
70
71
__get_appid(const struct qstr * key)72 static appid_t __get_appid(const struct qstr *key)
73 {
74 struct hashtable_entry *hash_cur;
75 unsigned int hash = key->hash;
76 appid_t ret_id;
77
78 rcu_read_lock();
79 hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
80 if (qstr_case_eq(key, &hash_cur->key)) {
81 ret_id = atomic_read(&hash_cur->value);
82 rcu_read_unlock();
83 return ret_id;
84 }
85 }
86 rcu_read_unlock();
87 return 0;
88 }
89
get_appid(const char * key)90 appid_t get_appid(const char *key)
91 {
92 struct qstr q;
93
94 qstr_init(&q, key);
95 return __get_appid(&q);
96 }
97
__get_ext_gid(const struct qstr * key)98 static appid_t __get_ext_gid(const struct qstr *key)
99 {
100 struct hashtable_entry *hash_cur;
101 unsigned int hash = key->hash;
102 appid_t ret_id;
103
104 rcu_read_lock();
105 hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
106 if (qstr_case_eq(key, &hash_cur->key)) {
107 ret_id = atomic_read(&hash_cur->value);
108 rcu_read_unlock();
109 return ret_id;
110 }
111 }
112 rcu_read_unlock();
113 return 0;
114 }
115
get_ext_gid(const char * key)116 appid_t get_ext_gid(const char *key)
117 {
118 struct qstr q;
119
120 qstr_init(&q, key);
121 return __get_ext_gid(&q);
122 }
123
__is_excluded(const struct qstr * app_name,userid_t user)124 static appid_t __is_excluded(const struct qstr *app_name, userid_t user)
125 {
126 struct hashtable_entry *hash_cur;
127 unsigned int hash = app_name->hash;
128
129 rcu_read_lock();
130 hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
131 if (atomic_read(&hash_cur->value) == user &&
132 qstr_case_eq(app_name, &hash_cur->key)) {
133 rcu_read_unlock();
134 return 1;
135 }
136 }
137 rcu_read_unlock();
138 return 0;
139 }
140
is_excluded(const char * key,userid_t user)141 appid_t is_excluded(const char *key, userid_t user)
142 {
143 struct qstr q;
144
145 qstr_init(&q, key);
146 return __is_excluded(&q, user);
147 }
148
149 /* Kernel has already enforced everything we returned through
150 * derive_permissions_locked(), so this is used to lock down access
151 * even further, such as enforcing that apps hold sdcard_rw.
152 */
check_caller_access_to_name(struct inode * parent_node,const struct qstr * name)153 int check_caller_access_to_name(struct inode *parent_node, const struct qstr *name)
154 {
155 struct qstr q_autorun = QSTR_LITERAL("autorun.inf");
156 struct qstr q__android_secure = QSTR_LITERAL(".android_secure");
157 struct qstr q_android_secure = QSTR_LITERAL("android_secure");
158
159 /* Always block security-sensitive files at root */
160 if (parent_node && SDCARDFS_I(parent_node)->data->perm == PERM_ROOT) {
161 if (qstr_case_eq(name, &q_autorun)
162 || qstr_case_eq(name, &q__android_secure)
163 || qstr_case_eq(name, &q_android_secure)) {
164 return 0;
165 }
166 }
167
168 /* Root always has access; access for any other UIDs should always
169 * be controlled through packages.list.
170 */
171 if (current_fsuid() == 0)
172 return 1;
173
174 /* No extra permissions to enforce */
175 return 1;
176 }
177
alloc_hashtable_entry(const struct qstr * key,appid_t value)178 static struct hashtable_entry *alloc_hashtable_entry(const struct qstr *key,
179 appid_t value)
180 {
181 struct hashtable_entry *ret = kmem_cache_alloc(hashtable_entry_cachep,
182 GFP_KERNEL);
183 if (!ret)
184 return NULL;
185 INIT_HLIST_NODE(&ret->dlist);
186 INIT_HLIST_NODE(&ret->hlist);
187
188 if (!qstr_copy(key, &ret->key)) {
189 kmem_cache_free(hashtable_entry_cachep, ret);
190 return NULL;
191 }
192
193 atomic_set(&ret->value, value);
194 return ret;
195 }
196
insert_packagelist_appid_entry_locked(const struct qstr * key,appid_t value)197 static int insert_packagelist_appid_entry_locked(const struct qstr *key, appid_t value)
198 {
199 struct hashtable_entry *hash_cur;
200 struct hashtable_entry *new_entry;
201 unsigned int hash = key->hash;
202
203 hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
204 if (qstr_case_eq(key, &hash_cur->key)) {
205 atomic_set(&hash_cur->value, value);
206 return 0;
207 }
208 }
209 new_entry = alloc_hashtable_entry(key, value);
210 if (!new_entry)
211 return -ENOMEM;
212 hash_add_rcu(package_to_appid, &new_entry->hlist, hash);
213 return 0;
214 }
215
insert_ext_gid_entry_locked(const struct qstr * key,appid_t value)216 static int insert_ext_gid_entry_locked(const struct qstr *key, appid_t value)
217 {
218 struct hashtable_entry *hash_cur;
219 struct hashtable_entry *new_entry;
220 unsigned int hash = key->hash;
221
222 /* An extension can only belong to one gid */
223 hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
224 if (qstr_case_eq(key, &hash_cur->key))
225 return -EINVAL;
226 }
227 new_entry = alloc_hashtable_entry(key, value);
228 if (!new_entry)
229 return -ENOMEM;
230 hash_add_rcu(ext_to_groupid, &new_entry->hlist, hash);
231 return 0;
232 }
233
insert_userid_exclude_entry_locked(const struct qstr * key,userid_t value)234 static int insert_userid_exclude_entry_locked(const struct qstr *key, userid_t value)
235 {
236 struct hashtable_entry *hash_cur;
237 struct hashtable_entry *new_entry;
238 unsigned int hash = key->hash;
239
240 /* Only insert if not already present */
241 hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
242 if (atomic_read(&hash_cur->value) == value &&
243 qstr_case_eq(key, &hash_cur->key))
244 return 0;
245 }
246 new_entry = alloc_hashtable_entry(key, value);
247 if (!new_entry)
248 return -ENOMEM;
249 hash_add_rcu(package_to_userid, &new_entry->hlist, hash);
250 return 0;
251 }
252
fixup_all_perms_name(const struct qstr * key)253 static void fixup_all_perms_name(const struct qstr *key)
254 {
255 struct sdcardfs_sb_info *sbinfo;
256 struct limit_search limit = {
257 .flags = BY_NAME,
258 .name = QSTR_INIT(key->name, key->len),
259 };
260 list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
261 if (sbinfo_has_sdcard_magic(sbinfo))
262 fixup_perms_recursive(sbinfo->sb->s_root, &limit);
263 }
264 }
265
fixup_all_perms_name_userid(const struct qstr * key,userid_t userid)266 static void fixup_all_perms_name_userid(const struct qstr *key, userid_t userid)
267 {
268 struct sdcardfs_sb_info *sbinfo;
269 struct limit_search limit = {
270 .flags = BY_NAME | BY_USERID,
271 .name = QSTR_INIT(key->name, key->len),
272 .userid = userid,
273 };
274 list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
275 if (sbinfo_has_sdcard_magic(sbinfo))
276 fixup_perms_recursive(sbinfo->sb->s_root, &limit);
277 }
278 }
279
fixup_all_perms_userid(userid_t userid)280 static void fixup_all_perms_userid(userid_t userid)
281 {
282 struct sdcardfs_sb_info *sbinfo;
283 struct limit_search limit = {
284 .flags = BY_USERID,
285 .userid = userid,
286 };
287 list_for_each_entry(sbinfo, &sdcardfs_super_list, list) {
288 if (sbinfo_has_sdcard_magic(sbinfo))
289 fixup_perms_recursive(sbinfo->sb->s_root, &limit);
290 }
291 }
292
insert_packagelist_entry(const struct qstr * key,appid_t value)293 static int insert_packagelist_entry(const struct qstr *key, appid_t value)
294 {
295 int err;
296
297 mutex_lock(&sdcardfs_super_list_lock);
298 err = insert_packagelist_appid_entry_locked(key, value);
299 if (!err)
300 fixup_all_perms_name(key);
301 mutex_unlock(&sdcardfs_super_list_lock);
302
303 return err;
304 }
305
insert_ext_gid_entry(const struct qstr * key,appid_t value)306 static int insert_ext_gid_entry(const struct qstr *key, appid_t value)
307 {
308 int err;
309
310 mutex_lock(&sdcardfs_super_list_lock);
311 err = insert_ext_gid_entry_locked(key, value);
312 mutex_unlock(&sdcardfs_super_list_lock);
313
314 return err;
315 }
316
insert_userid_exclude_entry(const struct qstr * key,userid_t value)317 static int insert_userid_exclude_entry(const struct qstr *key, userid_t value)
318 {
319 int err;
320
321 mutex_lock(&sdcardfs_super_list_lock);
322 err = insert_userid_exclude_entry_locked(key, value);
323 if (!err)
324 fixup_all_perms_name_userid(key, value);
325 mutex_unlock(&sdcardfs_super_list_lock);
326
327 return err;
328 }
329
free_hashtable_entry(struct hashtable_entry * entry)330 static void free_hashtable_entry(struct hashtable_entry *entry)
331 {
332 kfree(entry->key.name);
333 kmem_cache_free(hashtable_entry_cachep, entry);
334 }
335
remove_packagelist_entry_locked(const struct qstr * key)336 static void remove_packagelist_entry_locked(const struct qstr *key)
337 {
338 struct hashtable_entry *hash_cur;
339 unsigned int hash = key->hash;
340 struct hlist_node *h_t;
341 HLIST_HEAD(free_list);
342
343 hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
344 if (qstr_case_eq(key, &hash_cur->key)) {
345 hash_del_rcu(&hash_cur->hlist);
346 hlist_add_head(&hash_cur->dlist, &free_list);
347 }
348 }
349 hash_for_each_possible_rcu(package_to_appid, hash_cur, hlist, hash) {
350 if (qstr_case_eq(key, &hash_cur->key)) {
351 hash_del_rcu(&hash_cur->hlist);
352 hlist_add_head(&hash_cur->dlist, &free_list);
353 break;
354 }
355 }
356 synchronize_rcu();
357 hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist)
358 free_hashtable_entry(hash_cur);
359 }
360
remove_packagelist_entry(const struct qstr * key)361 static void remove_packagelist_entry(const struct qstr *key)
362 {
363 mutex_lock(&sdcardfs_super_list_lock);
364 remove_packagelist_entry_locked(key);
365 fixup_all_perms_name(key);
366 mutex_unlock(&sdcardfs_super_list_lock);
367 }
368
remove_ext_gid_entry_locked(const struct qstr * key,gid_t group)369 static void remove_ext_gid_entry_locked(const struct qstr *key, gid_t group)
370 {
371 struct hashtable_entry *hash_cur;
372 unsigned int hash = key->hash;
373
374 hash_for_each_possible_rcu(ext_to_groupid, hash_cur, hlist, hash) {
375 if (qstr_case_eq(key, &hash_cur->key) && atomic_read(&hash_cur->value) == group) {
376 hash_del_rcu(&hash_cur->hlist);
377 synchronize_rcu();
378 free_hashtable_entry(hash_cur);
379 break;
380 }
381 }
382 }
383
remove_ext_gid_entry(const struct qstr * key,gid_t group)384 static void remove_ext_gid_entry(const struct qstr *key, gid_t group)
385 {
386 mutex_lock(&sdcardfs_super_list_lock);
387 remove_ext_gid_entry_locked(key, group);
388 mutex_unlock(&sdcardfs_super_list_lock);
389 }
390
remove_userid_all_entry_locked(userid_t userid)391 static void remove_userid_all_entry_locked(userid_t userid)
392 {
393 struct hashtable_entry *hash_cur;
394 struct hlist_node *h_t;
395 HLIST_HEAD(free_list);
396 int i;
397
398 hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) {
399 if (atomic_read(&hash_cur->value) == userid) {
400 hash_del_rcu(&hash_cur->hlist);
401 hlist_add_head(&hash_cur->dlist, &free_list);
402 }
403 }
404 synchronize_rcu();
405 hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist) {
406 free_hashtable_entry(hash_cur);
407 }
408 }
409
remove_userid_all_entry(userid_t userid)410 static void remove_userid_all_entry(userid_t userid)
411 {
412 mutex_lock(&sdcardfs_super_list_lock);
413 remove_userid_all_entry_locked(userid);
414 fixup_all_perms_userid(userid);
415 mutex_unlock(&sdcardfs_super_list_lock);
416 }
417
remove_userid_exclude_entry_locked(const struct qstr * key,userid_t userid)418 static void remove_userid_exclude_entry_locked(const struct qstr *key, userid_t userid)
419 {
420 struct hashtable_entry *hash_cur;
421 unsigned int hash = key->hash;
422
423 hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
424 if (qstr_case_eq(key, &hash_cur->key) &&
425 atomic_read(&hash_cur->value) == userid) {
426 hash_del_rcu(&hash_cur->hlist);
427 synchronize_rcu();
428 free_hashtable_entry(hash_cur);
429 break;
430 }
431 }
432 }
433
remove_userid_exclude_entry(const struct qstr * key,userid_t userid)434 static void remove_userid_exclude_entry(const struct qstr *key, userid_t userid)
435 {
436 mutex_lock(&sdcardfs_super_list_lock);
437 remove_userid_exclude_entry_locked(key, userid);
438 fixup_all_perms_name_userid(key, userid);
439 mutex_unlock(&sdcardfs_super_list_lock);
440 }
441
packagelist_destroy(void)442 static void packagelist_destroy(void)
443 {
444 struct hashtable_entry *hash_cur;
445 struct hlist_node *h_t;
446 HLIST_HEAD(free_list);
447 int i;
448
449 mutex_lock(&sdcardfs_super_list_lock);
450 hash_for_each_rcu(package_to_appid, i, hash_cur, hlist) {
451 hash_del_rcu(&hash_cur->hlist);
452 hlist_add_head(&hash_cur->dlist, &free_list);
453 }
454 hash_for_each_rcu(package_to_userid, i, hash_cur, hlist) {
455 hash_del_rcu(&hash_cur->hlist);
456 hlist_add_head(&hash_cur->dlist, &free_list);
457 }
458 synchronize_rcu();
459 hlist_for_each_entry_safe(hash_cur, h_t, &free_list, dlist)
460 free_hashtable_entry(hash_cur);
461 mutex_unlock(&sdcardfs_super_list_lock);
462 pr_info("sdcardfs: destroyed packagelist pkgld\n");
463 }
464
465 struct package_details {
466 struct config_item item;
467 struct qstr name;
468 };
469
to_package_details(struct config_item * item)470 static inline struct package_details *to_package_details(struct config_item *item)
471 {
472 return item ? container_of(item, struct package_details, item) : NULL;
473 }
474
475 CONFIGFS_ATTR_STRUCT(package_details);
476 #define PACKAGE_DETAILS_ATTR(_name, _mode, _show, _store) \
477 struct package_details_attribute package_details_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
478 #define PACKAGE_DETAILS_ATTRIBUTE(name) (&package_details_attr_##name.attr)
479
package_details_appid_show(struct package_details * package_details,char * page)480 static ssize_t package_details_appid_show(struct package_details *package_details,
481 char *page)
482 {
483 return scnprintf(page, PAGE_SIZE, "%u\n", __get_appid(&package_details->name));
484 }
485
package_details_appid_store(struct package_details * package_details,const char * page,size_t count)486 static ssize_t package_details_appid_store(struct package_details *package_details,
487 const char *page, size_t count)
488 {
489 unsigned int tmp;
490 int ret;
491
492 ret = kstrtouint(page, 10, &tmp);
493 if (ret)
494 return ret;
495
496 ret = insert_packagelist_entry(&package_details->name, tmp);
497
498 if (ret)
499 return ret;
500
501 return count;
502 }
503
package_details_excluded_userids_show(struct package_details * package_details,char * page)504 static ssize_t package_details_excluded_userids_show(struct package_details *package_details,
505 char *page)
506 {
507 struct hashtable_entry *hash_cur;
508 unsigned int hash = package_details->name.hash;
509 int count = 0;
510
511 rcu_read_lock();
512 hash_for_each_possible_rcu(package_to_userid, hash_cur, hlist, hash) {
513 if (qstr_case_eq(&package_details->name, &hash_cur->key))
514 count += scnprintf(page + count, PAGE_SIZE - count,
515 "%d ", atomic_read(&hash_cur->value));
516 }
517 rcu_read_unlock();
518 if (count)
519 count--;
520 count += scnprintf(page + count, PAGE_SIZE - count, "\n");
521 return count;
522 }
523
package_details_excluded_userids_store(struct package_details * package_details,const char * page,size_t count)524 static ssize_t package_details_excluded_userids_store(struct package_details *package_details,
525 const char *page, size_t count)
526 {
527 unsigned int tmp;
528 int ret;
529
530 ret = kstrtouint(page, 10, &tmp);
531 if (ret)
532 return ret;
533
534 ret = insert_userid_exclude_entry(&package_details->name, tmp);
535
536 if (ret)
537 return ret;
538
539 return count;
540 }
541
package_details_clear_userid_store(struct package_details * package_details,const char * page,size_t count)542 static ssize_t package_details_clear_userid_store(struct package_details *package_details,
543 const char *page, size_t count)
544 {
545 unsigned int tmp;
546 int ret;
547
548 ret = kstrtouint(page, 10, &tmp);
549 if (ret)
550 return ret;
551 remove_userid_exclude_entry(&package_details->name, tmp);
552 return count;
553 }
554
package_details_release(struct config_item * item)555 static void package_details_release(struct config_item *item)
556 {
557 struct package_details *package_details = to_package_details(item);
558
559 pr_info("sdcardfs: removing %s\n", package_details->name.name);
560 remove_packagelist_entry(&package_details->name);
561 kfree(package_details->name.name);
562 kfree(package_details);
563 }
564
565 PACKAGE_DETAILS_ATTR(appid, S_IRUGO | S_IWUGO, package_details_appid_show, package_details_appid_store);
566 PACKAGE_DETAILS_ATTR(excluded_userids, S_IRUGO | S_IWUGO,
567 package_details_excluded_userids_show, package_details_excluded_userids_store);
568 PACKAGE_DETAILS_ATTR(clear_userid, S_IWUGO, NULL, package_details_clear_userid_store);
569
570 static struct configfs_attribute *package_details_attrs[] = {
571 PACKAGE_DETAILS_ATTRIBUTE(appid),
572 PACKAGE_DETAILS_ATTRIBUTE(excluded_userids),
573 PACKAGE_DETAILS_ATTRIBUTE(clear_userid),
574 NULL,
575 };
576
577 CONFIGFS_ATTR_OPS(package_details);
578
579 static struct configfs_item_operations package_details_item_ops = {
580 .release = package_details_release,
581 .show_attribute = package_details_attr_show,
582 .store_attribute = package_details_attr_store,
583 };
584
585 static struct config_item_type package_appid_type = {
586 .ct_item_ops = &package_details_item_ops,
587 .ct_attrs = package_details_attrs,
588 .ct_owner = THIS_MODULE,
589 };
590
591 struct extensions_value {
592 struct config_group group;
593 unsigned int num;
594 };
595
596 struct extension_details {
597 struct config_item item;
598 struct qstr name;
599 unsigned int num;
600 };
601
to_extensions_value(struct config_item * item)602 static inline struct extensions_value *to_extensions_value(struct config_item *item)
603 {
604 return item ? container_of(to_config_group(item), struct extensions_value, group) : NULL;
605 }
606
to_extension_details(struct config_item * item)607 static inline struct extension_details *to_extension_details(struct config_item *item)
608 {
609 return item ? container_of(item, struct extension_details, item) : NULL;
610 }
611
extension_details_release(struct config_item * item)612 static void extension_details_release(struct config_item *item)
613 {
614 struct extension_details *extension_details = to_extension_details(item);
615
616 pr_info("sdcardfs: No longer mapping %s files to gid %d\n",
617 extension_details->name.name, extension_details->num);
618 remove_ext_gid_entry(&extension_details->name, extension_details->num);
619 kfree(extension_details->name.name);
620 kfree(extension_details);
621 }
622
623 static struct configfs_item_operations extension_details_item_ops = {
624 .release = extension_details_release,
625 };
626
627 static struct config_item_type extension_details_type = {
628 .ct_item_ops = &extension_details_item_ops,
629 .ct_owner = THIS_MODULE,
630 };
631
extension_details_make_item(struct config_group * group,const char * name)632 static struct config_item *extension_details_make_item(struct config_group *group, const char *name)
633 {
634 struct extensions_value *extensions_value = to_extensions_value(&group->cg_item);
635 struct extension_details *extension_details = kzalloc(sizeof(struct extension_details), GFP_KERNEL);
636 const char *tmp;
637 int ret;
638
639 if (!extension_details)
640 return ERR_PTR(-ENOMEM);
641
642 tmp = kstrdup(name, GFP_KERNEL);
643 if (!tmp) {
644 kfree(extension_details);
645 return ERR_PTR(-ENOMEM);
646 }
647 qstr_init(&extension_details->name, tmp);
648 ret = insert_ext_gid_entry(&extension_details->name, extensions_value->num);
649
650 if (ret) {
651 kfree(extension_details->name.name);
652 kfree(extension_details);
653 return ERR_PTR(ret);
654 }
655 config_item_init_type_name(&extension_details->item, name, &extension_details_type);
656
657 return &extension_details->item;
658 }
659
660 static struct configfs_group_operations extensions_value_group_ops = {
661 .make_item = extension_details_make_item,
662 };
663
664 static struct config_item_type extensions_name_type = {
665 .ct_group_ops = &extensions_value_group_ops,
666 .ct_owner = THIS_MODULE,
667 };
668
extensions_make_group(struct config_group * group,const char * name)669 static struct config_group *extensions_make_group(struct config_group *group, const char *name)
670 {
671 struct extensions_value *extensions_value;
672 unsigned int tmp;
673 int ret;
674
675 extensions_value = kzalloc(sizeof(struct extensions_value), GFP_KERNEL);
676 if (!extensions_value)
677 return ERR_PTR(-ENOMEM);
678 ret = kstrtouint(name, 10, &tmp);
679 if (ret) {
680 kfree(extensions_value);
681 return ERR_PTR(ret);
682 }
683
684 extensions_value->num = tmp;
685 config_group_init_type_name(&extensions_value->group, name,
686 &extensions_name_type);
687 return &extensions_value->group;
688 }
689
extensions_drop_group(struct config_group * group,struct config_item * item)690 static void extensions_drop_group(struct config_group *group, struct config_item *item)
691 {
692 struct extensions_value *value = to_extensions_value(item);
693
694 pr_info("sdcardfs: No longer mapping any files to gid %d\n", value->num);
695 kfree(value);
696 }
697
698 static struct configfs_group_operations extensions_group_ops = {
699 .make_group = extensions_make_group,
700 .drop_item = extensions_drop_group,
701 };
702
703 static struct config_item_type extensions_type = {
704 .ct_group_ops = &extensions_group_ops,
705 .ct_owner = THIS_MODULE,
706 };
707
708 struct config_group extension_group = {
709 .cg_item = {
710 .ci_namebuf = "extensions",
711 .ci_type = &extensions_type,
712 },
713 };
714
715 struct packages {
716 struct configfs_subsystem subsystem;
717 };
718
to_packages(struct config_item * item)719 static inline struct packages *to_packages(struct config_item *item)
720 {
721 return item ? container_of(to_configfs_subsystem(to_config_group(item)), struct packages, subsystem) : NULL;
722 }
723
724 CONFIGFS_ATTR_STRUCT(packages);
725 #define PACKAGES_ATTR(_name, _mode, _show, _store) \
726 struct packages_attribute packages_attr_##_name = __CONFIGFS_ATTR(_name, _mode, _show, _store)
727 #define PACKAGES_ATTR_RO(_name, _show) \
728 struct packages_attribute packages_attr_##_name = __CONFIGFS_ATTR_RO(_name, _show)
729
packages_make_item(struct config_group * group,const char * name)730 static struct config_item *packages_make_item(struct config_group *group, const char *name)
731 {
732 struct package_details *package_details;
733 const char *tmp;
734
735 package_details = kzalloc(sizeof(struct package_details), GFP_KERNEL);
736 if (!package_details)
737 return ERR_PTR(-ENOMEM);
738 tmp = kstrdup(name, GFP_KERNEL);
739 if (!tmp) {
740 kfree(package_details);
741 return ERR_PTR(-ENOMEM);
742 }
743 qstr_init(&package_details->name, tmp);
744 config_item_init_type_name(&package_details->item, name,
745 &package_appid_type);
746
747 return &package_details->item;
748 }
749
packages_list_show(struct packages * packages,char * page)750 static ssize_t packages_list_show(struct packages *packages,
751 char *page)
752 {
753 struct hashtable_entry *hash_cur_app;
754 struct hashtable_entry *hash_cur_user;
755 int i;
756 int count = 0, written = 0;
757 const char errormsg[] = "<truncated>\n";
758 unsigned int hash;
759
760 rcu_read_lock();
761 hash_for_each_rcu(package_to_appid, i, hash_cur_app, hlist) {
762 written = scnprintf(page + count, PAGE_SIZE - sizeof(errormsg) - count, "%s %d\n",
763 hash_cur_app->key.name, atomic_read(&hash_cur_app->value));
764 hash = hash_cur_app->key.hash;
765 hash_for_each_possible_rcu(package_to_userid, hash_cur_user, hlist, hash) {
766 if (qstr_case_eq(&hash_cur_app->key, &hash_cur_user->key)) {
767 written += scnprintf(page + count + written - 1,
768 PAGE_SIZE - sizeof(errormsg) - count - written + 1,
769 " %d\n", atomic_read(&hash_cur_user->value)) - 1;
770 }
771 }
772 if (count + written == PAGE_SIZE - sizeof(errormsg) - 1) {
773 count += scnprintf(page + count, PAGE_SIZE - count, errormsg);
774 break;
775 }
776 count += written;
777 }
778 rcu_read_unlock();
779
780 return count;
781 }
782
packages_remove_userid_store(struct packages * packages,const char * page,size_t count)783 static ssize_t packages_remove_userid_store(struct packages *packages,
784 const char *page, size_t count)
785 {
786 unsigned int tmp;
787 int ret;
788
789 ret = kstrtouint(page, 10, &tmp);
790 if (ret)
791 return ret;
792 remove_userid_all_entry(tmp);
793 return count;
794 }
795
796 struct packages_attribute packages_attr_packages_gid_list = __CONFIGFS_ATTR_RO(packages_gid.list, packages_list_show);
797 PACKAGES_ATTR(remove_userid, S_IWUGO, NULL, packages_remove_userid_store);
798
799 static struct configfs_attribute *packages_attrs[] = {
800 &packages_attr_packages_gid_list.attr,
801 &packages_attr_remove_userid.attr,
802 NULL,
803 };
804
805 CONFIGFS_ATTR_OPS(packages)
806 static struct configfs_item_operations packages_item_ops = {
807 .show_attribute = packages_attr_show,
808 .store_attribute = packages_attr_store,
809 };
810
811 /*
812 * Note that, since no extra work is required on ->drop_item(),
813 * no ->drop_item() is provided.
814 */
815 static struct configfs_group_operations packages_group_ops = {
816 .make_item = packages_make_item,
817 };
818
819 static struct config_item_type packages_type = {
820 .ct_item_ops = &packages_item_ops,
821 .ct_group_ops = &packages_group_ops,
822 .ct_attrs = packages_attrs,
823 .ct_owner = THIS_MODULE,
824 };
825
826 struct config_group *sd_default_groups[] = {
827 &extension_group,
828 NULL,
829 };
830
831 static struct packages sdcardfs_packages = {
832 .subsystem = {
833 .su_group = {
834 .cg_item = {
835 .ci_namebuf = "sdcardfs",
836 .ci_type = &packages_type,
837 },
838 .default_groups = sd_default_groups,
839 },
840 },
841 };
842
configfs_sdcardfs_init(void)843 static int configfs_sdcardfs_init(void)
844 {
845 int ret, i;
846 struct configfs_subsystem *subsys = &sdcardfs_packages.subsystem;
847
848 for (i = 0; sd_default_groups[i]; i++)
849 config_group_init(sd_default_groups[i]);
850 config_group_init(&subsys->su_group);
851 mutex_init(&subsys->su_mutex);
852 ret = configfs_register_subsystem(subsys);
853 if (ret) {
854 pr_err("Error %d while registering subsystem %s\n",
855 ret,
856 subsys->su_group.cg_item.ci_namebuf);
857 }
858 return ret;
859 }
860
configfs_sdcardfs_exit(void)861 static void configfs_sdcardfs_exit(void)
862 {
863 configfs_unregister_subsystem(&sdcardfs_packages.subsystem);
864 }
865
packagelist_init(void)866 int packagelist_init(void)
867 {
868 hashtable_entry_cachep =
869 kmem_cache_create("packagelist_hashtable_entry",
870 sizeof(struct hashtable_entry), 0, 0, NULL);
871 if (!hashtable_entry_cachep) {
872 pr_err("sdcardfs: failed creating pkgl_hashtable entry slab cache\n");
873 return -ENOMEM;
874 }
875
876 configfs_sdcardfs_init();
877 return 0;
878 }
879
packagelist_exit(void)880 void packagelist_exit(void)
881 {
882 configfs_sdcardfs_exit();
883 packagelist_destroy();
884 kmem_cache_destroy(hashtable_entry_cachep);
885 }
886