mm.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
  1. /*
  2. * Copyright (c) 2015 Samsung Electronics Co., Ltd.
  3. *
  4. * Sensitive Data Protection
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License version 2 as
  8. * published by the Free Software Foundation.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License along
  16. * with this program; if not, write to the Free Software Foundation, Inc.,
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18. */
  19. #include <linux/kernel.h>
  20. #include <linux/mm.h>
  21. #include <linux/fs.h>
  22. #include <linux/kthread.h>
  23. #include <linux/slab.h>
  24. #include <linux/delay.h>
  25. #include <linux/mutex.h>
  26. #include <linux/swap.h>
  27. #include <linux/pagemap.h>
  28. #include "ecryptfs_kernel.h"
  29. extern spinlock_t inode_sb_list_lock;
  30. static int ecryptfs_mm_debug = 0;
  31. DEFINE_MUTEX(ecryptfs_mm_mutex);
  32. struct ecryptfs_mm_drop_cache_param {
  33. int user_id;
  34. int engine_id;
  35. };
  36. #define INVALIDATE_MAPPING_RETRY_CNT 3
  37. static unsigned long invalidate_mapping_pages_retry(struct address_space *mapping,
  38. pgoff_t start, pgoff_t end, int retries) {
  39. unsigned long ret;
  40. if(ecryptfs_mm_debug)
  41. printk("freeing [%s] sensitive inode[mapped pagenum = %lu]\n",
  42. mapping->host->i_sb->s_type->name,
  43. mapping->nrpages);
  44. retry:
  45. ret = invalidate_mapping_pages(mapping, start, end);
  46. if(ecryptfs_mm_debug)
  47. printk("invalidate_mapping_pages ret = %lu, [%lu] remained\n",
  48. ret, mapping->nrpages);
  49. if(mapping->nrpages != 0) {
  50. if(retries > 0) {
  51. printk("[%lu] mapped pages remained in sensitive inode, retry..\n",
  52. mapping->nrpages);
  53. retries--;
  54. msleep(100);
  55. goto retry;
  56. }
  57. }
  58. return ret;
  59. }
  60. #if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS)
  61. static unsigned long invalidate_lower_mapping_pages_retry(struct file *lower_file, int retries) {
  62. unsigned long ret, invalidated = 0;
  63. struct address_space *mapping;
  64. mapping = lower_file->f_mapping;
  65. if(ecryptfs_mm_debug)
  66. printk("%s:freeing [%s] sensitive inode[mapped pagenum = %lu]\n",__func__,
  67. mapping->host->i_sb->s_type->name,mapping->nrpages);
  68. for (; retries > 0; retries--) {
  69. // !! TODO !!
  70. //if (lower_file && lower_file->f_op && lower_file->f_op->unlocked_ioctl)
  71. // ret = lower_file->f_op->unlocked_ioctl(lower_file, FS_IOC_INVAL_MAPPING, 0);
  72. ret = do_vfs_ioctl(lower_file,0, FS_IOC_INVAL_MAPPING, 0); // lower_file is sdcardfs file
  73. invalidated += ret;
  74. if(ecryptfs_mm_debug)
  75. printk("invalidate_mapping_pages ret = %lu, [%lu] remained\n",
  76. ret, mapping->nrpages);
  77. if (mapping->nrpages == 0)
  78. break;
  79. printk("[%lu] mapped pages remained in sensitive inode, retry..\n",
  80. mapping->nrpages);
  81. msleep(100);
  82. }
  83. return invalidated;
  84. }
  85. #endif
  86. void ecryptfs_mm_do_sdp_cleanup(struct inode *inode) {
  87. struct ecryptfs_crypt_stat *crypt_stat;
  88. struct ecryptfs_mount_crypt_stat *mount_crypt_stat = NULL;
  89. struct ecryptfs_inode_info *inode_info;
  90. crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
  91. mount_crypt_stat = &ecryptfs_superblock_to_private(inode->i_sb)->mount_crypt_stat;
  92. inode_info = ecryptfs_inode_to_private(inode);
  93. if(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) {
  94. int rc;
  95. if(S_ISDIR(inode->i_mode)) {
  96. DEK_LOGD("%s: inode: %p is dir, return\n",__func__, inode);
  97. return;
  98. }
  99. DEK_LOGD("%s: inode: %p clean up start\n",__func__, inode);
  100. rc = vfs_fsync(inode_info->lower_file, 0);
  101. if(rc)
  102. DEK_LOGE("%s: vfs_sync returned error rc: %d\n", __func__, rc);
  103. if(ecryptfs_is_sdp_locked(crypt_stat->engine_id)) {
  104. DEK_LOGD("%s: persona locked inode: %lu useid: %d\n",
  105. __func__, inode->i_ino, crypt_stat->engine_id);
  106. invalidate_mapping_pages_retry(inode->i_mapping, 0, -1, 3);
  107. }
  108. #if defined(CONFIG_MMC_DW_FMP_ECRYPT_FS) || defined(CONFIG_UFS_FMP_ECRYPT_FS)
  109. if (mount_crypt_stat->flags & ECRYPTFS_USE_FMP) {
  110. DEK_LOGD("%s inode: %p calling invalidate_lower_mapping_pages_retry\n",__func__, inode);
  111. invalidate_lower_mapping_pages_retry(inode_info->lower_file, 3);
  112. }
  113. #endif
  114. if(ecryptfs_is_sdp_locked(crypt_stat->engine_id)) {
  115. ecryptfs_clean_sdp_dek(crypt_stat);
  116. }
  117. DEK_LOGD("%s: inode: %p clean up stop\n",__func__, inode);
  118. }
  119. return;
  120. }
  121. static unsigned long drop_inode_pagecache(struct inode *inode) {
  122. int rc = 0;
  123. spin_lock(&inode->i_lock);
  124. if(ecryptfs_mm_debug)
  125. printk("%s() cleaning [%s] pages: %lu\n", __func__,
  126. inode->i_sb->s_type->name,inode->i_mapping->nrpages);
  127. if ((inode->i_mapping->nrpages == 0)) {
  128. spin_unlock(&inode->i_lock);
  129. printk("%s inode having zero nrpages\n", __func__);
  130. return 0;
  131. }
  132. spin_unlock(&inode->i_lock);
  133. /*
  134. * flush mapped dirty pages.
  135. */
  136. rc = filemap_write_and_wait(inode->i_mapping);
  137. if(rc)
  138. printk("filemap_flush failed, rc=%d\n", rc);
  139. if (inode->i_mapping->nrpages != 0)
  140. lru_add_drain_all();
  141. rc = invalidate_mapping_pages_retry(inode->i_mapping, 0, -1,
  142. INVALIDATE_MAPPING_RETRY_CNT);
  143. if(inode->i_mapping->nrpages)
  144. printk("%s() uncleaned [%s] pages: %lu\n", __func__,
  145. inode->i_sb->s_type->name,inode->i_mapping->nrpages);
  146. return rc;
  147. }
  148. static void ecryptfs_mm_drop_pagecache(struct super_block *sb, void *arg)
  149. {
  150. struct inode *inode;
  151. struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
  152. struct ecryptfs_mm_drop_cache_param *param = arg;
  153. if(strcmp("ecryptfs", sb->s_type->name)) {
  154. printk("%s sb:%s is not ecryptfs superblock\n", __func__,
  155. sb->s_type->name);
  156. return;
  157. }
  158. mount_crypt_stat = &ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
  159. printk("%s start() sb:%s [%d], userid:%d\n", __func__,
  160. sb->s_type->name, mount_crypt_stat->userid, param->user_id);
  161. if (param->user_id >= 100 && param->user_id < 200) {
  162. if(mount_crypt_stat->userid != param->user_id)
  163. return;
  164. }
  165. spin_lock(&inode_sb_list_lock);
  166. list_for_each_entry(inode, &sb->s_inodes, i_sb_list)
  167. {
  168. struct ecryptfs_crypt_stat *crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
  169. if(crypt_stat == NULL)
  170. continue;
  171. if(crypt_stat->engine_id != param->engine_id) {
  172. continue;
  173. }
  174. if (!inode->i_mapping) {
  175. continue;
  176. }
  177. spin_lock(&inode->i_lock);
  178. if (inode->i_mapping->nrpages == 0) {
  179. spin_unlock(&inode->i_lock);
  180. spin_unlock(&inode_sb_list_lock);
  181. if(ecryptfs_mm_debug)
  182. printk("%s() ecryptfs inode [ino:%lu]\n",__func__, inode->i_ino);
  183. if((crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE) &&
  184. !atomic_read(&ecryptfs_inode_to_private(inode)->lower_file_count))
  185. ecryptfs_clean_sdp_dek(crypt_stat);
  186. spin_lock(&inode_sb_list_lock);
  187. continue;
  188. }
  189. spin_unlock(&inode->i_lock);
  190. spin_unlock(&inode_sb_list_lock);
  191. if(ecryptfs_mm_debug)
  192. printk(KERN_ERR "inode number: %lu i_mapping: %p [%s] userid:%d\n",inode->i_ino,
  193. inode->i_mapping,inode->i_sb->s_type->name,inode->i_mapping->userid);
  194. if(mapping_sensitive(inode->i_mapping) &&
  195. !atomic_read(&ecryptfs_inode_to_private(inode)->lower_file_count)) {
  196. drop_inode_pagecache(inode);
  197. if(ecryptfs_mm_debug)
  198. printk(KERN_ERR "lower inode: %p lower inode: %p nrpages: %lu\n",ecryptfs_inode_to_lower(inode),
  199. ecryptfs_inode_to_private(inode), ecryptfs_inode_to_lower(inode)->i_mapping->nrpages);
  200. if(crypt_stat->flags & ECRYPTFS_DEK_IS_SENSITIVE)
  201. ecryptfs_clean_sdp_dek(crypt_stat);
  202. }
  203. spin_lock(&inode_sb_list_lock);
  204. }
  205. spin_unlock(&inode_sb_list_lock);
  206. }
  207. static int ecryptfs_mm_task(void *arg)
  208. {
  209. struct file_system_type *type;
  210. struct ecryptfs_mm_drop_cache_param *param = arg;
  211. type = get_fs_type("ecryptfs");
  212. if(type) {
  213. if(ecryptfs_mm_debug)
  214. printk("%s type name: %s flags: %d\n", __func__, type->name, type->fs_flags);
  215. mutex_lock(&ecryptfs_mm_mutex);
  216. iterate_supers_type(type,ecryptfs_mm_drop_pagecache, param);
  217. mutex_unlock(&ecryptfs_mm_mutex);
  218. put_filesystem(type);
  219. }
  220. kfree(param);
  221. return 0;
  222. }
  223. void ecryptfs_mm_drop_cache(int userid, int engineid) {
  224. #if 1
  225. struct task_struct *task;
  226. struct ecryptfs_mm_drop_cache_param *param =
  227. kzalloc(sizeof(*param), GFP_KERNEL);
  228. if (!param) {
  229. printk("%s :: skip. no memory to alloc param\n", __func__);
  230. return;
  231. }
  232. param->user_id = userid;
  233. param->engine_id = engineid;
  234. printk("running cache cleanup thread - sdp-id : %d\n", userid);
  235. task = kthread_run(ecryptfs_mm_task, param, "sdp_cached");
  236. if (IS_ERR(task)) {
  237. printk(KERN_ERR "SDP : unable to create kernel thread: %ld\n",
  238. PTR_ERR(task));
  239. }
  240. #else
  241. ecryptfs_mm_task(&userid);
  242. #endif
  243. }
  244. #include <linux/pagevec.h>
  245. #include <linux/pagemap.h>
  246. #include <linux/memcontrol.h>
  247. #include <linux/atomic.h>
  248. static void __page_dump(unsigned char *buf, int len, const char* str)
  249. {
  250. unsigned int i;
  251. char s[512];
  252. s[0] = 0;
  253. for(i=0;i<len && i<16;++i) {
  254. char tmp[8];
  255. sprintf(tmp, " %02x", buf[i]);
  256. strcat(s, tmp);
  257. }
  258. if (len > 16) {
  259. char tmp[8];
  260. sprintf(tmp, " ...");
  261. strcat(s, tmp);
  262. }
  263. DEK_LOGD("%s [%s len=%d]\n", s, str, len);
  264. }
  265. #ifdef DEK_DEBUG
  266. /*
  267. * This dump will appear in ramdump
  268. */
  269. void page_dump (struct page *p) {
  270. void *d;
  271. d = kmap_atomic(p);
  272. if(d) {
  273. __page_dump((unsigned char *)d, PAGE_SIZE, "freeing");
  274. kunmap_atomic(d);
  275. }
  276. }
  277. #else
  278. void page_dump (struct page *p) {
  279. // Do nothing
  280. }
  281. #endif