diff options
| author | Tony Luck <tony.luck@intel.com> | 2005-10-20 13:41:44 -0400 |
|---|---|---|
| committer | Tony Luck <tony.luck@intel.com> | 2005-10-20 13:41:44 -0400 |
| commit | 9cec58dc138d6fcad9f447a19c8ff69f6540e667 (patch) | |
| tree | 4fe1cca94fdba8b705c87615bee06d3346f687ce /fs/proc | |
| parent | 17e5ad6c0ce5a970e2830d0de8bdd60a2f077d38 (diff) | |
| parent | ac9b9c667c2e1194e22ebe0a441ae1c37aaa9b90 (diff) | |
Update from upstream with manual merge of Yasunori Goto's
changes to swiotlb.c made in commit 281dd25cdc0d6903929b79183816d151ea626341
since this file has been moved from arch/ia64/lib/swiotlb.c to
lib/swiotlb.c
Signed-off-by: Tony Luck <tony.luck@intel.com>
Diffstat (limited to 'fs/proc')
| -rw-r--r-- | fs/proc/array.c | 3 | ||||
| -rw-r--r-- | fs/proc/base.c | 98 | ||||
| -rw-r--r-- | fs/proc/nommu.c | 1 |
3 files changed, 95 insertions, 7 deletions
diff --git a/fs/proc/array.c b/fs/proc/array.c index d88d518d30f6..d84eecacbeaf 100644 --- a/fs/proc/array.c +++ b/fs/proc/array.c | |||
| @@ -74,6 +74,7 @@ | |||
| 74 | #include <linux/file.h> | 74 | #include <linux/file.h> |
| 75 | #include <linux/times.h> | 75 | #include <linux/times.h> |
| 76 | #include <linux/cpuset.h> | 76 | #include <linux/cpuset.h> |
| 77 | #include <linux/rcupdate.h> | ||
| 77 | 78 | ||
| 78 | #include <asm/uaccess.h> | 79 | #include <asm/uaccess.h> |
| 79 | #include <asm/pgtable.h> | 80 | #include <asm/pgtable.h> |
| @@ -180,12 +181,14 @@ static inline char * task_state(struct task_struct *p, char *buffer) | |||
| 180 | p->gid, p->egid, p->sgid, p->fsgid); | 181 | p->gid, p->egid, p->sgid, p->fsgid); |
| 181 | read_unlock(&tasklist_lock); | 182 | read_unlock(&tasklist_lock); |
| 182 | task_lock(p); | 183 | task_lock(p); |
| 184 | rcu_read_lock(); | ||
| 183 | if (p->files) | 185 | if (p->files) |
| 184 | fdt = files_fdtable(p->files); | 186 | fdt = files_fdtable(p->files); |
| 185 | buffer += sprintf(buffer, | 187 | buffer += sprintf(buffer, |
| 186 | "FDSize:\t%d\n" | 188 | "FDSize:\t%d\n" |
| 187 | "Groups:\t", | 189 | "Groups:\t", |
| 188 | fdt ? fdt->max_fds : 0); | 190 | fdt ? fdt->max_fds : 0); |
| 191 | rcu_read_unlock(); | ||
| 189 | 192 | ||
| 190 | group_info = p->group_info; | 193 | group_info = p->group_info; |
| 191 | get_group_info(group_info); | 194 | get_group_info(group_info); |
diff --git a/fs/proc/base.c b/fs/proc/base.c index 23db452ab428..a170450aadb1 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
| @@ -103,7 +103,9 @@ enum pid_directory_inos { | |||
| 103 | PROC_TGID_NUMA_MAPS, | 103 | PROC_TGID_NUMA_MAPS, |
| 104 | PROC_TGID_MOUNTS, | 104 | PROC_TGID_MOUNTS, |
| 105 | PROC_TGID_WCHAN, | 105 | PROC_TGID_WCHAN, |
| 106 | #ifdef CONFIG_MMU | ||
| 106 | PROC_TGID_SMAPS, | 107 | PROC_TGID_SMAPS, |
| 108 | #endif | ||
| 107 | #ifdef CONFIG_SCHEDSTATS | 109 | #ifdef CONFIG_SCHEDSTATS |
| 108 | PROC_TGID_SCHEDSTAT, | 110 | PROC_TGID_SCHEDSTAT, |
| 109 | #endif | 111 | #endif |
| @@ -141,7 +143,9 @@ enum pid_directory_inos { | |||
| 141 | PROC_TID_NUMA_MAPS, | 143 | PROC_TID_NUMA_MAPS, |
| 142 | PROC_TID_MOUNTS, | 144 | PROC_TID_MOUNTS, |
| 143 | PROC_TID_WCHAN, | 145 | PROC_TID_WCHAN, |
| 146 | #ifdef CONFIG_MMU | ||
| 144 | PROC_TID_SMAPS, | 147 | PROC_TID_SMAPS, |
| 148 | #endif | ||
| 145 | #ifdef CONFIG_SCHEDSTATS | 149 | #ifdef CONFIG_SCHEDSTATS |
| 146 | PROC_TID_SCHEDSTAT, | 150 | PROC_TID_SCHEDSTAT, |
| 147 | #endif | 151 | #endif |
| @@ -195,7 +199,9 @@ static struct pid_entry tgid_base_stuff[] = { | |||
| 195 | E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), | 199 | E(PROC_TGID_ROOT, "root", S_IFLNK|S_IRWXUGO), |
| 196 | E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), | 200 | E(PROC_TGID_EXE, "exe", S_IFLNK|S_IRWXUGO), |
| 197 | E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), | 201 | E(PROC_TGID_MOUNTS, "mounts", S_IFREG|S_IRUGO), |
| 202 | #ifdef CONFIG_MMU | ||
| 198 | E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), | 203 | E(PROC_TGID_SMAPS, "smaps", S_IFREG|S_IRUGO), |
| 204 | #endif | ||
| 199 | #ifdef CONFIG_SECURITY | 205 | #ifdef CONFIG_SECURITY |
| 200 | E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), | 206 | E(PROC_TGID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), |
| 201 | #endif | 207 | #endif |
| @@ -235,7 +241,9 @@ static struct pid_entry tid_base_stuff[] = { | |||
| 235 | E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), | 241 | E(PROC_TID_ROOT, "root", S_IFLNK|S_IRWXUGO), |
| 236 | E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), | 242 | E(PROC_TID_EXE, "exe", S_IFLNK|S_IRWXUGO), |
| 237 | E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), | 243 | E(PROC_TID_MOUNTS, "mounts", S_IFREG|S_IRUGO), |
| 244 | #ifdef CONFIG_MMU | ||
| 238 | E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), | 245 | E(PROC_TID_SMAPS, "smaps", S_IFREG|S_IRUGO), |
| 246 | #endif | ||
| 239 | #ifdef CONFIG_SECURITY | 247 | #ifdef CONFIG_SECURITY |
| 240 | E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), | 248 | E(PROC_TID_ATTR, "attr", S_IFDIR|S_IRUGO|S_IXUGO), |
| 241 | #endif | 249 | #endif |
| @@ -340,6 +348,54 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf | |||
| 340 | return result; | 348 | return result; |
| 341 | } | 349 | } |
| 342 | 350 | ||
| 351 | |||
| 352 | /* Same as proc_root_link, but this addionally tries to get fs from other | ||
| 353 | * threads in the group */ | ||
| 354 | static int proc_task_root_link(struct inode *inode, struct dentry **dentry, | ||
| 355 | struct vfsmount **mnt) | ||
| 356 | { | ||
| 357 | struct fs_struct *fs; | ||
| 358 | int result = -ENOENT; | ||
| 359 | struct task_struct *leader = proc_task(inode); | ||
| 360 | |||
| 361 | task_lock(leader); | ||
| 362 | fs = leader->fs; | ||
| 363 | if (fs) { | ||
| 364 | atomic_inc(&fs->count); | ||
| 365 | task_unlock(leader); | ||
| 366 | } else { | ||
| 367 | /* Try to get fs from other threads */ | ||
| 368 | task_unlock(leader); | ||
| 369 | read_lock(&tasklist_lock); | ||
| 370 | if (pid_alive(leader)) { | ||
| 371 | struct task_struct *task = leader; | ||
| 372 | |||
| 373 | while ((task = next_thread(task)) != leader) { | ||
| 374 | task_lock(task); | ||
| 375 | fs = task->fs; | ||
| 376 | if (fs) { | ||
| 377 | atomic_inc(&fs->count); | ||
| 378 | task_unlock(task); | ||
| 379 | break; | ||
| 380 | } | ||
| 381 | task_unlock(task); | ||
| 382 | } | ||
| 383 | } | ||
| 384 | read_unlock(&tasklist_lock); | ||
| 385 | } | ||
| 386 | |||
| 387 | if (fs) { | ||
| 388 | read_lock(&fs->lock); | ||
| 389 | *mnt = mntget(fs->rootmnt); | ||
| 390 | *dentry = dget(fs->root); | ||
| 391 | read_unlock(&fs->lock); | ||
| 392 | result = 0; | ||
| 393 | put_fs_struct(fs); | ||
| 394 | } | ||
| 395 | return result; | ||
| 396 | } | ||
| 397 | |||
| 398 | |||
| 343 | #define MAY_PTRACE(task) \ | 399 | #define MAY_PTRACE(task) \ |
| 344 | (task == current || \ | 400 | (task == current || \ |
| 345 | (task->parent == current && \ | 401 | (task->parent == current && \ |
| @@ -471,14 +527,14 @@ static int proc_oom_score(struct task_struct *task, char *buffer) | |||
| 471 | 527 | ||
| 472 | /* permission checks */ | 528 | /* permission checks */ |
| 473 | 529 | ||
| 474 | static int proc_check_root(struct inode *inode) | 530 | /* If the process being read is separated by chroot from the reading process, |
| 531 | * don't let the reader access the threads. | ||
| 532 | */ | ||
| 533 | static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt) | ||
| 475 | { | 534 | { |
| 476 | struct dentry *de, *base, *root; | 535 | struct dentry *de, *base; |
| 477 | struct vfsmount *our_vfsmnt, *vfsmnt, *mnt; | 536 | struct vfsmount *our_vfsmnt, *mnt; |
| 478 | int res = 0; | 537 | int res = 0; |
| 479 | |||
| 480 | if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */ | ||
| 481 | return -ENOENT; | ||
| 482 | read_lock(¤t->fs->lock); | 538 | read_lock(¤t->fs->lock); |
| 483 | our_vfsmnt = mntget(current->fs->rootmnt); | 539 | our_vfsmnt = mntget(current->fs->rootmnt); |
| 484 | base = dget(current->fs->root); | 540 | base = dget(current->fs->root); |
| @@ -511,6 +567,16 @@ out: | |||
| 511 | goto exit; | 567 | goto exit; |
| 512 | } | 568 | } |
| 513 | 569 | ||
| 570 | static int proc_check_root(struct inode *inode) | ||
| 571 | { | ||
| 572 | struct dentry *root; | ||
| 573 | struct vfsmount *vfsmnt; | ||
| 574 | |||
| 575 | if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */ | ||
| 576 | return -ENOENT; | ||
| 577 | return proc_check_chroot(root, vfsmnt); | ||
| 578 | } | ||
| 579 | |||
| 514 | static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) | 580 | static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) |
| 515 | { | 581 | { |
| 516 | if (generic_permission(inode, mask, NULL) != 0) | 582 | if (generic_permission(inode, mask, NULL) != 0) |
| @@ -518,6 +584,20 @@ static int proc_permission(struct inode *inode, int mask, struct nameidata *nd) | |||
| 518 | return proc_check_root(inode); | 584 | return proc_check_root(inode); |
| 519 | } | 585 | } |
| 520 | 586 | ||
| 587 | static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd) | ||
| 588 | { | ||
| 589 | struct dentry *root; | ||
| 590 | struct vfsmount *vfsmnt; | ||
| 591 | |||
| 592 | if (generic_permission(inode, mask, NULL) != 0) | ||
| 593 | return -EACCES; | ||
| 594 | |||
| 595 | if (proc_task_root_link(inode, &root, &vfsmnt)) | ||
| 596 | return -ENOENT; | ||
| 597 | |||
| 598 | return proc_check_chroot(root, vfsmnt); | ||
| 599 | } | ||
| 600 | |||
| 521 | extern struct seq_operations proc_pid_maps_op; | 601 | extern struct seq_operations proc_pid_maps_op; |
| 522 | static int maps_open(struct inode *inode, struct file *file) | 602 | static int maps_open(struct inode *inode, struct file *file) |
| 523 | { | 603 | { |
| @@ -558,6 +638,7 @@ static struct file_operations proc_numa_maps_operations = { | |||
| 558 | }; | 638 | }; |
| 559 | #endif | 639 | #endif |
| 560 | 640 | ||
| 641 | #ifdef CONFIG_MMU | ||
| 561 | extern struct seq_operations proc_pid_smaps_op; | 642 | extern struct seq_operations proc_pid_smaps_op; |
| 562 | static int smaps_open(struct inode *inode, struct file *file) | 643 | static int smaps_open(struct inode *inode, struct file *file) |
| 563 | { | 644 | { |
| @@ -576,6 +657,7 @@ static struct file_operations proc_smaps_operations = { | |||
| 576 | .llseek = seq_lseek, | 657 | .llseek = seq_lseek, |
| 577 | .release = seq_release, | 658 | .release = seq_release, |
| 578 | }; | 659 | }; |
| 660 | #endif | ||
| 579 | 661 | ||
| 580 | extern struct seq_operations mounts_op; | 662 | extern struct seq_operations mounts_op; |
| 581 | static int mounts_open(struct inode *inode, struct file *file) | 663 | static int mounts_open(struct inode *inode, struct file *file) |
| @@ -1419,7 +1501,7 @@ static struct inode_operations proc_fd_inode_operations = { | |||
| 1419 | 1501 | ||
| 1420 | static struct inode_operations proc_task_inode_operations = { | 1502 | static struct inode_operations proc_task_inode_operations = { |
| 1421 | .lookup = proc_task_lookup, | 1503 | .lookup = proc_task_lookup, |
| 1422 | .permission = proc_permission, | 1504 | .permission = proc_task_permission, |
| 1423 | }; | 1505 | }; |
| 1424 | 1506 | ||
| 1425 | #ifdef CONFIG_SECURITY | 1507 | #ifdef CONFIG_SECURITY |
| @@ -1609,10 +1691,12 @@ static struct dentry *proc_pident_lookup(struct inode *dir, | |||
| 1609 | case PROC_TGID_MOUNTS: | 1691 | case PROC_TGID_MOUNTS: |
| 1610 | inode->i_fop = &proc_mounts_operations; | 1692 | inode->i_fop = &proc_mounts_operations; |
| 1611 | break; | 1693 | break; |
| 1694 | #ifdef CONFIG_MMU | ||
| 1612 | case PROC_TID_SMAPS: | 1695 | case PROC_TID_SMAPS: |
| 1613 | case PROC_TGID_SMAPS: | 1696 | case PROC_TGID_SMAPS: |
| 1614 | inode->i_fop = &proc_smaps_operations; | 1697 | inode->i_fop = &proc_smaps_operations; |
| 1615 | break; | 1698 | break; |
| 1699 | #endif | ||
| 1616 | #ifdef CONFIG_SECURITY | 1700 | #ifdef CONFIG_SECURITY |
| 1617 | case PROC_TID_ATTR: | 1701 | case PROC_TID_ATTR: |
| 1618 | inode->i_nlink = 2; | 1702 | inode->i_nlink = 2; |
diff --git a/fs/proc/nommu.c b/fs/proc/nommu.c index f3bf016d5ee3..cff10ab1af63 100644 --- a/fs/proc/nommu.c +++ b/fs/proc/nommu.c | |||
| @@ -91,6 +91,7 @@ static void *nommu_vma_list_start(struct seq_file *m, loff_t *_pos) | |||
| 91 | next = _rb; | 91 | next = _rb; |
| 92 | break; | 92 | break; |
| 93 | } | 93 | } |
| 94 | pos--; | ||
| 94 | } | 95 | } |
| 95 | 96 | ||
| 96 | return next; | 97 | return next; |
