diff options
Diffstat (limited to 'recipes-kernel/linux/linux-hierofalcon-3.19')
-rw-r--r-- | recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch b/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch new file mode 100644 index 0000000..ec86cb8 --- /dev/null +++ b/recipes-kernel/linux/linux-hierofalcon-3.19/fs-CVE-2015-3339.patch | |||
@@ -0,0 +1,121 @@ | |||
1 | Date: Sun, 19 Apr 2015 02:48:39 +0200 | ||
2 | Subject: fs: take i_mutex during prepare_binprm for set[ug]id executables | ||
3 | |||
4 | [ Upstream commit 8b01fc86b9f425899f8a3a8fc1c47d73c2c20543 ] | ||
5 | |||
6 | This prevents a race between chown() and execve(), where chowning a | ||
7 | setuid-user binary to root would momentarily make the binary setuid | ||
8 | root. | ||
9 | |||
10 | This patch was mostly written by Linus Torvalds. | ||
11 | |||
12 | Fixes CVE-2015-3339. | ||
13 | Upstream-Status: Backport | ||
14 | |||
15 | Signed-off-by: Jann Horn <jann@thejh.net> | ||
16 | Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> | ||
17 | Signed-off-by: Sasha Levin <sasha.levin@oracle.com> | ||
18 | Signed-off-by: Sona Sarmadi <sona.sarmadi@enea.com> | ||
19 | --- | ||
20 | fs/exec.c | 76 ++++++++++++++++++++++++++++++++++++++++----------------------- | ||
21 | 1 file changed, 48 insertions(+), 28 deletions(-) | ||
22 | |||
23 | diff --git a/fs/exec.c b/fs/exec.c | ||
24 | index 7302b75..2e83209 100644 | ||
25 | --- a/fs/exec.c | ||
26 | +++ b/fs/exec.c | ||
27 | @@ -1250,6 +1250,53 @@ static void check_unsafe_exec(struct linux_binprm *bprm) | ||
28 | spin_unlock(&p->fs->lock); | ||
29 | } | ||
30 | |||
31 | +static void bprm_fill_uid(struct linux_binprm *bprm) | ||
32 | +{ | ||
33 | + struct inode *inode; | ||
34 | + unsigned int mode; | ||
35 | + kuid_t uid; | ||
36 | + kgid_t gid; | ||
37 | + | ||
38 | + /* clear any previous set[ug]id data from a previous binary */ | ||
39 | + bprm->cred->euid = current_euid(); | ||
40 | + bprm->cred->egid = current_egid(); | ||
41 | + | ||
42 | + if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) | ||
43 | + return; | ||
44 | + | ||
45 | + if (task_no_new_privs(current)) | ||
46 | + return; | ||
47 | + | ||
48 | + inode = file_inode(bprm->file); | ||
49 | + mode = READ_ONCE(inode->i_mode); | ||
50 | + if (!(mode & (S_ISUID|S_ISGID))) | ||
51 | + return; | ||
52 | + | ||
53 | + /* Be careful if suid/sgid is set */ | ||
54 | + mutex_lock(&inode->i_mutex); | ||
55 | + | ||
56 | + /* reload atomically mode/uid/gid now that lock held */ | ||
57 | + mode = inode->i_mode; | ||
58 | + uid = inode->i_uid; | ||
59 | + gid = inode->i_gid; | ||
60 | + mutex_unlock(&inode->i_mutex); | ||
61 | + | ||
62 | + /* We ignore suid/sgid if there are no mappings for them in the ns */ | ||
63 | + if (!kuid_has_mapping(bprm->cred->user_ns, uid) || | ||
64 | + !kgid_has_mapping(bprm->cred->user_ns, gid)) | ||
65 | + return; | ||
66 | + | ||
67 | + if (mode & S_ISUID) { | ||
68 | + bprm->per_clear |= PER_CLEAR_ON_SETID; | ||
69 | + bprm->cred->euid = uid; | ||
70 | + } | ||
71 | + | ||
72 | + if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | ||
73 | + bprm->per_clear |= PER_CLEAR_ON_SETID; | ||
74 | + bprm->cred->egid = gid; | ||
75 | + } | ||
76 | +} | ||
77 | + | ||
78 | /* | ||
79 | * Fill the binprm structure from the inode. | ||
80 | * Check permissions, then read the first 128 (BINPRM_BUF_SIZE) bytes | ||
81 | @@ -1258,36 +1305,9 @@ static void check_unsafe_exec(struct linux_binprm *bprm) | ||
82 | */ | ||
83 | int prepare_binprm(struct linux_binprm *bprm) | ||
84 | { | ||
85 | - struct inode *inode = file_inode(bprm->file); | ||
86 | - umode_t mode = inode->i_mode; | ||
87 | int retval; | ||
88 | |||
89 | - | ||
90 | - /* clear any previous set[ug]id data from a previous binary */ | ||
91 | - bprm->cred->euid = current_euid(); | ||
92 | - bprm->cred->egid = current_egid(); | ||
93 | - | ||
94 | - if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && | ||
95 | - !task_no_new_privs(current) && | ||
96 | - kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && | ||
97 | - kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { | ||
98 | - /* Set-uid? */ | ||
99 | - if (mode & S_ISUID) { | ||
100 | - bprm->per_clear |= PER_CLEAR_ON_SETID; | ||
101 | - bprm->cred->euid = inode->i_uid; | ||
102 | - } | ||
103 | - | ||
104 | - /* Set-gid? */ | ||
105 | - /* | ||
106 | - * If setgid is set but no group execute bit then this | ||
107 | - * is a candidate for mandatory locking, not a setgid | ||
108 | - * executable. | ||
109 | - */ | ||
110 | - if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) { | ||
111 | - bprm->per_clear |= PER_CLEAR_ON_SETID; | ||
112 | - bprm->cred->egid = inode->i_gid; | ||
113 | - } | ||
114 | - } | ||
115 | + bprm_fill_uid(bprm); | ||
116 | |||
117 | /* fill in binprm security blob */ | ||
118 | retval = security_bprm_set_creds(bprm); | ||
119 | -- | ||
120 | cgit v0.11.2 | ||
121 | |||