^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * security/tomoyo/file.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 2005-2011 NTT DATA CORPORATION
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include "common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Mapping table from "enum tomoyo_path_acl_index" to "enum tomoyo_mac_index".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) static const u8 tomoyo_p2mac[TOMOYO_MAX_PATH_OPERATION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) [TOMOYO_TYPE_EXECUTE] = TOMOYO_MAC_FILE_EXECUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) [TOMOYO_TYPE_READ] = TOMOYO_MAC_FILE_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) [TOMOYO_TYPE_WRITE] = TOMOYO_MAC_FILE_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) [TOMOYO_TYPE_APPEND] = TOMOYO_MAC_FILE_OPEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) [TOMOYO_TYPE_UNLINK] = TOMOYO_MAC_FILE_UNLINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) [TOMOYO_TYPE_GETATTR] = TOMOYO_MAC_FILE_GETATTR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) [TOMOYO_TYPE_RMDIR] = TOMOYO_MAC_FILE_RMDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) [TOMOYO_TYPE_TRUNCATE] = TOMOYO_MAC_FILE_TRUNCATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) [TOMOYO_TYPE_SYMLINK] = TOMOYO_MAC_FILE_SYMLINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) [TOMOYO_TYPE_CHROOT] = TOMOYO_MAC_FILE_CHROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) [TOMOYO_TYPE_UMOUNT] = TOMOYO_MAC_FILE_UMOUNT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * Mapping table from "enum tomoyo_mkdev_acl_index" to "enum tomoyo_mac_index".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) const u8 tomoyo_pnnn2mac[TOMOYO_MAX_MKDEV_OPERATION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) [TOMOYO_TYPE_MKBLOCK] = TOMOYO_MAC_FILE_MKBLOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) [TOMOYO_TYPE_MKCHAR] = TOMOYO_MAC_FILE_MKCHAR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * Mapping table from "enum tomoyo_path2_acl_index" to "enum tomoyo_mac_index".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) const u8 tomoyo_pp2mac[TOMOYO_MAX_PATH2_OPERATION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) [TOMOYO_TYPE_LINK] = TOMOYO_MAC_FILE_LINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) [TOMOYO_TYPE_RENAME] = TOMOYO_MAC_FILE_RENAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) [TOMOYO_TYPE_PIVOT_ROOT] = TOMOYO_MAC_FILE_PIVOT_ROOT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * Mapping table from "enum tomoyo_path_number_acl_index" to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * "enum tomoyo_mac_index".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) const u8 tomoyo_pn2mac[TOMOYO_MAX_PATH_NUMBER_OPERATION] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) [TOMOYO_TYPE_CREATE] = TOMOYO_MAC_FILE_CREATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) [TOMOYO_TYPE_MKDIR] = TOMOYO_MAC_FILE_MKDIR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) [TOMOYO_TYPE_MKFIFO] = TOMOYO_MAC_FILE_MKFIFO,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) [TOMOYO_TYPE_MKSOCK] = TOMOYO_MAC_FILE_MKSOCK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) [TOMOYO_TYPE_IOCTL] = TOMOYO_MAC_FILE_IOCTL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) [TOMOYO_TYPE_CHMOD] = TOMOYO_MAC_FILE_CHMOD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) [TOMOYO_TYPE_CHOWN] = TOMOYO_MAC_FILE_CHOWN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) [TOMOYO_TYPE_CHGRP] = TOMOYO_MAC_FILE_CHGRP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * tomoyo_put_name_union - Drop reference on "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) * @ptr: Pointer to "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) void tomoyo_put_name_union(struct tomoyo_name_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) tomoyo_put_group(ptr->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) tomoyo_put_name(ptr->filename);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * tomoyo_compare_name_union - Check whether a name matches "struct tomoyo_name_union" or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) * @name: Pointer to "struct tomoyo_path_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) * @ptr: Pointer to "struct tomoyo_name_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) * Returns "struct tomoyo_path_info" if @name matches @ptr, NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) const struct tomoyo_path_info *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) tomoyo_compare_name_union(const struct tomoyo_path_info *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) const struct tomoyo_name_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) if (ptr->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return tomoyo_path_matches_group(name, ptr->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (tomoyo_path_matches_pattern(name, ptr->filename))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) return ptr->filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * tomoyo_put_number_union - Drop reference on "struct tomoyo_number_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * @ptr: Pointer to "struct tomoyo_number_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) void tomoyo_put_number_union(struct tomoyo_number_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) tomoyo_put_group(ptr->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) * tomoyo_compare_number_union - Check whether a value matches "struct tomoyo_number_union" or not.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) * @value: Number to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) * @ptr: Pointer to "struct tomoyo_number_union".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) * Returns true if @value matches @ptr, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) bool tomoyo_compare_number_union(const unsigned long value,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) const struct tomoyo_number_union *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (ptr->group)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) return tomoyo_number_matches_group(value, value, ptr->group);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) return value >= ptr->values[0] && value <= ptr->values[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) * tomoyo_add_slash - Add trailing '/' if needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * @buf: Pointer to "struct tomoyo_path_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * Returns nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * @buf must be generated by tomoyo_encode() because this function does not
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) * allocate memory for adding '/'.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) static void tomoyo_add_slash(struct tomoyo_path_info *buf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) if (buf->is_dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) * This is OK because tomoyo_encode() reserves space for appending "/".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) strcat((char *) buf->name, "/");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) tomoyo_fill_path_info(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * tomoyo_get_realpath - Get realpath.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * @buf: Pointer to "struct tomoyo_path_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * @path: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * Returns true on success, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static bool tomoyo_get_realpath(struct tomoyo_path_info *buf, const struct path *path)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) buf->name = tomoyo_realpath_from_path(path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) if (buf->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) tomoyo_fill_path_info(buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) * tomoyo_audit_path_log - Audit path request log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static int tomoyo_audit_path_log(struct tomoyo_request_info *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return tomoyo_supervisor(r, "file %s %s\n", tomoyo_path_keyword
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) [r->param.path.operation],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) r->param.path.filename->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * tomoyo_audit_path2_log - Audit path/path request log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) static int tomoyo_audit_path2_log(struct tomoyo_request_info *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) [tomoyo_pp2mac[r->param.path2.operation]],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) r->param.path2.filename1->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) r->param.path2.filename2->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * tomoyo_audit_mkdev_log - Audit path/number/number/number request log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) static int tomoyo_audit_mkdev_log(struct tomoyo_request_info *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return tomoyo_supervisor(r, "file %s %s 0%o %u %u\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) tomoyo_mac_keywords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) [tomoyo_pnnn2mac[r->param.mkdev.operation]],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) r->param.mkdev.filename->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) r->param.mkdev.mode, r->param.mkdev.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) r->param.mkdev.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * tomoyo_audit_path_number_log - Audit path/number request log.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) static int tomoyo_audit_path_number_log(struct tomoyo_request_info *r)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) const u8 type = r->param.path_number.operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) u8 radix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) char buffer[64];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) switch (type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) case TOMOYO_TYPE_CREATE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) case TOMOYO_TYPE_MKDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) case TOMOYO_TYPE_MKFIFO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) case TOMOYO_TYPE_MKSOCK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) case TOMOYO_TYPE_CHMOD:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) radix = TOMOYO_VALUE_TYPE_OCTAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) case TOMOYO_TYPE_IOCTL:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) radix = TOMOYO_VALUE_TYPE_HEXADECIMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) radix = TOMOYO_VALUE_TYPE_DECIMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) tomoyo_print_ulong(buffer, sizeof(buffer), r->param.path_number.number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) radix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) return tomoyo_supervisor(r, "file %s %s %s\n", tomoyo_mac_keywords
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) [tomoyo_pn2mac[type]],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) r->param.path_number.filename->name, buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) * tomoyo_check_path_acl - Check permission for path operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) * @ptr: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) * Returns true if granted, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * To be able to use wildcard for domain transition, this function sets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * matching entry on success. Since the caller holds tomoyo_read_lock(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * it is safe to set matching entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) static bool tomoyo_check_path_acl(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) const struct tomoyo_acl_info *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) const struct tomoyo_path_acl *acl = container_of(ptr, typeof(*acl),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) if (acl->perm & (1 << r->param.path.operation)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) r->param.path.matched_path =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) tomoyo_compare_name_union(r->param.path.filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) &acl->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) return r->param.path.matched_path != NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) * tomoyo_check_path_number_acl - Check permission for path number operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * @ptr: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * Returns true if granted, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) static bool tomoyo_check_path_number_acl(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) const struct tomoyo_acl_info *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) const struct tomoyo_path_number_acl *acl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) container_of(ptr, typeof(*acl), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return (acl->perm & (1 << r->param.path_number.operation)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) tomoyo_compare_number_union(r->param.path_number.number,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) &acl->number) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) tomoyo_compare_name_union(r->param.path_number.filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) &acl->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * tomoyo_check_path2_acl - Check permission for path path operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * @ptr: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) * Returns true if granted, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) static bool tomoyo_check_path2_acl(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) const struct tomoyo_acl_info *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) const struct tomoyo_path2_acl *acl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) container_of(ptr, typeof(*acl), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) return (acl->perm & (1 << r->param.path2.operation)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) tomoyo_compare_name_union(r->param.path2.filename1, &acl->name1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) && tomoyo_compare_name_union(r->param.path2.filename2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) &acl->name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * tomoyo_check_mkdev_acl - Check permission for path number number number operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * @ptr: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * Returns true if granted, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) static bool tomoyo_check_mkdev_acl(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) const struct tomoyo_acl_info *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) const struct tomoyo_mkdev_acl *acl =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) container_of(ptr, typeof(*acl), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) return (acl->perm & (1 << r->param.mkdev.operation)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) tomoyo_compare_number_union(r->param.mkdev.mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) &acl->mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) tomoyo_compare_number_union(r->param.mkdev.major,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) &acl->major) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) tomoyo_compare_number_union(r->param.mkdev.minor,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) &acl->minor) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) tomoyo_compare_name_union(r->param.mkdev.filename,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) &acl->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * tomoyo_same_path_acl - Check for duplicated "struct tomoyo_path_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) * Returns true if @a == @b except permission bits, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) static bool tomoyo_same_path_acl(const struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) const struct tomoyo_acl_info *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) const struct tomoyo_path_acl *p1 = container_of(a, typeof(*p1), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) const struct tomoyo_path_acl *p2 = container_of(b, typeof(*p2), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) return tomoyo_same_name_union(&p1->name, &p2->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) * tomoyo_merge_path_acl - Merge duplicated "struct tomoyo_path_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) * @is_delete: True for @a &= ~@b, false for @a |= @b.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) * Returns true if @a is empty, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) static bool tomoyo_merge_path_acl(struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) struct tomoyo_acl_info *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) const bool is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) u16 * const a_perm = &container_of(a, struct tomoyo_path_acl, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) ->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) u16 perm = READ_ONCE(*a_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) const u16 b_perm = container_of(b, struct tomoyo_path_acl, head)->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) if (is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) perm &= ~b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) perm |= b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) WRITE_ONCE(*a_perm, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) return !perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) * tomoyo_update_path_acl - Update "struct tomoyo_path_acl" list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) * @perm: Permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) static int tomoyo_update_path_acl(const u16 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) struct tomoyo_path_acl e = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) .head.type = TOMOYO_TYPE_PATH_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) .perm = perm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (!tomoyo_parse_name_union(param, &e.name))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) error = tomoyo_update_domain(&e.head, sizeof(e), param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) tomoyo_same_path_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) tomoyo_merge_path_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) tomoyo_put_name_union(&e.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) * tomoyo_same_mkdev_acl - Check for duplicated "struct tomoyo_mkdev_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) * Returns true if @a == @b except permission bits, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) static bool tomoyo_same_mkdev_acl(const struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) const struct tomoyo_acl_info *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) const struct tomoyo_mkdev_acl *p1 = container_of(a, typeof(*p1), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) const struct tomoyo_mkdev_acl *p2 = container_of(b, typeof(*p2), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) return tomoyo_same_name_union(&p1->name, &p2->name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) tomoyo_same_number_union(&p1->mode, &p2->mode) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) tomoyo_same_number_union(&p1->major, &p2->major) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) tomoyo_same_number_union(&p1->minor, &p2->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * tomoyo_merge_mkdev_acl - Merge duplicated "struct tomoyo_mkdev_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * @is_delete: True for @a &= ~@b, false for @a |= @b.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * Returns true if @a is empty, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) static bool tomoyo_merge_mkdev_acl(struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) struct tomoyo_acl_info *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) const bool is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) u8 *const a_perm = &container_of(a, struct tomoyo_mkdev_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) head)->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) u8 perm = READ_ONCE(*a_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) const u8 b_perm = container_of(b, struct tomoyo_mkdev_acl, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) if (is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) perm &= ~b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) perm |= b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) WRITE_ONCE(*a_perm, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) return !perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) * tomoyo_update_mkdev_acl - Update "struct tomoyo_mkdev_acl" list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) * @perm: Permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) static int tomoyo_update_mkdev_acl(const u8 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) struct tomoyo_mkdev_acl e = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) .head.type = TOMOYO_TYPE_MKDEV_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) .perm = perm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) if (!tomoyo_parse_name_union(param, &e.name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) !tomoyo_parse_number_union(param, &e.mode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) !tomoyo_parse_number_union(param, &e.major) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) !tomoyo_parse_number_union(param, &e.minor))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) error = tomoyo_update_domain(&e.head, sizeof(e), param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) tomoyo_same_mkdev_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) tomoyo_merge_mkdev_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) tomoyo_put_name_union(&e.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) tomoyo_put_number_union(&e.mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) tomoyo_put_number_union(&e.major);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) tomoyo_put_number_union(&e.minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) * tomoyo_same_path2_acl - Check for duplicated "struct tomoyo_path2_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) * Returns true if @a == @b except permission bits, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) static bool tomoyo_same_path2_acl(const struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) const struct tomoyo_acl_info *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) const struct tomoyo_path2_acl *p1 = container_of(a, typeof(*p1), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) const struct tomoyo_path2_acl *p2 = container_of(b, typeof(*p2), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) return tomoyo_same_name_union(&p1->name1, &p2->name1) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) tomoyo_same_name_union(&p1->name2, &p2->name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * tomoyo_merge_path2_acl - Merge duplicated "struct tomoyo_path2_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * @is_delete: True for @a &= ~@b, false for @a |= @b.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) * Returns true if @a is empty, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static bool tomoyo_merge_path2_acl(struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) struct tomoyo_acl_info *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) const bool is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) u8 * const a_perm = &container_of(a, struct tomoyo_path2_acl, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) ->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) u8 perm = READ_ONCE(*a_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) const u8 b_perm = container_of(b, struct tomoyo_path2_acl, head)->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) if (is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) perm &= ~b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) perm |= b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) WRITE_ONCE(*a_perm, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return !perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * tomoyo_update_path2_acl - Update "struct tomoyo_path2_acl" list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * @perm: Permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) static int tomoyo_update_path2_acl(const u8 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) struct tomoyo_path2_acl e = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) .head.type = TOMOYO_TYPE_PATH2_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) .perm = perm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) if (!tomoyo_parse_name_union(param, &e.name1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) !tomoyo_parse_name_union(param, &e.name2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) error = tomoyo_update_domain(&e.head, sizeof(e), param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) tomoyo_same_path2_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) tomoyo_merge_path2_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) tomoyo_put_name_union(&e.name1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) tomoyo_put_name_union(&e.name2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) * tomoyo_path_permission - Check permission for single path operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) * @operation: Type of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) * @filename: Filename to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) static int tomoyo_path_permission(struct tomoyo_request_info *r, u8 operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) const struct tomoyo_path_info *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) r->type = tomoyo_p2mac[operation];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) if (r->mode == TOMOYO_CONFIG_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) r->param_type = TOMOYO_TYPE_PATH_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) r->param.path.filename = filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) r->param.path.operation = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) tomoyo_check_acl(r, tomoyo_check_path_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) error = tomoyo_audit_path_log(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) } while (error == TOMOYO_RETRY_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) * tomoyo_execute_permission - Check permission for execute operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) * @r: Pointer to "struct tomoyo_request_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) * @filename: Filename to check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) int tomoyo_execute_permission(struct tomoyo_request_info *r,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) const struct tomoyo_path_info *filename)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) * Unlike other permission checks, this check is done regardless of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) * profile mode settings in order to check for domain transition
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) * preference.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) r->type = TOMOYO_MAC_FILE_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) r->mode = tomoyo_get_mode(r->domain->ns, r->profile, r->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) r->param_type = TOMOYO_TYPE_PATH_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) r->param.path.filename = filename;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) r->param.path.operation = TOMOYO_TYPE_EXECUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) tomoyo_check_acl(r, tomoyo_check_path_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) r->ee->transition = r->matched_acl && r->matched_acl->cond ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) r->matched_acl->cond->transit : NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) if (r->mode != TOMOYO_CONFIG_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) return tomoyo_audit_path_log(r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) * tomoyo_same_path_number_acl - Check for duplicated "struct tomoyo_path_number_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * Returns true if @a == @b except permission bits, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) static bool tomoyo_same_path_number_acl(const struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) const struct tomoyo_acl_info *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) const struct tomoyo_path_number_acl *p1 = container_of(a, typeof(*p1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) const struct tomoyo_path_number_acl *p2 = container_of(b, typeof(*p2),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) return tomoyo_same_name_union(&p1->name, &p2->name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) tomoyo_same_number_union(&p1->number, &p2->number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) * tomoyo_merge_path_number_acl - Merge duplicated "struct tomoyo_path_number_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) * @is_delete: True for @a &= ~@b, false for @a |= @b.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) * Returns true if @a is empty, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) static bool tomoyo_merge_path_number_acl(struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) struct tomoyo_acl_info *b,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) const bool is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) u8 * const a_perm = &container_of(a, struct tomoyo_path_number_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) head)->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) u8 perm = READ_ONCE(*a_perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) const u8 b_perm = container_of(b, struct tomoyo_path_number_acl, head)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ->perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (is_delete)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) perm &= ~b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) perm |= b_perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666) WRITE_ONCE(*a_perm, perm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) return !perm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) * tomoyo_update_path_number_acl - Update ioctl/chmod/chown/chgrp ACL.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) * @perm: Permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) static int tomoyo_update_path_number_acl(const u8 perm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) struct tomoyo_path_number_acl e = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) .head.type = TOMOYO_TYPE_PATH_NUMBER_ACL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) .perm = perm
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) if (!tomoyo_parse_name_union(param, &e.name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) !tomoyo_parse_number_union(param, &e.number))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) error = tomoyo_update_domain(&e.head, sizeof(e), param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) tomoyo_same_path_number_acl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) tomoyo_merge_path_number_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) tomoyo_put_name_union(&e.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) tomoyo_put_number_union(&e.number);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) * tomoyo_path_number_perm - Check permission for "create", "mkdir", "mkfifo", "mksock", "ioctl", "chmod", "chown", "chgrp".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) * @type: Type of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) * @path: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * @number: Number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) int tomoyo_path_number_perm(const u8 type, const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) unsigned long number)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) struct tomoyo_request_info r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) struct tomoyo_obj_info obj = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) .path1 = { .mnt = path->mnt, .dentry = path->dentry },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) struct tomoyo_path_info buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) if (tomoyo_init_request_info(&r, NULL, tomoyo_pn2mac[type])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) == TOMOYO_CONFIG_DISABLED || !path->dentry)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) idx = tomoyo_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) if (!tomoyo_get_realpath(&buf, path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) r.obj = &obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) if (type == TOMOYO_TYPE_MKDIR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) tomoyo_add_slash(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) r.param_type = TOMOYO_TYPE_PATH_NUMBER_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) r.param.path_number.operation = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) r.param.path_number.filename = &buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) r.param.path_number.number = number;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) tomoyo_check_acl(&r, tomoyo_check_path_number_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) error = tomoyo_audit_path_number_log(&r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) } while (error == TOMOYO_RETRY_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) kfree(buf.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) tomoyo_read_unlock(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739) if (r.mode != TOMOYO_CONFIG_ENFORCING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) * tomoyo_check_open_permission - Check permission for "read" and "write".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) * @domain: Pointer to "struct tomoyo_domain_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) * @path: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) * @flag: Flags for open().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) int tomoyo_check_open_permission(struct tomoyo_domain_info *domain,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) const struct path *path, const int flag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) const u8 acc_mode = ACC_MODE(flag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) int error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) struct tomoyo_path_info buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) struct tomoyo_request_info r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) struct tomoyo_obj_info obj = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) .path1 = { .mnt = path->mnt, .dentry = path->dentry },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) buf.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) r.mode = TOMOYO_CONFIG_DISABLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) idx = tomoyo_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) if (acc_mode &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) tomoyo_init_request_info(&r, domain, TOMOYO_MAC_FILE_OPEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) != TOMOYO_CONFIG_DISABLED) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) if (!tomoyo_get_realpath(&buf, path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) r.obj = &obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776) if (acc_mode & MAY_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) error = tomoyo_path_permission(&r, TOMOYO_TYPE_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) if (!error && (acc_mode & MAY_WRITE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) error = tomoyo_path_permission(&r, (flag & O_APPEND) ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) TOMOYO_TYPE_APPEND :
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) TOMOYO_TYPE_WRITE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) kfree(buf.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) tomoyo_read_unlock(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) if (r.mode != TOMOYO_CONFIG_ENFORCING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * tomoyo_path_perm - Check permission for "unlink", "rmdir", "truncate", "symlink", "append", "chroot" and "unmount".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) * @operation: Type of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * @path: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) * @target: Symlink's target if @operation is TOMOYO_TYPE_SYMLINK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) * NULL otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) int tomoyo_path_perm(const u8 operation, const struct path *path, const char *target)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) struct tomoyo_request_info r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) struct tomoyo_obj_info obj = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) .path1 = { .mnt = path->mnt, .dentry = path->dentry },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) struct tomoyo_path_info buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) bool is_enforce;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) struct tomoyo_path_info symlink_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) if (tomoyo_init_request_info(&r, NULL, tomoyo_p2mac[operation])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) == TOMOYO_CONFIG_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) is_enforce = (r.mode == TOMOYO_CONFIG_ENFORCING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) buf.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) idx = tomoyo_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) if (!tomoyo_get_realpath(&buf, path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) r.obj = &obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) switch (operation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) case TOMOYO_TYPE_RMDIR:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827) case TOMOYO_TYPE_CHROOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) tomoyo_add_slash(&buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) case TOMOYO_TYPE_SYMLINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) symlink_target.name = tomoyo_encode(target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) if (!symlink_target.name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) tomoyo_fill_path_info(&symlink_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) obj.symlink_target = &symlink_target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) error = tomoyo_path_permission(&r, operation, &buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) if (operation == TOMOYO_TYPE_SYMLINK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) kfree(symlink_target.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) kfree(buf.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) tomoyo_read_unlock(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) if (!is_enforce)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * tomoyo_mkdev_perm - Check permission for "mkblock" and "mkchar".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * @operation: Type of operation. (TOMOYO_TYPE_MKCHAR or TOMOYO_TYPE_MKBLOCK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * @path: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * @mode: Create mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) * @dev: Device number.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) int tomoyo_mkdev_perm(const u8 operation, const struct path *path,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) const unsigned int mode, unsigned int dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) struct tomoyo_request_info r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) struct tomoyo_obj_info obj = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) .path1 = { .mnt = path->mnt, .dentry = path->dentry },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) struct tomoyo_path_info buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) if (tomoyo_init_request_info(&r, NULL, tomoyo_pnnn2mac[operation])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) == TOMOYO_CONFIG_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) idx = tomoyo_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) if (tomoyo_get_realpath(&buf, path)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) r.obj = &obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) dev = new_decode_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) r.param_type = TOMOYO_TYPE_MKDEV_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) r.param.mkdev.filename = &buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) r.param.mkdev.operation = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) r.param.mkdev.mode = mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) r.param.mkdev.major = MAJOR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) r.param.mkdev.minor = MINOR(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) tomoyo_check_acl(&r, tomoyo_check_mkdev_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) error = tomoyo_audit_mkdev_log(&r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) kfree(buf.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) tomoyo_read_unlock(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) if (r.mode != TOMOYO_CONFIG_ENFORCING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * tomoyo_path2_perm - Check permission for "rename", "link" and "pivot_root".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) * @operation: Type of operation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) * @path1: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) * @path2: Pointer to "struct path".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) int tomoyo_path2_perm(const u8 operation, const struct path *path1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) const struct path *path2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) int error = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) struct tomoyo_path_info buf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) struct tomoyo_path_info buf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) struct tomoyo_request_info r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) struct tomoyo_obj_info obj = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) .path1 = { .mnt = path1->mnt, .dentry = path1->dentry },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) .path2 = { .mnt = path2->mnt, .dentry = path2->dentry }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (tomoyo_init_request_info(&r, NULL, tomoyo_pp2mac[operation])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) == TOMOYO_CONFIG_DISABLED)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) buf1.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) buf2.name = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) idx = tomoyo_read_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) if (!tomoyo_get_realpath(&buf1, path1) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) !tomoyo_get_realpath(&buf2, path2))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) switch (operation) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) case TOMOYO_TYPE_RENAME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) case TOMOYO_TYPE_LINK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) if (!d_is_dir(path1->dentry))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) case TOMOYO_TYPE_PIVOT_ROOT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) tomoyo_add_slash(&buf1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) tomoyo_add_slash(&buf2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) r.obj = &obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) r.param_type = TOMOYO_TYPE_PATH2_ACL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) r.param.path2.operation = operation;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) r.param.path2.filename1 = &buf1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) r.param.path2.filename2 = &buf2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) tomoyo_check_acl(&r, tomoyo_check_path2_acl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) error = tomoyo_audit_path2_log(&r);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) } while (error == TOMOYO_RETRY_REQUEST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) kfree(buf1.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) kfree(buf2.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) tomoyo_read_unlock(idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) if (r.mode != TOMOYO_CONFIG_ENFORCING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) error = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) * tomoyo_same_mount_acl - Check for duplicated "struct tomoyo_mount_acl" entry.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) * @a: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) * @b: Pointer to "struct tomoyo_acl_info".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) * Returns true if @a == @b, false otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) static bool tomoyo_same_mount_acl(const struct tomoyo_acl_info *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) const struct tomoyo_acl_info *b)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) const struct tomoyo_mount_acl *p1 = container_of(a, typeof(*p1), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) const struct tomoyo_mount_acl *p2 = container_of(b, typeof(*p2), head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) return tomoyo_same_name_union(&p1->dev_name, &p2->dev_name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) tomoyo_same_name_union(&p1->dir_name, &p2->dir_name) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) tomoyo_same_name_union(&p1->fs_type, &p2->fs_type) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) tomoyo_same_number_union(&p1->flags, &p2->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) * tomoyo_update_mount_acl - Write "struct tomoyo_mount_acl" list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) static int tomoyo_update_mount_acl(struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) struct tomoyo_mount_acl e = { .head.type = TOMOYO_TYPE_MOUNT_ACL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) int error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) if (!tomoyo_parse_name_union(param, &e.dev_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) !tomoyo_parse_name_union(param, &e.dir_name) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) !tomoyo_parse_name_union(param, &e.fs_type) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) !tomoyo_parse_number_union(param, &e.flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) error = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) error = tomoyo_update_domain(&e.head, sizeof(e), param,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) tomoyo_same_mount_acl, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) tomoyo_put_name_union(&e.dev_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) tomoyo_put_name_union(&e.dir_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) tomoyo_put_name_union(&e.fs_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) tomoyo_put_number_union(&e.flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) return error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) * tomoyo_write_file - Update file related list.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) * @param: Pointer to "struct tomoyo_acl_param".
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) * Returns 0 on success, negative value otherwise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) * Caller holds tomoyo_read_lock().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) int tomoyo_write_file(struct tomoyo_acl_param *param)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) u16 perm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) u8 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) const char *operation = tomoyo_read_token(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) for (type = 0; type < TOMOYO_MAX_PATH_OPERATION; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) if (tomoyo_permstr(operation, tomoyo_path_keyword[type]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) perm |= 1 << type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) if (perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) return tomoyo_update_path_acl(perm, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) for (type = 0; type < TOMOYO_MAX_PATH2_OPERATION; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) if (tomoyo_permstr(operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) tomoyo_mac_keywords[tomoyo_pp2mac[type]]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) perm |= 1 << type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) if (perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) return tomoyo_update_path2_acl(perm, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) for (type = 0; type < TOMOYO_MAX_PATH_NUMBER_OPERATION; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) if (tomoyo_permstr(operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) tomoyo_mac_keywords[tomoyo_pn2mac[type]]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) perm |= 1 << type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) if (perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) return tomoyo_update_path_number_acl(perm, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) for (type = 0; type < TOMOYO_MAX_MKDEV_OPERATION; type++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) if (tomoyo_permstr(operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) tomoyo_mac_keywords[tomoyo_pnnn2mac[type]]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) perm |= 1 << type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) if (perm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) return tomoyo_update_mkdev_acl(perm, param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) if (tomoyo_permstr(operation,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) tomoyo_mac_keywords[TOMOYO_MAC_FILE_MOUNT]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) return tomoyo_update_mount_acl(param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) }