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