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