1 /* 2 * security/tomoyo/realpath.c 3 * 4 * Get the canonicalized absolute pathnames. The basis for TOMOYO. 5 * 6 * Copyright (C) 2005-2009 NTT DATA CORPORATION 7 * 8 * Version: 2.2.0 2009/04/01 9 * 10 */ 11 12 #include <linux/types.h> 13 #include <linux/mount.h> 14 #include <linux/mnt_namespace.h> 15 #include <linux/fs_struct.h> 16 #include <linux/hash.h> 17 #include <linux/magic.h> 18 #include "common.h" 19 20 /** 21 * tomoyo_encode: Convert binary string to ascii string. 22 * 23 * @buffer: Buffer for ASCII string. 24 * @buflen: Size of @buffer. 25 * @str: Binary string. 26 * 27 * Returns 0 on success, -ENOMEM otherwise. 28 */ 29 int tomoyo_encode(char *buffer, int buflen, const char *str) 30 { 31 while (1) { 32 const unsigned char c = *(unsigned char *) str++; 33 34 if (tomoyo_is_valid(c)) { 35 if (--buflen <= 0) 36 break; 37 *buffer++ = (char) c; 38 if (c != '\\') 39 continue; 40 if (--buflen <= 0) 41 break; 42 *buffer++ = (char) c; 43 continue; 44 } 45 if (!c) { 46 if (--buflen <= 0) 47 break; 48 *buffer = '\0'; 49 return 0; 50 } 51 buflen -= 4; 52 if (buflen <= 0) 53 break; 54 *buffer++ = '\\'; 55 *buffer++ = (c >> 6) + '0'; 56 *buffer++ = ((c >> 3) & 7) + '0'; 57 *buffer++ = (c & 7) + '0'; 58 } 59 return -ENOMEM; 60 } 61 62 /** 63 * tomoyo_realpath_from_path2 - Returns realpath(3) of the given dentry but ignores chroot'ed root. 64 * 65 * @path: Pointer to "struct path". 66 * @newname: Pointer to buffer to return value in. 67 * @newname_len: Size of @newname. 68 * 69 * Returns 0 on success, negative value otherwise. 70 * 71 * If dentry is a directory, trailing '/' is appended. 72 * Characters out of 0x20 < c < 0x7F range are converted to 73 * \ooo style octal string. 74 * Character \ is converted to \\ string. 75 */ 76 int tomoyo_realpath_from_path2(struct path *path, char *newname, 77 int newname_len) 78 { 79 int error = -ENOMEM; 80 struct dentry *dentry = path->dentry; 81 char *sp; 82 83 if (!dentry || !path->mnt || !newname || newname_len <= 2048) 84 return -EINVAL; 85 if (dentry->d_op && dentry->d_op->d_dname) { 86 /* For "socket:[\$]" and "pipe:[\$]". */ 87 static const int offset = 1536; 88 sp = dentry->d_op->d_dname(dentry, newname + offset, 89 newname_len - offset); 90 } else { 91 struct path ns_root = {.mnt = NULL, .dentry = NULL}; 92 93 spin_lock(&dcache_lock); 94 /* go to whatever namespace root we are under */ 95 sp = __d_path(path, &ns_root, newname, newname_len); 96 spin_unlock(&dcache_lock); 97 /* Prepend "/proc" prefix if using internal proc vfs mount. */ 98 if (!IS_ERR(sp) && (path->mnt->mnt_flags & MNT_INTERNAL) && 99 (path->mnt->mnt_sb->s_magic == PROC_SUPER_MAGIC)) { 100 sp -= 5; 101 if (sp >= newname) 102 memcpy(sp, "/proc", 5); 103 else 104 sp = ERR_PTR(-ENOMEM); 105 } 106 } 107 if (IS_ERR(sp)) 108 error = PTR_ERR(sp); 109 else 110 error = tomoyo_encode(newname, sp - newname, sp); 111 /* Append trailing '/' if dentry is a directory. */ 112 if (!error && dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode) 113 && *newname) { 114 sp = newname + strlen(newname); 115 if (*(sp - 1) != '/') { 116 if (sp < newname + newname_len - 4) { 117 *sp++ = '/'; 118 *sp = '\0'; 119 } else { 120 error = -ENOMEM; 121 } 122 } 123 } 124 if (error) 125 printk(KERN_WARNING "tomoyo_realpath: Pathname too long.\n"); 126 return error; 127 } 128 129 /** 130 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. 131 * 132 * @path: Pointer to "struct path". 133 * 134 * Returns the realpath of the given @path on success, NULL otherwise. 135 * 136 * These functions use kzalloc(), so the caller must call kfree() 137 * if these functions didn't return NULL. 138 */ 139 char *tomoyo_realpath_from_path(struct path *path) 140 { 141 char *buf = kzalloc(sizeof(struct tomoyo_page_buffer), GFP_KERNEL); 142 143 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) 144 <= TOMOYO_MAX_PATHNAME_LEN - 1); 145 if (!buf) 146 return NULL; 147 if (tomoyo_realpath_from_path2(path, buf, 148 TOMOYO_MAX_PATHNAME_LEN - 1) == 0) 149 return buf; 150 kfree(buf); 151 return NULL; 152 } 153 154 /** 155 * tomoyo_realpath - Get realpath of a pathname. 156 * 157 * @pathname: The pathname to solve. 158 * 159 * Returns the realpath of @pathname on success, NULL otherwise. 160 */ 161 char *tomoyo_realpath(const char *pathname) 162 { 163 struct path path; 164 165 if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) { 166 char *buf = tomoyo_realpath_from_path(&path); 167 path_put(&path); 168 return buf; 169 } 170 return NULL; 171 } 172 173 /** 174 * tomoyo_realpath_nofollow - Get realpath of a pathname. 175 * 176 * @pathname: The pathname to solve. 177 * 178 * Returns the realpath of @pathname on success, NULL otherwise. 179 */ 180 char *tomoyo_realpath_nofollow(const char *pathname) 181 { 182 struct path path; 183 184 if (pathname && kern_path(pathname, 0, &path) == 0) { 185 char *buf = tomoyo_realpath_from_path(&path); 186 path_put(&path); 187 return buf; 188 } 189 return NULL; 190 } 191 192 /* Memory allocated for non-string data. */ 193 static atomic_t tomoyo_policy_memory_size; 194 /* Quota for holding policy. */ 195 static unsigned int tomoyo_quota_for_policy; 196 197 /** 198 * tomoyo_memory_ok - Check memory quota. 199 * 200 * @ptr: Pointer to allocated memory. 201 * 202 * Returns true on success, false otherwise. 203 * 204 * Caller holds tomoyo_policy_lock. 205 * Memory pointed by @ptr will be zeroed on success. 206 */ 207 bool tomoyo_memory_ok(void *ptr) 208 { 209 int allocated_len = ptr ? ksize(ptr) : 0; 210 atomic_add(allocated_len, &tomoyo_policy_memory_size); 211 if (ptr && (!tomoyo_quota_for_policy || 212 atomic_read(&tomoyo_policy_memory_size) 213 <= tomoyo_quota_for_policy)) { 214 memset(ptr, 0, allocated_len); 215 return true; 216 } 217 printk(KERN_WARNING "ERROR: Out of memory " 218 "for tomoyo_alloc_element().\n"); 219 if (!tomoyo_policy_loaded) 220 panic("MAC Initialization failed.\n"); 221 return false; 222 } 223 224 /** 225 * tomoyo_memory_free - Free memory for elements. 226 * 227 * @ptr: Pointer to allocated memory. 228 */ 229 void tomoyo_memory_free(void *ptr) 230 { 231 atomic_sub(ksize(ptr), &tomoyo_policy_memory_size); 232 kfree(ptr); 233 } 234 235 /* 236 * tomoyo_name_list is used for holding string data used by TOMOYO. 237 * Since same string data is likely used for multiple times (e.g. 238 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 239 * "const struct tomoyo_path_info *". 240 */ 241 struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 242 /* Lock for protecting tomoyo_name_list . */ 243 DEFINE_MUTEX(tomoyo_name_list_lock); 244 245 /** 246 * tomoyo_get_name - Allocate permanent memory for string data. 247 * 248 * @name: The string to store into the permernent memory. 249 * 250 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 251 */ 252 const struct tomoyo_path_info *tomoyo_get_name(const char *name) 253 { 254 struct tomoyo_name_entry *ptr; 255 unsigned int hash; 256 int len; 257 int allocated_len; 258 struct list_head *head; 259 260 if (!name) 261 return NULL; 262 len = strlen(name) + 1; 263 hash = full_name_hash((const unsigned char *) name, len - 1); 264 head = &tomoyo_name_list[hash_long(hash, TOMOYO_HASH_BITS)]; 265 mutex_lock(&tomoyo_name_list_lock); 266 list_for_each_entry(ptr, head, list) { 267 if (hash != ptr->entry.hash || strcmp(name, ptr->entry.name)) 268 continue; 269 atomic_inc(&ptr->users); 270 goto out; 271 } 272 ptr = kzalloc(sizeof(*ptr) + len, GFP_KERNEL); 273 allocated_len = ptr ? ksize(ptr) : 0; 274 if (!ptr || (tomoyo_quota_for_policy && 275 atomic_read(&tomoyo_policy_memory_size) + allocated_len 276 > tomoyo_quota_for_policy)) { 277 kfree(ptr); 278 printk(KERN_WARNING "ERROR: Out of memory " 279 "for tomoyo_get_name().\n"); 280 if (!tomoyo_policy_loaded) 281 panic("MAC Initialization failed.\n"); 282 ptr = NULL; 283 goto out; 284 } 285 atomic_add(allocated_len, &tomoyo_policy_memory_size); 286 ptr->entry.name = ((char *) ptr) + sizeof(*ptr); 287 memmove((char *) ptr->entry.name, name, len); 288 atomic_set(&ptr->users, 1); 289 tomoyo_fill_path_info(&ptr->entry); 290 list_add_tail(&ptr->list, head); 291 out: 292 mutex_unlock(&tomoyo_name_list_lock); 293 return ptr ? &ptr->entry : NULL; 294 } 295 296 /** 297 * tomoyo_realpath_init - Initialize realpath related code. 298 */ 299 void __init tomoyo_realpath_init(void) 300 { 301 int i; 302 303 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX); 304 for (i = 0; i < TOMOYO_MAX_HASH; i++) 305 INIT_LIST_HEAD(&tomoyo_name_list[i]); 306 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 307 tomoyo_kernel_domain.domainname = tomoyo_get_name(TOMOYO_ROOT_NAME); 308 /* 309 * tomoyo_read_lock() is not needed because this function is 310 * called before the first "delete" request. 311 */ 312 list_add_tail_rcu(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 313 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) 314 panic("Can't register tomoyo_kernel_domain"); 315 } 316 317 /** 318 * tomoyo_read_memory_counter - Check for memory usage in bytes. 319 * 320 * @head: Pointer to "struct tomoyo_io_buffer". 321 * 322 * Returns memory usage. 323 */ 324 int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 325 { 326 if (!head->read_eof) { 327 const unsigned int policy 328 = atomic_read(&tomoyo_policy_memory_size); 329 char buffer[64]; 330 331 memset(buffer, 0, sizeof(buffer)); 332 if (tomoyo_quota_for_policy) 333 snprintf(buffer, sizeof(buffer) - 1, 334 " (Quota: %10u)", 335 tomoyo_quota_for_policy); 336 else 337 buffer[0] = '\0'; 338 tomoyo_io_printf(head, "Policy: %10u%s\n", policy, buffer); 339 tomoyo_io_printf(head, "Total: %10u\n", policy); 340 head->read_eof = true; 341 } 342 return 0; 343 } 344 345 /** 346 * tomoyo_write_memory_quota - Set memory quota. 347 * 348 * @head: Pointer to "struct tomoyo_io_buffer". 349 * 350 * Returns 0. 351 */ 352 int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) 353 { 354 char *data = head->write_buf; 355 unsigned int size; 356 357 if (sscanf(data, "Policy: %u", &size) == 1) 358 tomoyo_quota_for_policy = size; 359 return 0; 360 } 361