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