tomoyo.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*
  2. * security/tomoyo/tomoyo.c
  3. *
  4. * LSM hooks for TOMOYO Linux.
  5. *
  6. * Copyright (C) 2005-2009 NTT DATA CORPORATION
  7. *
  8. * Version: 2.2.0 2009/04/01
  9. *
  10. */
  11. #include <linux/security.h>
  12. #include "common.h"
  13. static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
  14. {
  15. new->security = NULL;
  16. return 0;
  17. }
  18. static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
  19. gfp_t gfp)
  20. {
  21. /*
  22. * Since "struct tomoyo_domain_info *" is a sharable pointer,
  23. * we don't need to duplicate.
  24. */
  25. new->security = old->security;
  26. return 0;
  27. }
  28. static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
  29. {
  30. /*
  31. * Since "struct tomoyo_domain_info *" is a sharable pointer,
  32. * we don't need to duplicate.
  33. */
  34. new->security = old->security;
  35. }
  36. static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
  37. {
  38. int rc;
  39. rc = cap_bprm_set_creds(bprm);
  40. if (rc)
  41. return rc;
  42. /*
  43. * Do only if this function is called for the first time of an execve
  44. * operation.
  45. */
  46. if (bprm->cred_prepared)
  47. return 0;
  48. /*
  49. * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
  50. * for the first time.
  51. */
  52. if (!tomoyo_policy_loaded)
  53. tomoyo_load_policy(bprm->filename);
  54. /*
  55. * Tell tomoyo_bprm_check_security() is called for the first time of an
  56. * execve operation.
  57. */
  58. bprm->cred->security = NULL;
  59. return 0;
  60. }
  61. static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
  62. {
  63. struct tomoyo_domain_info *domain = bprm->cred->security;
  64. /*
  65. * Execute permission is checked against pathname passed to do_execve()
  66. * using current domain.
  67. */
  68. if (!domain) {
  69. /*
  70. * We will need to protect whole execve() operation when GC
  71. * starts kfree()ing "struct tomoyo_domain_info" because
  72. * bprm->cred->security points to "struct tomoyo_domain_info"
  73. * but "struct tomoyo_domain_info" does not have a refcounter.
  74. */
  75. const int idx = tomoyo_read_lock();
  76. const int err = tomoyo_find_next_domain(bprm);
  77. tomoyo_read_unlock(idx);
  78. return err;
  79. }
  80. /*
  81. * Read permission is checked against interpreters using next domain.
  82. * '1' is the result of open_to_namei_flags(O_RDONLY).
  83. */
  84. return tomoyo_check_open_permission(domain, &bprm->file->f_path, 1);
  85. }
  86. static int tomoyo_path_truncate(struct path *path, loff_t length,
  87. unsigned int time_attrs)
  88. {
  89. return tomoyo_check_1path_perm(tomoyo_domain(),
  90. TOMOYO_TYPE_TRUNCATE_ACL,
  91. path);
  92. }
  93. static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
  94. {
  95. struct path path = { parent->mnt, dentry };
  96. return tomoyo_check_1path_perm(tomoyo_domain(),
  97. TOMOYO_TYPE_UNLINK_ACL,
  98. &path);
  99. }
  100. static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
  101. int mode)
  102. {
  103. struct path path = { parent->mnt, dentry };
  104. return tomoyo_check_1path_perm(tomoyo_domain(),
  105. TOMOYO_TYPE_MKDIR_ACL,
  106. &path);
  107. }
  108. static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
  109. {
  110. struct path path = { parent->mnt, dentry };
  111. return tomoyo_check_1path_perm(tomoyo_domain(),
  112. TOMOYO_TYPE_RMDIR_ACL,
  113. &path);
  114. }
  115. static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
  116. const char *old_name)
  117. {
  118. struct path path = { parent->mnt, dentry };
  119. return tomoyo_check_1path_perm(tomoyo_domain(),
  120. TOMOYO_TYPE_SYMLINK_ACL,
  121. &path);
  122. }
  123. static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
  124. int mode, unsigned int dev)
  125. {
  126. struct path path = { parent->mnt, dentry };
  127. int type = TOMOYO_TYPE_CREATE_ACL;
  128. switch (mode & S_IFMT) {
  129. case S_IFCHR:
  130. type = TOMOYO_TYPE_MKCHAR_ACL;
  131. break;
  132. case S_IFBLK:
  133. type = TOMOYO_TYPE_MKBLOCK_ACL;
  134. break;
  135. case S_IFIFO:
  136. type = TOMOYO_TYPE_MKFIFO_ACL;
  137. break;
  138. case S_IFSOCK:
  139. type = TOMOYO_TYPE_MKSOCK_ACL;
  140. break;
  141. }
  142. return tomoyo_check_1path_perm(tomoyo_domain(),
  143. type, &path);
  144. }
  145. static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
  146. struct dentry *new_dentry)
  147. {
  148. struct path path1 = { new_dir->mnt, old_dentry };
  149. struct path path2 = { new_dir->mnt, new_dentry };
  150. return tomoyo_check_2path_perm(tomoyo_domain(),
  151. TOMOYO_TYPE_LINK_ACL,
  152. &path1, &path2);
  153. }
  154. static int tomoyo_path_rename(struct path *old_parent,
  155. struct dentry *old_dentry,
  156. struct path *new_parent,
  157. struct dentry *new_dentry)
  158. {
  159. struct path path1 = { old_parent->mnt, old_dentry };
  160. struct path path2 = { new_parent->mnt, new_dentry };
  161. return tomoyo_check_2path_perm(tomoyo_domain(),
  162. TOMOYO_TYPE_RENAME_ACL,
  163. &path1, &path2);
  164. }
  165. static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
  166. unsigned long arg)
  167. {
  168. if (cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND))
  169. return tomoyo_check_rewrite_permission(tomoyo_domain(), file);
  170. return 0;
  171. }
  172. static int tomoyo_dentry_open(struct file *f, const struct cred *cred)
  173. {
  174. int flags = f->f_flags;
  175. if ((flags + 1) & O_ACCMODE)
  176. flags++;
  177. flags |= f->f_flags & (O_APPEND | O_TRUNC);
  178. /* Don't check read permission here if called from do_execve(). */
  179. if (current->in_execve)
  180. return 0;
  181. return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
  182. }
  183. static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
  184. unsigned long arg)
  185. {
  186. return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_IOCTL_ACL,
  187. &file->f_path);
  188. }
  189. static int tomoyo_path_chmod(struct dentry *dentry, struct vfsmount *mnt,
  190. mode_t mode)
  191. {
  192. struct path path = { mnt, dentry };
  193. return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_CHMOD_ACL,
  194. &path);
  195. }
  196. static int tomoyo_path_chown(struct path *path, uid_t uid, gid_t gid)
  197. {
  198. int error = 0;
  199. if (uid != (uid_t) -1)
  200. error = tomoyo_check_1path_perm(tomoyo_domain(),
  201. TOMOYO_TYPE_CHOWN_ACL, path);
  202. if (!error && gid != (gid_t) -1)
  203. error = tomoyo_check_1path_perm(tomoyo_domain(),
  204. TOMOYO_TYPE_CHGRP_ACL, path);
  205. return error;
  206. }
  207. static int tomoyo_path_chroot(struct path *path)
  208. {
  209. return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_CHROOT_ACL,
  210. path);
  211. }
  212. static int tomoyo_sb_mount(char *dev_name, struct path *path,
  213. char *type, unsigned long flags, void *data)
  214. {
  215. return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_MOUNT_ACL,
  216. path);
  217. }
  218. static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
  219. {
  220. struct path path = { mnt, mnt->mnt_root };
  221. return tomoyo_check_1path_perm(tomoyo_domain(), TOMOYO_TYPE_UMOUNT_ACL,
  222. &path);
  223. }
  224. static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
  225. {
  226. return tomoyo_check_2path_perm(tomoyo_domain(),
  227. TOMOYO_TYPE_PIVOT_ROOT_ACL,
  228. new_path, old_path);
  229. }
  230. /*
  231. * tomoyo_security_ops is a "struct security_operations" which is used for
  232. * registering TOMOYO.
  233. */
  234. static struct security_operations tomoyo_security_ops = {
  235. .name = "tomoyo",
  236. .cred_alloc_blank = tomoyo_cred_alloc_blank,
  237. .cred_prepare = tomoyo_cred_prepare,
  238. .cred_transfer = tomoyo_cred_transfer,
  239. .bprm_set_creds = tomoyo_bprm_set_creds,
  240. .bprm_check_security = tomoyo_bprm_check_security,
  241. .file_fcntl = tomoyo_file_fcntl,
  242. .dentry_open = tomoyo_dentry_open,
  243. .path_truncate = tomoyo_path_truncate,
  244. .path_unlink = tomoyo_path_unlink,
  245. .path_mkdir = tomoyo_path_mkdir,
  246. .path_rmdir = tomoyo_path_rmdir,
  247. .path_symlink = tomoyo_path_symlink,
  248. .path_mknod = tomoyo_path_mknod,
  249. .path_link = tomoyo_path_link,
  250. .path_rename = tomoyo_path_rename,
  251. .file_ioctl = tomoyo_file_ioctl,
  252. .path_chmod = tomoyo_path_chmod,
  253. .path_chown = tomoyo_path_chown,
  254. .path_chroot = tomoyo_path_chroot,
  255. .sb_mount = tomoyo_sb_mount,
  256. .sb_umount = tomoyo_sb_umount,
  257. .sb_pivotroot = tomoyo_sb_pivotroot,
  258. };
  259. /* Lock for GC. */
  260. struct srcu_struct tomoyo_ss;
  261. static int __init tomoyo_init(void)
  262. {
  263. struct cred *cred = (struct cred *) current_cred();
  264. if (!security_module_enable(&tomoyo_security_ops))
  265. return 0;
  266. /* register ourselves with the security framework */
  267. if (register_security(&tomoyo_security_ops) ||
  268. init_srcu_struct(&tomoyo_ss))
  269. panic("Failure registering TOMOYO Linux");
  270. printk(KERN_INFO "TOMOYO Linux initialized\n");
  271. cred->security = &tomoyo_kernel_domain;
  272. tomoyo_realpath_init();
  273. return 0;
  274. }
  275. security_initcall(tomoyo_init);