diff options
| -rw-r--r-- | fs/coredump.c | 5 | ||||
| -rw-r--r-- | include/linux/fs.h | 126 | ||||
| -rw-r--r-- | include/uapi/linux/fs.h | 132 | ||||
| -rw-r--r-- | security/selinux/hooks.c | 18 |
4 files changed, 136 insertions, 145 deletions
diff --git a/fs/coredump.c b/fs/coredump.c index fd37facac8dc..ce47379bfa61 100644 --- a/fs/coredump.c +++ b/fs/coredump.c | |||
| @@ -450,11 +450,12 @@ static int umh_pipe_setup(struct subprocess_info *info, struct cred *new) | |||
| 450 | 450 | ||
| 451 | cp->file = files[1]; | 451 | cp->file = files[1]; |
| 452 | 452 | ||
| 453 | replace_fd(0, files[0], 0); | 453 | err = replace_fd(0, files[0], 0); |
| 454 | fput(files[0]); | ||
| 454 | /* and disallow core files too */ | 455 | /* and disallow core files too */ |
| 455 | current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; | 456 | current->signal->rlim[RLIMIT_CORE] = (struct rlimit){1, 1}; |
| 456 | 457 | ||
| 457 | return 0; | 458 | return err; |
| 458 | } | 459 | } |
| 459 | 460 | ||
| 460 | void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) | 461 | void do_coredump(siginfo_t *siginfo, struct pt_regs *regs) |
diff --git a/include/linux/fs.h b/include/linux/fs.h index 001c7cff2d48..b33cfc97b9ca 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
| @@ -64,6 +64,73 @@ typedef void (dio_iodone_t)(struct kiocb *iocb, loff_t offset, | |||
| 64 | ssize_t bytes, void *private, int ret, | 64 | ssize_t bytes, void *private, int ret, |
| 65 | bool is_async); | 65 | bool is_async); |
| 66 | 66 | ||
| 67 | #define MAY_EXEC 0x00000001 | ||
| 68 | #define MAY_WRITE 0x00000002 | ||
| 69 | #define MAY_READ 0x00000004 | ||
| 70 | #define MAY_APPEND 0x00000008 | ||
| 71 | #define MAY_ACCESS 0x00000010 | ||
| 72 | #define MAY_OPEN 0x00000020 | ||
| 73 | #define MAY_CHDIR 0x00000040 | ||
| 74 | /* called from RCU mode, don't block */ | ||
| 75 | #define MAY_NOT_BLOCK 0x00000080 | ||
| 76 | |||
| 77 | /* | ||
| 78 | * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond | ||
| 79 | * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() | ||
| 80 | */ | ||
| 81 | |||
| 82 | /* file is open for reading */ | ||
| 83 | #define FMODE_READ ((__force fmode_t)0x1) | ||
| 84 | /* file is open for writing */ | ||
| 85 | #define FMODE_WRITE ((__force fmode_t)0x2) | ||
| 86 | /* file is seekable */ | ||
| 87 | #define FMODE_LSEEK ((__force fmode_t)0x4) | ||
| 88 | /* file can be accessed using pread */ | ||
| 89 | #define FMODE_PREAD ((__force fmode_t)0x8) | ||
| 90 | /* file can be accessed using pwrite */ | ||
| 91 | #define FMODE_PWRITE ((__force fmode_t)0x10) | ||
| 92 | /* File is opened for execution with sys_execve / sys_uselib */ | ||
| 93 | #define FMODE_EXEC ((__force fmode_t)0x20) | ||
| 94 | /* File is opened with O_NDELAY (only set for block devices) */ | ||
| 95 | #define FMODE_NDELAY ((__force fmode_t)0x40) | ||
| 96 | /* File is opened with O_EXCL (only set for block devices) */ | ||
| 97 | #define FMODE_EXCL ((__force fmode_t)0x80) | ||
| 98 | /* File is opened using open(.., 3, ..) and is writeable only for ioctls | ||
| 99 | (specialy hack for floppy.c) */ | ||
| 100 | #define FMODE_WRITE_IOCTL ((__force fmode_t)0x100) | ||
| 101 | /* 32bit hashes as llseek() offset (for directories) */ | ||
| 102 | #define FMODE_32BITHASH ((__force fmode_t)0x200) | ||
| 103 | /* 64bit hashes as llseek() offset (for directories) */ | ||
| 104 | #define FMODE_64BITHASH ((__force fmode_t)0x400) | ||
| 105 | |||
| 106 | /* | ||
| 107 | * Don't update ctime and mtime. | ||
| 108 | * | ||
| 109 | * Currently a special hack for the XFS open_by_handle ioctl, but we'll | ||
| 110 | * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon. | ||
| 111 | */ | ||
| 112 | #define FMODE_NOCMTIME ((__force fmode_t)0x800) | ||
| 113 | |||
| 114 | /* Expect random access pattern */ | ||
| 115 | #define FMODE_RANDOM ((__force fmode_t)0x1000) | ||
| 116 | |||
| 117 | /* File is huge (eg. /dev/kmem): treat loff_t as unsigned */ | ||
| 118 | #define FMODE_UNSIGNED_OFFSET ((__force fmode_t)0x2000) | ||
| 119 | |||
| 120 | /* File is opened with O_PATH; almost nothing can be done with it */ | ||
| 121 | #define FMODE_PATH ((__force fmode_t)0x4000) | ||
| 122 | |||
| 123 | /* File was opened by fanotify and shouldn't generate fanotify events */ | ||
| 124 | #define FMODE_NONOTIFY ((__force fmode_t)0x1000000) | ||
| 125 | |||
| 126 | /* | ||
| 127 | * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector | ||
| 128 | * that indicates that they should check the contents of the iovec are | ||
| 129 | * valid, but not check the memory that the iovec elements | ||
| 130 | * points too. | ||
| 131 | */ | ||
| 132 | #define CHECK_IOVEC_ONLY -1 | ||
| 133 | |||
| 67 | /* | 134 | /* |
| 68 | * The below are the various read and write types that we support. Some of | 135 | * The below are the various read and write types that we support. Some of |
| 69 | * them include behavioral modifiers that send information down to the | 136 | * them include behavioral modifiers that send information down to the |
| @@ -1557,6 +1624,60 @@ struct super_operations { | |||
| 1557 | }; | 1624 | }; |
| 1558 | 1625 | ||
| 1559 | /* | 1626 | /* |
| 1627 | * Inode flags - they have no relation to superblock flags now | ||
| 1628 | */ | ||
| 1629 | #define S_SYNC 1 /* Writes are synced at once */ | ||
| 1630 | #define S_NOATIME 2 /* Do not update access times */ | ||
| 1631 | #define S_APPEND 4 /* Append-only file */ | ||
| 1632 | #define S_IMMUTABLE 8 /* Immutable file */ | ||
| 1633 | #define S_DEAD 16 /* removed, but still open directory */ | ||
| 1634 | #define S_NOQUOTA 32 /* Inode is not counted to quota */ | ||
| 1635 | #define S_DIRSYNC 64 /* Directory modifications are synchronous */ | ||
| 1636 | #define S_NOCMTIME 128 /* Do not update file c/mtime */ | ||
| 1637 | #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ | ||
| 1638 | #define S_PRIVATE 512 /* Inode is fs-internal */ | ||
| 1639 | #define S_IMA 1024 /* Inode has an associated IMA struct */ | ||
| 1640 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ | ||
| 1641 | #define S_NOSEC 4096 /* no suid or xattr security attributes */ | ||
| 1642 | |||
| 1643 | /* | ||
| 1644 | * Note that nosuid etc flags are inode-specific: setting some file-system | ||
| 1645 | * flags just means all the inodes inherit those flags by default. It might be | ||
| 1646 | * possible to override it selectively if you really wanted to with some | ||
| 1647 | * ioctl() that is not currently implemented. | ||
| 1648 | * | ||
| 1649 | * Exception: MS_RDONLY is always applied to the entire file system. | ||
| 1650 | * | ||
| 1651 | * Unfortunately, it is possible to change a filesystems flags with it mounted | ||
| 1652 | * with files in use. This means that all of the inodes will not have their | ||
| 1653 | * i_flags updated. Hence, i_flags no longer inherit the superblock mount | ||
| 1654 | * flags, so these have to be checked separately. -- rmk@arm.uk.linux.org | ||
| 1655 | */ | ||
| 1656 | #define __IS_FLG(inode, flg) ((inode)->i_sb->s_flags & (flg)) | ||
| 1657 | |||
| 1658 | #define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY) | ||
| 1659 | #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \ | ||
| 1660 | ((inode)->i_flags & S_SYNC)) | ||
| 1661 | #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ | ||
| 1662 | ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) | ||
| 1663 | #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) | ||
| 1664 | #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) | ||
| 1665 | #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) | ||
| 1666 | |||
| 1667 | #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) | ||
| 1668 | #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) | ||
| 1669 | #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) | ||
| 1670 | #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) | ||
| 1671 | |||
| 1672 | #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) | ||
| 1673 | #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) | ||
| 1674 | #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) | ||
| 1675 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) | ||
| 1676 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) | ||
| 1677 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) | ||
| 1678 | #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) | ||
| 1679 | |||
| 1680 | /* | ||
| 1560 | * Inode state bits. Protected by inode->i_lock | 1681 | * Inode state bits. Protected by inode->i_lock |
| 1561 | * | 1682 | * |
| 1562 | * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, | 1683 | * Three bits determine the dirty state of the inode, I_DIRTY_SYNC, |
| @@ -1688,6 +1809,11 @@ int sync_inode_metadata(struct inode *inode, int wait); | |||
| 1688 | struct file_system_type { | 1809 | struct file_system_type { |
| 1689 | const char *name; | 1810 | const char *name; |
| 1690 | int fs_flags; | 1811 | int fs_flags; |
| 1812 | #define FS_REQUIRES_DEV 1 | ||
| 1813 | #define FS_BINARY_MOUNTDATA 2 | ||
| 1814 | #define FS_HAS_SUBTYPE 4 | ||
| 1815 | #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */ | ||
| 1816 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */ | ||
| 1691 | struct dentry *(*mount) (struct file_system_type *, int, | 1817 | struct dentry *(*mount) (struct file_system_type *, int, |
| 1692 | const char *, void *); | 1818 | const char *, void *); |
| 1693 | void (*kill_sb) (struct super_block *); | 1819 | void (*kill_sb) (struct super_block *); |
diff --git a/include/uapi/linux/fs.h b/include/uapi/linux/fs.h index 9fcc880d4be2..780d4c6093eb 100644 --- a/include/uapi/linux/fs.h +++ b/include/uapi/linux/fs.h | |||
| @@ -57,85 +57,6 @@ struct inodes_stat_t { | |||
| 57 | 57 | ||
| 58 | #define NR_FILE 8192 /* this can well be larger on a larger system */ | 58 | #define NR_FILE 8192 /* this can well be larger on a larger system */ |
| 59 | 59 | ||
| 60 | #define MAY_EXEC 0x00000001 | ||
| 61 | #define MAY_WRITE 0x00000002 | ||
| 62 | #define MAY_READ 0x00000004 | ||
| 63 | #define MAY_APPEND 0x00000008 | ||
| 64 | #define MAY_ACCESS 0x00000010 | ||
| 65 | #define MAY_OPEN 0x00000020 | ||
| 66 | #define MAY_CHDIR 0x00000040 | ||
| 67 | /* called from RCU mode, don't block */ | ||
| 68 | #define MAY_NOT_BLOCK 0x00000080 | ||
| 69 | |||
| 70 | /* | ||
| 71 | * flags in file.f_mode. Note that FMODE_READ and FMODE_WRITE must correspond | ||
| 72 | * to O_WRONLY and O_RDWR via the strange trick in __dentry_open() | ||
| 73 | */ | ||
| 74 | |||
| 75 | /* file is open for reading */ | ||
| 76 | #define FMODE_READ ((__force fmode_t)0x1) | ||
| 77 | /* file is open for writing */ | ||
| 78 | #define FMODE_WRITE ((__force fmode_t)0x2) | ||
| 79 | /* file is seekable */ | ||
| 80 | #define FMODE_LSEEK ((__force fmode_t)0x4) | ||
| 81 | /* file can be accessed using pread */ | ||
| 82 | #define FMODE_PREAD ((__force fmode_t)0x8) | ||
| 83 | /* file can be accessed using pwrite */ | ||
| 84 | #define FMODE_PWRITE ((__force fmode_t)0x10) | ||
| 85 | /* File is opened for execution with sys_execve / sys_uselib */ | ||
| 86 | #define FMODE_EXEC ((__force fmode_t)0x20) | ||
| 87 | /* File is opened with O_NDELAY (only set for block devices) */ | ||
| 88 | #define FMODE_NDELAY ((__force fmode_t)0x40) | ||
| 89 | /* File is opened with O_EXCL (only set for block devices) */ | ||
| 90 | #define FMODE_EXCL ((__force fmode_t)0x80) | ||
| 91 | /* File is opened using open(.., 3, ..) and is writeable only for ioctls | ||
| 92 | (specialy hack for floppy.c) */ | ||
| 93 | #define FMODE_WRITE_IOCTL ((__force fmode_t)0x100) | ||
| 94 | /* 32bit hashes as llseek() offset (for directories) */ | ||
| 95 | #define FMODE_32BITHASH ((__force fmode_t)0x200) | ||
| 96 | /* 64bit hashes as llseek() offset (for directories) */ | ||
| 97 | #define FMODE_64BITHASH ((__force fmode_t)0x400) | ||
| 98 | |||
| 99 | /* | ||
| 100 | * Don't update ctime and mtime. | ||
| 101 | * | ||
| 102 | * Currently a special hack for the XFS open_by_handle ioctl, but we'll | ||
| 103 | * hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon. | ||
| 104 | */ | ||
| 105 | #define FMODE_NOCMTIME ((__force fmode_t)0x800) | ||
| 106 | |||
| 107 | /* Expect random access pattern */ | ||
| 108 | #define FMODE_RANDOM ((__force fmode_t)0x1000) | ||
| 109 | |||
| 110 | /* File is huge (eg. /dev/kmem): treat loff_t as unsigned */ | ||
| 111 | #define FMODE_UNSIGNED_OFFSET ((__force fmode_t)0x2000) | ||
| 112 | |||
| 113 | /* File is opened with O_PATH; almost nothing can be done with it */ | ||
| 114 | #define FMODE_PATH ((__force fmode_t)0x4000) | ||
| 115 | |||
| 116 | /* File was opened by fanotify and shouldn't generate fanotify events */ | ||
| 117 | #define FMODE_NONOTIFY ((__force fmode_t)0x1000000) | ||
| 118 | |||
| 119 | /* | ||
| 120 | * Flag for rw_copy_check_uvector and compat_rw_copy_check_uvector | ||
| 121 | * that indicates that they should check the contents of the iovec are | ||
| 122 | * valid, but not check the memory that the iovec elements | ||
| 123 | * points too. | ||
| 124 | */ | ||
| 125 | #define CHECK_IOVEC_ONLY -1 | ||
| 126 | |||
| 127 | #define SEL_IN 1 | ||
| 128 | #define SEL_OUT 2 | ||
| 129 | #define SEL_EX 4 | ||
| 130 | |||
| 131 | /* public flags for file_system_type */ | ||
| 132 | #define FS_REQUIRES_DEV 1 | ||
| 133 | #define FS_BINARY_MOUNTDATA 2 | ||
| 134 | #define FS_HAS_SUBTYPE 4 | ||
| 135 | #define FS_REVAL_DOT 16384 /* Check the paths ".", ".." for staleness */ | ||
| 136 | #define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() | ||
| 137 | * during rename() internally. | ||
| 138 | */ | ||
| 139 | 60 | ||
| 140 | /* | 61 | /* |
| 141 | * These are the fs-independent mount-flags: up to 32 flags are supported | 62 | * These are the fs-independent mount-flags: up to 32 flags are supported |
| @@ -181,59 +102,6 @@ struct inodes_stat_t { | |||
| 181 | #define MS_MGC_VAL 0xC0ED0000 | 102 | #define MS_MGC_VAL 0xC0ED0000 |
| 182 | #define MS_MGC_MSK 0xffff0000 | 103 | #define MS_MGC_MSK 0xffff0000 |
| 183 | 104 | ||
| 184 | /* Inode flags - they have nothing to superblock flags now */ | ||
| 185 | |||
| 186 | #define S_SYNC 1 /* Writes are synced at once */ | ||
| 187 | #define S_NOATIME 2 /* Do not update access times */ | ||
| 188 | #define S_APPEND 4 /* Append-only file */ | ||
| 189 | #define S_IMMUTABLE 8 /* Immutable file */ | ||
| 190 | #define S_DEAD 16 /* removed, but still open directory */ | ||
| 191 | #define S_NOQUOTA 32 /* Inode is not counted to quota */ | ||
| 192 | #define S_DIRSYNC 64 /* Directory modifications are synchronous */ | ||
| 193 | #define S_NOCMTIME 128 /* Do not update file c/mtime */ | ||
| 194 | #define S_SWAPFILE 256 /* Do not truncate: swapon got its bmaps */ | ||
| 195 | #define S_PRIVATE 512 /* Inode is fs-internal */ | ||
| 196 | #define S_IMA 1024 /* Inode has an associated IMA struct */ | ||
| 197 | #define S_AUTOMOUNT 2048 /* Automount/referral quasi-directory */ | ||
| 198 | #define S_NOSEC 4096 /* no suid or xattr security attributes */ | ||
| 199 | |||
| 200 | /* | ||
| 201 | * Note that nosuid etc flags are inode-specific: setting some file-system | ||
| 202 | * flags just means all the inodes inherit those flags by default. It might be | ||
| 203 | * possible to override it selectively if you really wanted to with some | ||
| 204 | * ioctl() that is not currently implemented. | ||
| 205 | * | ||
| 206 | * Exception: MS_RDONLY is always applied to the entire file system. | ||
| 207 | * | ||
| 208 | * Unfortunately, it is possible to change a filesystems flags with it mounted | ||
| 209 | * with files in use. This means that all of the inodes will not have their | ||
| 210 | * i_flags updated. Hence, i_flags no longer inherit the superblock mount | ||
| 211 | * flags, so these have to be checked separately. -- rmk@arm.uk.linux.org | ||
| 212 | */ | ||
| 213 | #define __IS_FLG(inode,flg) ((inode)->i_sb->s_flags & (flg)) | ||
| 214 | |||
| 215 | #define IS_RDONLY(inode) ((inode)->i_sb->s_flags & MS_RDONLY) | ||
| 216 | #define IS_SYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS) || \ | ||
| 217 | ((inode)->i_flags & S_SYNC)) | ||
| 218 | #define IS_DIRSYNC(inode) (__IS_FLG(inode, MS_SYNCHRONOUS|MS_DIRSYNC) || \ | ||
| 219 | ((inode)->i_flags & (S_SYNC|S_DIRSYNC))) | ||
| 220 | #define IS_MANDLOCK(inode) __IS_FLG(inode, MS_MANDLOCK) | ||
| 221 | #define IS_NOATIME(inode) __IS_FLG(inode, MS_RDONLY|MS_NOATIME) | ||
| 222 | #define IS_I_VERSION(inode) __IS_FLG(inode, MS_I_VERSION) | ||
| 223 | |||
| 224 | #define IS_NOQUOTA(inode) ((inode)->i_flags & S_NOQUOTA) | ||
| 225 | #define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) | ||
| 226 | #define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) | ||
| 227 | #define IS_POSIXACL(inode) __IS_FLG(inode, MS_POSIXACL) | ||
| 228 | |||
| 229 | #define IS_DEADDIR(inode) ((inode)->i_flags & S_DEAD) | ||
| 230 | #define IS_NOCMTIME(inode) ((inode)->i_flags & S_NOCMTIME) | ||
| 231 | #define IS_SWAPFILE(inode) ((inode)->i_flags & S_SWAPFILE) | ||
| 232 | #define IS_PRIVATE(inode) ((inode)->i_flags & S_PRIVATE) | ||
| 233 | #define IS_IMA(inode) ((inode)->i_flags & S_IMA) | ||
| 234 | #define IS_AUTOMOUNT(inode) ((inode)->i_flags & S_AUTOMOUNT) | ||
| 235 | #define IS_NOSEC(inode) ((inode)->i_flags & S_NOSEC) | ||
| 236 | |||
| 237 | /* the read-only stuff doesn't really belong here, but any other place is | 105 | /* the read-only stuff doesn't really belong here, but any other place is |
| 238 | probably as bad and I don't want to create yet another include file. */ | 106 | probably as bad and I don't want to create yet another include file. */ |
| 239 | 107 | ||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 24ab4148547c..61a53367d029 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
| @@ -2132,18 +2132,14 @@ static inline void flush_unauthorized_files(const struct cred *cred, | |||
| 2132 | return; | 2132 | return; |
| 2133 | 2133 | ||
| 2134 | devnull = dentry_open(&selinux_null, O_RDWR, cred); | 2134 | devnull = dentry_open(&selinux_null, O_RDWR, cred); |
| 2135 | if (!IS_ERR(devnull)) { | 2135 | if (IS_ERR(devnull)) |
| 2136 | /* replace all the matching ones with this */ | 2136 | devnull = NULL; |
| 2137 | do { | 2137 | /* replace all the matching ones with this */ |
| 2138 | replace_fd(n - 1, get_file(devnull), 0); | 2138 | do { |
| 2139 | } while ((n = iterate_fd(files, n, match_file, cred)) != 0); | 2139 | replace_fd(n - 1, devnull, 0); |
| 2140 | } while ((n = iterate_fd(files, n, match_file, cred)) != 0); | ||
| 2141 | if (devnull) | ||
| 2140 | fput(devnull); | 2142 | fput(devnull); |
| 2141 | } else { | ||
| 2142 | /* just close all the matching ones */ | ||
| 2143 | do { | ||
| 2144 | replace_fd(n - 1, NULL, 0); | ||
| 2145 | } while ((n = iterate_fd(files, n, match_file, cred)) != 0); | ||
| 2146 | } | ||
| 2147 | } | 2143 | } |
| 2148 | 2144 | ||
| 2149 | /* | 2145 | /* |
