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