linux/security/tomoyo/tomoyo.c
<<
>>
Prefs
   1/*
   2 * security/tomoyo/tomoyo.c
   3 *
   4 * Copyright (C) 2005-2011  NTT DATA CORPORATION
   5 */
   6
   7#include <linux/security.h>
   8#include "common.h"
   9
  10/**
  11 * tomoyo_cred_alloc_blank - Target for security_cred_alloc_blank().
  12 *
  13 * @new: Pointer to "struct cred".
  14 * @gfp: Memory allocation flags.
  15 *
  16 * Returns 0.
  17 */
  18static int tomoyo_cred_alloc_blank(struct cred *new, gfp_t gfp)
  19{
  20        new->security = NULL;
  21        return 0;
  22}
  23
  24/**
  25 * tomoyo_cred_prepare - Target for security_prepare_creds().
  26 *
  27 * @new: Pointer to "struct cred".
  28 * @old: Pointer to "struct cred".
  29 * @gfp: Memory allocation flags.
  30 *
  31 * Returns 0.
  32 */
  33static int tomoyo_cred_prepare(struct cred *new, const struct cred *old,
  34                               gfp_t gfp)
  35{
  36        struct tomoyo_domain_info *domain = old->security;
  37        new->security = domain;
  38        if (domain)
  39                atomic_inc(&domain->users);
  40        return 0;
  41}
  42
  43/**
  44 * tomoyo_cred_transfer - Target for security_transfer_creds().
  45 *
  46 * @new: Pointer to "struct cred".
  47 * @old: Pointer to "struct cred".
  48 */
  49static void tomoyo_cred_transfer(struct cred *new, const struct cred *old)
  50{
  51        tomoyo_cred_prepare(new, old, 0);
  52}
  53
  54/**
  55 * tomoyo_cred_free - Target for security_cred_free().
  56 *
  57 * @cred: Pointer to "struct cred".
  58 */
  59static void tomoyo_cred_free(struct cred *cred)
  60{
  61        struct tomoyo_domain_info *domain = cred->security;
  62        if (domain)
  63                atomic_dec(&domain->users);
  64}
  65
  66/**
  67 * tomoyo_bprm_set_creds - Target for security_bprm_set_creds().
  68 *
  69 * @bprm: Pointer to "struct linux_binprm".
  70 *
  71 * Returns 0 on success, negative value otherwise.
  72 */
  73static int tomoyo_bprm_set_creds(struct linux_binprm *bprm)
  74{
  75        int rc;
  76
  77        rc = cap_bprm_set_creds(bprm);
  78        if (rc)
  79                return rc;
  80
  81        /*
  82         * Do only if this function is called for the first time of an execve
  83         * operation.
  84         */
  85        if (bprm->cred_prepared)
  86                return 0;
  87#ifndef CONFIG_SECURITY_TOMOYO_OMIT_USERSPACE_LOADER
  88        /*
  89         * Load policy if /sbin/tomoyo-init exists and /sbin/init is requested
  90         * for the first time.
  91         */
  92        if (!tomoyo_policy_loaded)
  93                tomoyo_load_policy(bprm->filename);
  94#endif
  95        /*
  96         * Release reference to "struct tomoyo_domain_info" stored inside
  97         * "bprm->cred->security". New reference to "struct tomoyo_domain_info"
  98         * stored inside "bprm->cred->security" will be acquired later inside
  99         * tomoyo_find_next_domain().
 100         */
 101        atomic_dec(&((struct tomoyo_domain_info *)
 102                     bprm->cred->security)->users);
 103        /*
 104         * Tell tomoyo_bprm_check_security() is called for the first time of an
 105         * execve operation.
 106         */
 107        bprm->cred->security = NULL;
 108        return 0;
 109}
 110
 111/**
 112 * tomoyo_bprm_check_security - Target for security_bprm_check().
 113 *
 114 * @bprm: Pointer to "struct linux_binprm".
 115 *
 116 * Returns 0 on success, negative value otherwise.
 117 */
 118static int tomoyo_bprm_check_security(struct linux_binprm *bprm)
 119{
 120        struct tomoyo_domain_info *domain = bprm->cred->security;
 121
 122        /*
 123         * Execute permission is checked against pathname passed to do_execve()
 124         * using current domain.
 125         */
 126        if (!domain) {
 127                const int idx = tomoyo_read_lock();
 128                const int err = tomoyo_find_next_domain(bprm);
 129                tomoyo_read_unlock(idx);
 130                return err;
 131        }
 132        /*
 133         * Read permission is checked against interpreters using next domain.
 134         */
 135        return tomoyo_check_open_permission(domain, &bprm->file->f_path,
 136                                            O_RDONLY);
 137}
 138
 139/**
 140 * tomoyo_inode_getattr - Target for security_inode_getattr().
 141 *
 142 * @mnt:    Pointer to "struct vfsmount".
 143 * @dentry: Pointer to "struct dentry".
 144 *
 145 * Returns 0 on success, negative value otherwise.
 146 */
 147static int tomoyo_inode_getattr(struct vfsmount *mnt, struct dentry *dentry)
 148{
 149        struct path path = { mnt, dentry };
 150        return tomoyo_path_perm(TOMOYO_TYPE_GETATTR, &path, NULL);
 151}
 152
 153/**
 154 * tomoyo_path_truncate - Target for security_path_truncate().
 155 *
 156 * @path: Pointer to "struct path".
 157 *
 158 * Returns 0 on success, negative value otherwise.
 159 */
 160static int tomoyo_path_truncate(struct path *path)
 161{
 162        return tomoyo_path_perm(TOMOYO_TYPE_TRUNCATE, path, NULL);
 163}
 164
 165/**
 166 * tomoyo_path_unlink - Target for security_path_unlink().
 167 *
 168 * @parent: Pointer to "struct path".
 169 * @dentry: Pointer to "struct dentry".
 170 *
 171 * Returns 0 on success, negative value otherwise.
 172 */
 173static int tomoyo_path_unlink(struct path *parent, struct dentry *dentry)
 174{
 175        struct path path = { parent->mnt, dentry };
 176        return tomoyo_path_perm(TOMOYO_TYPE_UNLINK, &path, NULL);
 177}
 178
 179/**
 180 * tomoyo_path_mkdir - Target for security_path_mkdir().
 181 *
 182 * @parent: Pointer to "struct path".
 183 * @dentry: Pointer to "struct dentry".
 184 * @mode:   DAC permission mode.
 185 *
 186 * Returns 0 on success, negative value otherwise.
 187 */
 188static int tomoyo_path_mkdir(struct path *parent, struct dentry *dentry,
 189                             umode_t mode)
 190{
 191        struct path path = { parent->mnt, dentry };
 192        return tomoyo_path_number_perm(TOMOYO_TYPE_MKDIR, &path,
 193                                       mode & S_IALLUGO);
 194}
 195
 196/**
 197 * tomoyo_path_rmdir - Target for security_path_rmdir().
 198 *
 199 * @parent: Pointer to "struct path".
 200 * @dentry: Pointer to "struct dentry".
 201 *
 202 * Returns 0 on success, negative value otherwise.
 203 */
 204static int tomoyo_path_rmdir(struct path *parent, struct dentry *dentry)
 205{
 206        struct path path = { parent->mnt, dentry };
 207        return tomoyo_path_perm(TOMOYO_TYPE_RMDIR, &path, NULL);
 208}
 209
 210/**
 211 * tomoyo_path_symlink - Target for security_path_symlink().
 212 *
 213 * @parent:   Pointer to "struct path".
 214 * @dentry:   Pointer to "struct dentry".
 215 * @old_name: Symlink's content.
 216 *
 217 * Returns 0 on success, negative value otherwise.
 218 */
 219static int tomoyo_path_symlink(struct path *parent, struct dentry *dentry,
 220                               const char *old_name)
 221{
 222        struct path path = { parent->mnt, dentry };
 223        return tomoyo_path_perm(TOMOYO_TYPE_SYMLINK, &path, old_name);
 224}
 225
 226/**
 227 * tomoyo_path_mknod - Target for security_path_mknod().
 228 *
 229 * @parent: Pointer to "struct path".
 230 * @dentry: Pointer to "struct dentry".
 231 * @mode:   DAC permission mode.
 232 * @dev:    Device attributes.
 233 *
 234 * Returns 0 on success, negative value otherwise.
 235 */
 236static int tomoyo_path_mknod(struct path *parent, struct dentry *dentry,
 237                             umode_t mode, unsigned int dev)
 238{
 239        struct path path = { parent->mnt, dentry };
 240        int type = TOMOYO_TYPE_CREATE;
 241        const unsigned int perm = mode & S_IALLUGO;
 242
 243        switch (mode & S_IFMT) {
 244        case S_IFCHR:
 245                type = TOMOYO_TYPE_MKCHAR;
 246                break;
 247        case S_IFBLK:
 248                type = TOMOYO_TYPE_MKBLOCK;
 249                break;
 250        default:
 251                goto no_dev;
 252        }
 253        return tomoyo_mkdev_perm(type, &path, perm, dev);
 254 no_dev:
 255        switch (mode & S_IFMT) {
 256        case S_IFIFO:
 257                type = TOMOYO_TYPE_MKFIFO;
 258                break;
 259        case S_IFSOCK:
 260                type = TOMOYO_TYPE_MKSOCK;
 261                break;
 262        }
 263        return tomoyo_path_number_perm(type, &path, perm);
 264}
 265
 266/**
 267 * tomoyo_path_link - Target for security_path_link().
 268 *
 269 * @old_dentry: Pointer to "struct dentry".
 270 * @new_dir:    Pointer to "struct path".
 271 * @new_dentry: Pointer to "struct dentry".
 272 *
 273 * Returns 0 on success, negative value otherwise.
 274 */
 275static int tomoyo_path_link(struct dentry *old_dentry, struct path *new_dir,
 276                            struct dentry *new_dentry)
 277{
 278        struct path path1 = { new_dir->mnt, old_dentry };
 279        struct path path2 = { new_dir->mnt, new_dentry };
 280        return tomoyo_path2_perm(TOMOYO_TYPE_LINK, &path1, &path2);
 281}
 282
 283/**
 284 * tomoyo_path_rename - Target for security_path_rename().
 285 *
 286 * @old_parent: Pointer to "struct path".
 287 * @old_dentry: Pointer to "struct dentry".
 288 * @new_parent: Pointer to "struct path".
 289 * @new_dentry: Pointer to "struct dentry".
 290 *
 291 * Returns 0 on success, negative value otherwise.
 292 */
 293static int tomoyo_path_rename(struct path *old_parent,
 294                              struct dentry *old_dentry,
 295                              struct path *new_parent,
 296                              struct dentry *new_dentry)
 297{
 298        struct path path1 = { old_parent->mnt, old_dentry };
 299        struct path path2 = { new_parent->mnt, new_dentry };
 300        return tomoyo_path2_perm(TOMOYO_TYPE_RENAME, &path1, &path2);
 301}
 302
 303/**
 304 * tomoyo_file_fcntl - Target for security_file_fcntl().
 305 *
 306 * @file: Pointer to "struct file".
 307 * @cmd:  Command for fcntl().
 308 * @arg:  Argument for @cmd.
 309 *
 310 * Returns 0 on success, negative value otherwise.
 311 */
 312static int tomoyo_file_fcntl(struct file *file, unsigned int cmd,
 313                             unsigned long arg)
 314{
 315        if (!(cmd == F_SETFL && ((arg ^ file->f_flags) & O_APPEND)))
 316                return 0;
 317        return tomoyo_check_open_permission(tomoyo_domain(), &file->f_path,
 318                                            O_WRONLY | (arg & O_APPEND));
 319}
 320
 321/**
 322 * tomoyo_file_open - Target for security_file_open().
 323 *
 324 * @f:    Pointer to "struct file".
 325 * @cred: Pointer to "struct cred".
 326 *
 327 * Returns 0 on success, negative value otherwise.
 328 */
 329static int tomoyo_file_open(struct file *f, const struct cred *cred)
 330{
 331        int flags = f->f_flags;
 332        /* Don't check read permission here if called from do_execve(). */
 333        if (current->in_execve)
 334                return 0;
 335        return tomoyo_check_open_permission(tomoyo_domain(), &f->f_path, flags);
 336}
 337
 338/**
 339 * tomoyo_file_ioctl - Target for security_file_ioctl().
 340 *
 341 * @file: Pointer to "struct file".
 342 * @cmd:  Command for ioctl().
 343 * @arg:  Argument for @cmd.
 344 *
 345 * Returns 0 on success, negative value otherwise.
 346 */
 347static int tomoyo_file_ioctl(struct file *file, unsigned int cmd,
 348                             unsigned long arg)
 349{
 350        return tomoyo_path_number_perm(TOMOYO_TYPE_IOCTL, &file->f_path, cmd);
 351}
 352
 353/**
 354 * tomoyo_path_chmod - Target for security_path_chmod().
 355 *
 356 * @path: Pointer to "struct path".
 357 * @mode: DAC permission mode.
 358 *
 359 * Returns 0 on success, negative value otherwise.
 360 */
 361static int tomoyo_path_chmod(struct path *path, umode_t mode)
 362{
 363        return tomoyo_path_number_perm(TOMOYO_TYPE_CHMOD, path,
 364                                       mode & S_IALLUGO);
 365}
 366
 367/**
 368 * tomoyo_path_chown - Target for security_path_chown().
 369 *
 370 * @path: Pointer to "struct path".
 371 * @uid:  Owner ID.
 372 * @gid:  Group ID.
 373 *
 374 * Returns 0 on success, negative value otherwise.
 375 */
 376static int tomoyo_path_chown(struct path *path, kuid_t uid, kgid_t gid)
 377{
 378        int error = 0;
 379        if (uid_valid(uid))
 380                error = tomoyo_path_number_perm(TOMOYO_TYPE_CHOWN, path,
 381                                                from_kuid(&init_user_ns, uid));
 382        if (!error && gid_valid(gid))
 383                error = tomoyo_path_number_perm(TOMOYO_TYPE_CHGRP, path,
 384                                                from_kgid(&init_user_ns, gid));
 385        return error;
 386}
 387
 388/**
 389 * tomoyo_path_chroot - Target for security_path_chroot().
 390 *
 391 * @path: Pointer to "struct path".
 392 *
 393 * Returns 0 on success, negative value otherwise.
 394 */
 395static int tomoyo_path_chroot(struct path *path)
 396{
 397        return tomoyo_path_perm(TOMOYO_TYPE_CHROOT, path, NULL);
 398}
 399
 400/**
 401 * tomoyo_sb_mount - Target for security_sb_mount().
 402 *
 403 * @dev_name: Name of device file. Maybe NULL.
 404 * @path:     Pointer to "struct path".
 405 * @type:     Name of filesystem type. Maybe NULL.
 406 * @flags:    Mount options.
 407 * @data:     Optional data. Maybe NULL.
 408 *
 409 * Returns 0 on success, negative value otherwise.
 410 */
 411static int tomoyo_sb_mount(const char *dev_name, struct path *path,
 412                           const char *type, unsigned long flags, void *data)
 413{
 414        return tomoyo_mount_permission(dev_name, path, type, flags, data);
 415}
 416
 417/**
 418 * tomoyo_sb_umount - Target for security_sb_umount().
 419 *
 420 * @mnt:   Pointer to "struct vfsmount".
 421 * @flags: Unmount options.
 422 *
 423 * Returns 0 on success, negative value otherwise.
 424 */
 425static int tomoyo_sb_umount(struct vfsmount *mnt, int flags)
 426{
 427        struct path path = { mnt, mnt->mnt_root };
 428        return tomoyo_path_perm(TOMOYO_TYPE_UMOUNT, &path, NULL);
 429}
 430
 431/**
 432 * tomoyo_sb_pivotroot - Target for security_sb_pivotroot().
 433 *
 434 * @old_path: Pointer to "struct path".
 435 * @new_path: Pointer to "struct path".
 436 *
 437 * Returns 0 on success, negative value otherwise.
 438 */
 439static int tomoyo_sb_pivotroot(struct path *old_path, struct path *new_path)
 440{
 441        return tomoyo_path2_perm(TOMOYO_TYPE_PIVOT_ROOT, new_path, old_path);
 442}
 443
 444/**
 445 * tomoyo_socket_listen - Check permission for listen().
 446 *
 447 * @sock:    Pointer to "struct socket".
 448 * @backlog: Backlog parameter.
 449 *
 450 * Returns 0 on success, negative value otherwise.
 451 */
 452static int tomoyo_socket_listen(struct socket *sock, int backlog)
 453{
 454        return tomoyo_socket_listen_permission(sock);
 455}
 456
 457/**
 458 * tomoyo_socket_connect - Check permission for connect().
 459 *
 460 * @sock:     Pointer to "struct socket".
 461 * @addr:     Pointer to "struct sockaddr".
 462 * @addr_len: Size of @addr.
 463 *
 464 * Returns 0 on success, negative value otherwise.
 465 */
 466static int tomoyo_socket_connect(struct socket *sock, struct sockaddr *addr,
 467                                 int addr_len)
 468{
 469        return tomoyo_socket_connect_permission(sock, addr, addr_len);
 470}
 471
 472/**
 473 * tomoyo_socket_bind - Check permission for bind().
 474 *
 475 * @sock:     Pointer to "struct socket".
 476 * @addr:     Pointer to "struct sockaddr".
 477 * @addr_len: Size of @addr.
 478 *
 479 * Returns 0 on success, negative value otherwise.
 480 */
 481static int tomoyo_socket_bind(struct socket *sock, struct sockaddr *addr,
 482                              int addr_len)
 483{
 484        return tomoyo_socket_bind_permission(sock, addr, addr_len);
 485}
 486
 487/**
 488 * tomoyo_socket_sendmsg - Check permission for sendmsg().
 489 *
 490 * @sock: Pointer to "struct socket".
 491 * @msg:  Pointer to "struct msghdr".
 492 * @size: Size of message.
 493 *
 494 * Returns 0 on success, negative value otherwise.
 495 */
 496static int tomoyo_socket_sendmsg(struct socket *sock, struct msghdr *msg,
 497                                 int size)
 498{
 499        return tomoyo_socket_sendmsg_permission(sock, msg, size);
 500}
 501
 502/*
 503 * tomoyo_security_ops is a "struct security_operations" which is used for
 504 * registering TOMOYO.
 505 */
 506static struct security_operations tomoyo_security_ops = {
 507        .name                = "tomoyo",
 508        .cred_alloc_blank    = tomoyo_cred_alloc_blank,
 509        .cred_prepare        = tomoyo_cred_prepare,
 510        .cred_transfer       = tomoyo_cred_transfer,
 511        .cred_free           = tomoyo_cred_free,
 512        .bprm_set_creds      = tomoyo_bprm_set_creds,
 513        .bprm_check_security = tomoyo_bprm_check_security,
 514        .file_fcntl          = tomoyo_file_fcntl,
 515        .file_open           = tomoyo_file_open,
 516        .path_truncate       = tomoyo_path_truncate,
 517        .path_unlink         = tomoyo_path_unlink,
 518        .path_mkdir          = tomoyo_path_mkdir,
 519        .path_rmdir          = tomoyo_path_rmdir,
 520        .path_symlink        = tomoyo_path_symlink,
 521        .path_mknod          = tomoyo_path_mknod,
 522        .path_link           = tomoyo_path_link,
 523        .path_rename         = tomoyo_path_rename,
 524        .inode_getattr       = tomoyo_inode_getattr,
 525        .file_ioctl          = tomoyo_file_ioctl,
 526        .path_chmod          = tomoyo_path_chmod,
 527        .path_chown          = tomoyo_path_chown,
 528        .path_chroot         = tomoyo_path_chroot,
 529        .sb_mount            = tomoyo_sb_mount,
 530        .sb_umount           = tomoyo_sb_umount,
 531        .sb_pivotroot        = tomoyo_sb_pivotroot,
 532        .socket_bind         = tomoyo_socket_bind,
 533        .socket_connect      = tomoyo_socket_connect,
 534        .socket_listen       = tomoyo_socket_listen,
 535        .socket_sendmsg      = tomoyo_socket_sendmsg,
 536};
 537
 538/* Lock for GC. */
 539DEFINE_SRCU(tomoyo_ss);
 540
 541/**
 542 * tomoyo_init - Register TOMOYO Linux as a LSM module.
 543 *
 544 * Returns 0.
 545 */
 546static int __init tomoyo_init(void)
 547{
 548        struct cred *cred = (struct cred *) current_cred();
 549
 550        if (!security_module_enable(&tomoyo_security_ops))
 551                return 0;
 552        /* register ourselves with the security framework */
 553        if (register_security(&tomoyo_security_ops))
 554                panic("Failure registering TOMOYO Linux");
 555        printk(KERN_INFO "TOMOYO Linux initialized\n");
 556        cred->security = &tomoyo_kernel_domain;
 557        tomoyo_mm_init();
 558        return 0;
 559}
 560
 561security_initcall(tomoyo_init);
 562