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 nameidata nd; 169 170 if (pathname && path_lookup(pathname, LOOKUP_FOLLOW, &nd) == 0) { 171 char *buf = tomoyo_realpath_from_path(&nd.path); 172 path_put(&nd.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 nameidata nd; 188 189 if (pathname && path_lookup(pathname, 0, &nd) == 0) { 190 char *buf = tomoyo_realpath_from_path(&nd.path); 191 path_put(&nd.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 /***** EXCLUSIVE SECTION START *****/ 224 mutex_lock(&lock); 225 if (buf_used_len + word_aligned_size > PATH_MAX) { 226 if (!tomoyo_quota_for_elements || 227 tomoyo_allocated_memory_for_elements 228 + PATH_MAX <= tomoyo_quota_for_elements) 229 ptr = kzalloc(PATH_MAX, GFP_KERNEL); 230 if (!ptr) { 231 printk(KERN_WARNING "ERROR: Out of memory " 232 "for tomoyo_alloc_element().\n"); 233 if (!tomoyo_policy_loaded) 234 panic("MAC Initialization failed.\n"); 235 } else { 236 buf = ptr; 237 tomoyo_allocated_memory_for_elements += PATH_MAX; 238 buf_used_len = word_aligned_size; 239 ptr = buf; 240 } 241 } else if (word_aligned_size) { 242 int i; 243 ptr = buf + buf_used_len; 244 buf_used_len += word_aligned_size; 245 for (i = 0; i < word_aligned_size; i++) { 246 if (!ptr[i]) 247 continue; 248 printk(KERN_ERR "WARNING: Reserved memory was tainted! " 249 "The system might go wrong.\n"); 250 ptr[i] = '\0'; 251 } 252 } 253 mutex_unlock(&lock); 254 /***** EXCLUSIVE SECTION END *****/ 255 return ptr; 256 } 257 258 /* Memory allocated for string data in bytes. */ 259 static unsigned int tomoyo_allocated_memory_for_savename; 260 /* Quota for holding string data in bytes. */ 261 static unsigned int tomoyo_quota_for_savename; 262 263 /* 264 * TOMOYO uses this hash only when appending a string into the string 265 * table. Frequency of appending strings is very low. So we don't need 266 * large (e.g. 64k) hash size. 256 will be sufficient. 267 */ 268 #define TOMOYO_MAX_HASH 256 269 270 /* Structure for string data. */ 271 struct tomoyo_name_entry { 272 struct list_head list; 273 struct tomoyo_path_info entry; 274 }; 275 276 /* Structure for available memory region. */ 277 struct tomoyo_free_memory_block_list { 278 struct list_head list; 279 char *ptr; /* Pointer to a free area. */ 280 int len; /* Length of the area. */ 281 }; 282 283 /* 284 * The list for "struct tomoyo_name_entry". 285 * 286 * This list is updated only inside tomoyo_save_name(), thus 287 * no global mutex exists. 288 */ 289 static struct list_head tomoyo_name_list[TOMOYO_MAX_HASH]; 290 291 /** 292 * tomoyo_save_name - Allocate permanent memory for string data. 293 * 294 * @name: The string to store into the permernent memory. 295 * 296 * Returns pointer to "struct tomoyo_path_info" on success, NULL otherwise. 297 * 298 * The RAM is shared, so NEVER try to modify or kfree() the returned name. 299 */ 300 const struct tomoyo_path_info *tomoyo_save_name(const char *name) 301 { 302 static LIST_HEAD(fmb_list); 303 static DEFINE_MUTEX(lock); 304 struct tomoyo_name_entry *ptr; 305 unsigned int hash; 306 /* fmb contains available size in bytes. 307 fmb is removed from the fmb_list when fmb->len becomes 0. */ 308 struct tomoyo_free_memory_block_list *fmb; 309 int len; 310 char *cp; 311 312 if (!name) 313 return NULL; 314 len = strlen(name) + 1; 315 if (len > TOMOYO_MAX_PATHNAME_LEN) { 316 printk(KERN_WARNING "ERROR: Name too long " 317 "for tomoyo_save_name().\n"); 318 return NULL; 319 } 320 hash = full_name_hash((const unsigned char *) name, len - 1); 321 /***** EXCLUSIVE SECTION START *****/ 322 mutex_lock(&lock); 323 list_for_each_entry(ptr, &tomoyo_name_list[hash % TOMOYO_MAX_HASH], 324 list) { 325 if (hash == ptr->entry.hash && !strcmp(name, ptr->entry.name)) 326 goto out; 327 } 328 list_for_each_entry(fmb, &fmb_list, list) { 329 if (len <= fmb->len) 330 goto ready; 331 } 332 if (!tomoyo_quota_for_savename || 333 tomoyo_allocated_memory_for_savename + PATH_MAX 334 <= tomoyo_quota_for_savename) 335 cp = kzalloc(PATH_MAX, GFP_KERNEL); 336 else 337 cp = NULL; 338 fmb = kzalloc(sizeof(*fmb), GFP_KERNEL); 339 if (!cp || !fmb) { 340 kfree(cp); 341 kfree(fmb); 342 printk(KERN_WARNING "ERROR: Out of memory " 343 "for tomoyo_save_name().\n"); 344 if (!tomoyo_policy_loaded) 345 panic("MAC Initialization failed.\n"); 346 ptr = NULL; 347 goto out; 348 } 349 tomoyo_allocated_memory_for_savename += PATH_MAX; 350 list_add(&fmb->list, &fmb_list); 351 fmb->ptr = cp; 352 fmb->len = PATH_MAX; 353 ready: 354 ptr = tomoyo_alloc_element(sizeof(*ptr)); 355 if (!ptr) 356 goto out; 357 ptr->entry.name = fmb->ptr; 358 memmove(fmb->ptr, name, len); 359 tomoyo_fill_path_info(&ptr->entry); 360 fmb->ptr += len; 361 fmb->len -= len; 362 list_add_tail(&ptr->list, &tomoyo_name_list[hash % TOMOYO_MAX_HASH]); 363 if (fmb->len == 0) { 364 list_del(&fmb->list); 365 kfree(fmb); 366 } 367 out: 368 mutex_unlock(&lock); 369 /***** EXCLUSIVE SECTION END *****/ 370 return ptr ? &ptr->entry : NULL; 371 } 372 373 /** 374 * tomoyo_realpath_init - Initialize realpath related code. 375 */ 376 void __init tomoyo_realpath_init(void) 377 { 378 int i; 379 380 BUILD_BUG_ON(TOMOYO_MAX_PATHNAME_LEN > PATH_MAX); 381 for (i = 0; i < TOMOYO_MAX_HASH; i++) 382 INIT_LIST_HEAD(&tomoyo_name_list[i]); 383 INIT_LIST_HEAD(&tomoyo_kernel_domain.acl_info_list); 384 tomoyo_kernel_domain.domainname = tomoyo_save_name(TOMOYO_ROOT_NAME); 385 list_add_tail(&tomoyo_kernel_domain.list, &tomoyo_domain_list); 386 down_read(&tomoyo_domain_list_lock); 387 if (tomoyo_find_domain(TOMOYO_ROOT_NAME) != &tomoyo_kernel_domain) 388 panic("Can't register tomoyo_kernel_domain"); 389 up_read(&tomoyo_domain_list_lock); 390 } 391 392 /* Memory allocated for temporary purpose. */ 393 static atomic_t tomoyo_dynamic_memory_size; 394 395 /** 396 * tomoyo_alloc - Allocate memory for temporary purpose. 397 * 398 * @size: Size in bytes. 399 * 400 * Returns pointer to allocated memory on success, NULL otherwise. 401 */ 402 void *tomoyo_alloc(const size_t size) 403 { 404 void *p = kzalloc(size, GFP_KERNEL); 405 if (p) 406 atomic_add(ksize(p), &tomoyo_dynamic_memory_size); 407 return p; 408 } 409 410 /** 411 * tomoyo_free - Release memory allocated by tomoyo_alloc(). 412 * 413 * @p: Pointer returned by tomoyo_alloc(). May be NULL. 414 * 415 * Returns nothing. 416 */ 417 void tomoyo_free(const void *p) 418 { 419 if (p) { 420 atomic_sub(ksize(p), &tomoyo_dynamic_memory_size); 421 kfree(p); 422 } 423 } 424 425 /** 426 * tomoyo_read_memory_counter - Check for memory usage in bytes. 427 * 428 * @head: Pointer to "struct tomoyo_io_buffer". 429 * 430 * Returns memory usage. 431 */ 432 int tomoyo_read_memory_counter(struct tomoyo_io_buffer *head) 433 { 434 if (!head->read_eof) { 435 const unsigned int shared 436 = tomoyo_allocated_memory_for_savename; 437 const unsigned int private 438 = tomoyo_allocated_memory_for_elements; 439 const unsigned int dynamic 440 = atomic_read(&tomoyo_dynamic_memory_size); 441 char buffer[64]; 442 443 memset(buffer, 0, sizeof(buffer)); 444 if (tomoyo_quota_for_savename) 445 snprintf(buffer, sizeof(buffer) - 1, 446 " (Quota: %10u)", 447 tomoyo_quota_for_savename); 448 else 449 buffer[0] = '\0'; 450 tomoyo_io_printf(head, "Shared: %10u%s\n", shared, buffer); 451 if (tomoyo_quota_for_elements) 452 snprintf(buffer, sizeof(buffer) - 1, 453 " (Quota: %10u)", 454 tomoyo_quota_for_elements); 455 else 456 buffer[0] = '\0'; 457 tomoyo_io_printf(head, "Private: %10u%s\n", private, buffer); 458 tomoyo_io_printf(head, "Dynamic: %10u\n", dynamic); 459 tomoyo_io_printf(head, "Total: %10u\n", 460 shared + private + dynamic); 461 head->read_eof = true; 462 } 463 return 0; 464 } 465 466 /** 467 * tomoyo_write_memory_quota - Set memory quota. 468 * 469 * @head: Pointer to "struct tomoyo_io_buffer". 470 * 471 * Returns 0. 472 */ 473 int tomoyo_write_memory_quota(struct tomoyo_io_buffer *head) 474 { 475 char *data = head->write_buf; 476 unsigned int size; 477 478 if (sscanf(data, "Shared: %u", &size) == 1) 479 tomoyo_quota_for_savename = size; 480 else if (sscanf(data, "Private: %u", &size) == 1) 481 tomoyo_quota_for_elements = size; 482 return 0; 483 } 484