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 "common.h" 17 #include "realpath.h" 18 19 /** 20 * tomoyo_encode: Convert binary string to ascii string. 21 * 22 * @buffer: Buffer for ASCII string. 23 * @buflen: Size of @buffer. 24 * @str: Binary string. 25 * 26 * Returns 0 on success, -ENOMEM otherwise. 27 */ 28 int tomoyo_encode(char *buffer, int buflen, const char *str) 29 { 30 while (1) { 31 const unsigned char c = *(unsigned char *) str++; 32 33 if (tomoyo_is_valid(c)) { 34 if (--buflen <= 0) 35 break; 36 *buffer++ = (char) c; 37 if (c != '\\') 38 continue; 39 if (--buflen <= 0) 40 break; 41 *buffer++ = (char) c; 42 continue; 43 } 44 if (!c) { 45 if (--buflen <= 0) 46 break; 47 *buffer = '\0'; 48 return 0; 49 } 50 buflen -= 4; 51 if (buflen <= 0) 52 break; 53 *buffer++ = '\\'; 54 *buffer++ = (c >> 6) + '0'; 55 *buffer++ = ((c >> 3) & 7) + '0'; 56 *buffer++ = (c & 7) + '0'; 57 } 58 return -ENOMEM; 59 } 60 61 /** 62 * tomoyo_realpath_from_path2 - Returns realpath(3) of the given dentry but ignores chroot'ed root. 63 * 64 * @path: Pointer to "struct path". 65 * @newname: Pointer to buffer to return value in. 66 * @newname_len: Size of @newname. 67 * 68 * Returns 0 on success, negative value otherwise. 69 * 70 * If dentry is a directory, trailing '/' is appended. 71 * Characters out of 0x20 < c < 0x7F range are converted to 72 * \ooo style octal string. 73 * Character \ is converted to \\ string. 74 */ 75 int tomoyo_realpath_from_path2(struct path *path, char *newname, 76 int newname_len) 77 { 78 int error = -ENOMEM; 79 struct dentry *dentry = path->dentry; 80 char *sp; 81 82 if (!dentry || !path->mnt || !newname || newname_len <= 2048) 83 return -EINVAL; 84 if (dentry->d_op && dentry->d_op->d_dname) { 85 /* For "socket:[\$]" and "pipe:[\$]". */ 86 static const int offset = 1536; 87 sp = dentry->d_op->d_dname(dentry, newname + offset, 88 newname_len - offset); 89 } else { 90 /* Taken from d_namespace_path(). */ 91 struct path root; 92 struct path ns_root = { }; 93 struct path tmp; 94 95 read_lock(¤t->fs->lock); 96 root = current->fs->root; 97 path_get(&root); 98 read_unlock(¤t->fs->lock); 99 spin_lock(&vfsmount_lock); 100 if (root.mnt && root.mnt->mnt_ns) 101 ns_root.mnt = mntget(root.mnt->mnt_ns->root); 102 if (ns_root.mnt) 103 ns_root.dentry = dget(ns_root.mnt->mnt_root); 104 spin_unlock(&vfsmount_lock); 105 spin_lock(&dcache_lock); 106 tmp = ns_root; 107 sp = __d_path(path, &tmp, newname, newname_len); 108 spin_unlock(&dcache_lock); 109 path_put(&root); 110 path_put(&ns_root); 111 } 112 if (IS_ERR(sp)) 113 error = PTR_ERR(sp); 114 else 115 error = tomoyo_encode(newname, sp - newname, sp); 116 /* Append trailing '/' if dentry is a directory. */ 117 if (!error && dentry->d_inode && S_ISDIR(dentry->d_inode->i_mode) 118 && *newname) { 119 sp = newname + strlen(newname); 120 if (*(sp - 1) != '/') { 121 if (sp < newname + newname_len - 4) { 122 *sp++ = '/'; 123 *sp = '\0'; 124 } else { 125 error = -ENOMEM; 126 } 127 } 128 } 129 if (error) 130 printk(KERN_WARNING "tomoyo_realpath: Pathname too long.\n"); 131 return error; 132 } 133 134 /** 135 * tomoyo_realpath_from_path - Returns realpath(3) of the given pathname but ignores chroot'ed root. 136 * 137 * @path: Pointer to "struct path". 138 * 139 * Returns the realpath of the given @path on success, NULL otherwise. 140 * 141 * These functions use tomoyo_alloc(), so the caller must call tomoyo_free() 142 * if these functions didn't return NULL. 143 */ 144 char *tomoyo_realpath_from_path(struct path *path) 145 { 146 char *buf = tomoyo_alloc(sizeof(struct tomoyo_page_buffer)); 147 148 BUILD_BUG_ON(sizeof(struct tomoyo_page_buffer) 149 <= TOMOYO_MAX_PATHNAME_LEN - 1); 150 if (!buf) 151 return NULL; 152 if (tomoyo_realpath_from_path2(path, buf, 153 TOMOYO_MAX_PATHNAME_LEN - 1) == 0) 154 return buf; 155 tomoyo_free(buf); 156 return NULL; 157 } 158 159 /** 160 * tomoyo_realpath - Get realpath of a pathname. 161 * 162 * @pathname: The pathname to solve. 163 * 164 * Returns the realpath of @pathname on success, NULL otherwise. 165 */ 166 char *tomoyo_realpath(const char *pathname) 167 { 168 struct path path; 169 170 if (pathname && kern_path(pathname, LOOKUP_FOLLOW, &path) == 0) { 171 char *buf = tomoyo_realpath_from_path(&path); 172 path_put(&path); 173 return buf; 174 } 175 return NULL; 176 } 177 178 /** 179 * tomoyo_realpath_nofollow - Get realpath of a pathname. 180 * 181 * @pathname: The pathname to solve. 182 * 183 * Returns the realpath of @pathname on success, NULL otherwise. 184 */ 185 char *tomoyo_realpath_nofollow(const char *pathname) 186 { 187 struct path path; 188 189 if (pathname && kern_path(pathname, 0, &path) == 0) { 190 char *buf = tomoyo_realpath_from_path(&path); 191 path_put(&path); 192 return buf; 193 } 194 return NULL; 195 } 196 197 /* Memory allocated for non-string data. */ 198 static unsigned int tomoyo_allocated_memory_for_elements; 199 /* Quota for holding non-string data. */ 200 static unsigned int tomoyo_quota_for_elements; 201 202 /** 203 * tomoyo_alloc_element - Allocate permanent memory for structures. 204 * 205 * @size: Size in bytes. 206 * 207 * Returns pointer to allocated memory on success, NULL otherwise. 208 * 209 * Memory has to be zeroed. 210 * The RAM is chunked, so NEVER try to kfree() the returned pointer. 211 */ 212 void *tomoyo_alloc_element(const unsigned int size) 213 { 214 static char *buf; 215 static DEFINE_MUTEX(lock); 216 static unsigned int buf_used_len = PATH_MAX; 217 char *ptr = NULL; 218 /*Assumes sizeof(void *) >= sizeof(long) is true. */ 219 const unsigned int word_aligned_size 220 = roundup(size, max(sizeof(void *), sizeof(long))); 221 if (word_aligned_size > PATH_MAX) 222 return NULL; 223 mutex_lock(&lock); 224 if (buf_used_len + word_aligned_size > PATH_MAX) { 225 if (!tomoyo_quota_for_elements || 226 tomoyo_allocated_memory_for_elements 227 + PATH_MAX <= tomoyo_quota_for_elements) 228 ptr = kzalloc(PATH_MAX, GFP_KERNEL); 229 if (!ptr) { 230 printk(KERN_WARNING "ERROR: Out of memory " 231 "for tomoyo_alloc_element().\n"); 232 if (!tomoyo_policy_loaded) 233 panic("MAC Initialization failed.\n"); 234 } else { 235 buf = ptr; 236 tomoyo_allocated_memory_for_elements += PATH_MAX; 237 buf_used_len = word_aligned_size; 238 ptr = buf; 239 } 240 } else if (word_aligned_size) { 241 int i; 242 ptr = buf + buf_used_len; 243 buf_used_len += word_aligned_size; 244 for (i = 0; i < word_aligned_size; i++) { 245 if (!ptr[i]) 246 continue; 247 printk(KERN_ERR "WARNING: Reserved memory was tainted! " 248 "The system might go wrong.\n"); 249 ptr[i] = '\0'; 250 } 251 } 252 mutex_unlock(&lock); 253 return ptr; 254 } 255 256 /* Memory allocated for string data in bytes. */ 257 static unsigned int tomoyo_allocated_memory_for_savename; 258 /* Quota for holding string data in bytes. */ 259 static unsigned int tomoyo_quota_for_savename; 260 261 /* 262 * TOMOYO uses this hash only when appending a string into the string 263 * table. Frequency of appending strings is very low. So we don't need 264 * large (e.g. 64k) hash size. 256 will be sufficient. 265 */ 266 #define TOMOYO_MAX_HASH 256 267 268 /* 269 * tomoyo_name_entry is a structure which is used for linking 270 * "struct tomoyo_path_info" into tomoyo_name_list . 271 * 272 * Since tomoyo_name_list manages a list of strings which are shared by 273 * multiple processes (whereas "struct tomoyo_path_info" inside 274 * "struct tomoyo_path_info_with_data" is not shared), a reference counter will 275 * be added to "struct tomoyo_name_entry" rather than "struct tomoyo_path_info" 276 * when TOMOYO starts supporting garbage collector. 277 */ 278 struct tomoyo_name_entry { 279 struct list_head list; 280 struct tomoyo_path_info entry; 281 }; 282 283 /* Structure for available memory region. */ 284 struct tomoyo_free_memory_block_list { 285 struct list_head list; 286 char *ptr; /* Pointer to a free area. */ 287 int len; /* Length of the area. */ 288 }; 289 290 /* 291 * tomoyo_name_list is used for holding string data used by TOMOYO. 292 * Since same string data is likely used for multiple times (e.g. 293 * "/lib/libc-2.5.so"), TOMOYO shares string data in the form of 294 * "const struct tomoyo_path_info *". 295 */ 296 static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 297 298 /** 299 * tomoyo_save_name - Allocate permanent memory for string data. 300 * 301 * @name: The string to store into the permernent memory. 302 * 303 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 304 * 305 * The RAM is shared, so NEVER try to modify or kfree() the returned name. 306 */ 307 const struct tomoyo_path_info *tomoyo_save_name(const char *name) 308 { 309 static LIST_HEAD(fmb_list); 310 static DEFINE_MUTEX(lock); 311 struct tomoyo_name_entry *ptr; 312 unsigned int hash; 313 /* fmb contains available size in bytes. 314 fmb is removed from the fmb_list when fmb->len becomes 0. */ 315 struct tomoyo_free_memory_block_list *fmb; 316 int len; 317 char *cp; 318 319 if (!name) 320 return NULL; 321 len = strlen(name) + 1; 322 if (len > TOMOYO_MAX_PATHNAME_LEN) { 323 printk(KERN_WARNING "ERROR: Name too long " 324 "for tomoyo_save_name().\n"); 325 return NULL; 326 } 327 hash = full_name_hash((const unsigned char *) name, len - 1); 328 mutex_lock(&lock); 329 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 330 list) { 331 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 332 goto out; 333 } 334 list_for_each_entry(fmb, &fmb_list, list) { 335 if (len <= fmb->len) 336 goto ready; 337 } 338 if (!tomoyo_quota_for_savename || 339 tomoyo_allocated_memory_for_savename + PATH_MAX 340 <= tomoyo_quota_for_savename) 341 cp = kzalloc(PATH_MAX, GFP_KERNEL); 342 else 343 cp = NULL; 344 fmb = kzalloc(sizeof(*fmb), GFP_KERNEL); 345 if (!cp || !fmb) { 346 kfree(cp); 347 kfree(fmb); 348 printk(KERN_WARNING "ERROR: Out of memory " 349 "for tomoyo_save_name().\n"); 350 if (!tomoyo_policy_loaded) 351 panic("MAC Initialization failed.\n"); 352 ptr = NULL; 353 goto out; 354 } 355 tomoyo_allocated_memory_for_savename += PATH_MAX; 356 list_add(&fmb->list, &fmb_list); 357 fmb->ptr = cp; 358 fmb->len = PATH_MAX; 359 ready: 360 ptr = tomoyo_alloc_element(sizeof(*ptr)); 361 if (!ptr) 362 goto out; 363 ptr->entry.name = fmb->ptr; 364 memmove(fmb->ptr, name, len); 365 tomoyo_fill_path_info(&ptr->entry); 366 fmb->ptr += len; 367 fmb->len -= len; 368 list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]); 369 if (fmb->len == 0) { 370 list_del(&fmb->list); 371 kfree(fmb); 372 } 373 out: 374 mutex_unlock(&lock); 375 return ptr ? &ptr->entry : NULL; 376 } 377 378 /** 379 * tomoyo_realpath_init - Initialize realpath related code. 380 */ 381 void __init tomoyo_realpath_init(void) 382 { 383 int i; 384 385 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX); 386 for (i = 0; i < TOMOYO_MAX_HASH; i++) 387 INIT_LIST_HEAD(&tomoyo_name_list[i]); 388 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 389 tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); 390 list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 391 down_read(&tomoyo_domain_list_lock); 392 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) 393 panic("Can't register tomoyo_kernel_domain"); 394 up_read(&tomoyo_domain_list_lock); 395 } 396 397 /* Memory allocated for temporary purpose. */ 398 static atomic_t tomoyo_dynamic_memory_size; 399 400 /** 401 * tomoyo_alloc - Allocate memory for temporary purpose. 402 * 403 * @size: Size in bytes. 404 * 405 * Returns pointer to allocated memory on success, NULL otherwise. 406 */ 407 void *tomoyo_alloc(const size_t size) 408 { 409 void *p = kzalloc(size, GFP_KERNEL); 410 if (p) 411 atomic_add(ksize(p), &tomoyo_dynamic_memory_size); 412 return p; 413 } 414 415 /** 416 * tomoyo_free - Release memory allocated by tomoyo_alloc(). 417 * 418 * @p: Pointer returned by tomoyo_alloc(). May be NULL. 419 * 420 * Returns nothing. 421 */ 422 void tomoyo_free(const void *p) 423 { 424 if (p) { 425 atomic_sub(ksize(p), &tomoyo_dynamic_memory_size); 426 kfree(p); 427 } 428 } 429 430 /** 431 * tomoyo_read_memory_counter - Check for memory usage in bytes. 432 * 433 * @head: Pointer to "struct tomoyo_io_buffer". 434 * 435 * Returns memory usage. 436 */ 437 int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 438 { 439 if (!head->read_eof) { 440 const unsigned int shared 441 = tomoyo_allocated_memory_for_savename; 442 const unsigned int private 443 = tomoyo_allocated_memory_for_elements; 444 const unsigned int dynamic 445 = atomic_read(&tomoyo_dynamic_memory_size); 446 char buffer[64]; 447 448 memset(buffer, 0, sizeof(buffer)); 449 if (tomoyo_quota_for_savename) 450 snprintf(buffer, sizeof(buffer) - 1, 451 " (Quota: %10u)", 452 tomoyo_quota_for_savename); 453 else 454 buffer[0] = '\0'; 455 tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer); 456 if (tomoyo_quota_for_elements) 457 snprintf(buffer, sizeof(buffer) - 1, 458 " (Quota: %10u)", 459 tomoyo_quota_for_elements); 460 else 461 buffer[0] = '\0'; 462 tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); 463 tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic); 464 tomoyo_io_printf(head, "Total: %10u\n", 465 shared + private + dynamic); 466 head->read_eof = true; 467 } 468 return 0; 469 } 470 471 /** 472 * tomoyo_write_memory_quota - Set memory quota. 473 * 474 * @head: Pointer to "struct tomoyo_io_buffer". 475 * 476 * Returns 0. 477 */ 478 int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) 479 { 480 char *data = head->write_buf; 481 unsigned int size; 482 483 if (sscanf(data, "Shared: %u", &size) == 1) 484 tomoyo_quota_for_savename = size; 485 else if (sscanf(data, "Private: %u", &size) == 1) 486 tomoyo_quota_for_elements = size; 487 return 0; 488 } 489