aboutsummaryrefslogtreecommitdiffstats
path: root/security/selinux/hooks.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/selinux/hooks.c')
-rw-r--r--security/selinux/hooks.c283
1 files changed, 118 insertions, 165 deletions
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index c71bba78872f..21a592184633 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2029,59 +2029,45 @@ static int selinux_vm_enough_memory(struct mm_struct *mm, long pages)
2029 2029
2030/* binprm security operations */ 2030/* binprm security operations */
2031 2031
2032static int selinux_bprm_alloc_security(struct linux_binprm *bprm) 2032static int selinux_bprm_set_creds(struct linux_binprm *bprm)
2033{ 2033{
2034 struct bprm_security_struct *bsec; 2034 const struct task_security_struct *old_tsec;
2035 2035 struct task_security_struct *new_tsec;
2036 bsec = kzalloc(sizeof(struct bprm_security_struct), GFP_KERNEL);
2037 if (!bsec)
2038 return -ENOMEM;
2039
2040 bsec->sid = SECINITSID_UNLABELED;
2041 bsec->set = 0;
2042
2043 bprm->security = bsec;
2044 return 0;
2045}
2046
2047static int selinux_bprm_set_security(struct linux_binprm *bprm)
2048{
2049 struct task_security_struct *tsec;
2050 struct inode *inode = bprm->file->f_path.dentry->d_inode;
2051 struct inode_security_struct *isec; 2036 struct inode_security_struct *isec;
2052 struct bprm_security_struct *bsec;
2053 u32 newsid;
2054 struct avc_audit_data ad; 2037 struct avc_audit_data ad;
2038 struct inode *inode = bprm->file->f_path.dentry->d_inode;
2055 int rc; 2039 int rc;
2056 2040
2057 rc = secondary_ops->bprm_set_security(bprm); 2041 rc = secondary_ops->bprm_set_creds(bprm);
2058 if (rc) 2042 if (rc)
2059 return rc; 2043 return rc;
2060 2044
2061 bsec = bprm->security; 2045 /* SELinux context only depends on initial program or script and not
2062 2046 * the script interpreter */
2063 if (bsec->set) 2047 if (bprm->cred_prepared)
2064 return 0; 2048 return 0;
2065 2049
2066 tsec = current_security(); 2050 old_tsec = current_security();
2051 new_tsec = bprm->cred->security;
2067 isec = inode->i_security; 2052 isec = inode->i_security;
2068 2053
2069 /* Default to the current task SID. */ 2054 /* Default to the current task SID. */
2070 bsec->sid = tsec->sid; 2055 new_tsec->sid = old_tsec->sid;
2056 new_tsec->osid = old_tsec->sid;
2071 2057
2072 /* Reset fs, key, and sock SIDs on execve. */ 2058 /* Reset fs, key, and sock SIDs on execve. */
2073 tsec->create_sid = 0; 2059 new_tsec->create_sid = 0;
2074 tsec->keycreate_sid = 0; 2060 new_tsec->keycreate_sid = 0;
2075 tsec->sockcreate_sid = 0; 2061 new_tsec->sockcreate_sid = 0;
2076 2062
2077 if (tsec->exec_sid) { 2063 if (old_tsec->exec_sid) {
2078 newsid = tsec->exec_sid; 2064 new_tsec->sid = old_tsec->exec_sid;
2079 /* Reset exec SID on execve. */ 2065 /* Reset exec SID on execve. */
2080 tsec->exec_sid = 0; 2066 new_tsec->exec_sid = 0;
2081 } else { 2067 } else {
2082 /* Check for a default transition on this program. */ 2068 /* Check for a default transition on this program. */
2083 rc = security_transition_sid(tsec->sid, isec->sid, 2069 rc = security_transition_sid(old_tsec->sid, isec->sid,
2084 SECCLASS_PROCESS, &newsid); 2070 SECCLASS_PROCESS, &new_tsec->sid);
2085 if (rc) 2071 if (rc)
2086 return rc; 2072 return rc;
2087 } 2073 }
@@ -2090,33 +2076,63 @@ static int selinux_bprm_set_security(struct linux_binprm *bprm)
2090 ad.u.fs.path = bprm->file->f_path; 2076 ad.u.fs.path = bprm->file->f_path;
2091 2077
2092 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) 2078 if (bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID)
2093 newsid = tsec->sid; 2079 new_tsec->sid = old_tsec->sid;
2094 2080
2095 if (tsec->sid == newsid) { 2081 if (new_tsec->sid == old_tsec->sid) {
2096 rc = avc_has_perm(tsec->sid, isec->sid, 2082 rc = avc_has_perm(old_tsec->sid, isec->sid,
2097 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad); 2083 SECCLASS_FILE, FILE__EXECUTE_NO_TRANS, &ad);
2098 if (rc) 2084 if (rc)
2099 return rc; 2085 return rc;
2100 } else { 2086 } else {
2101 /* Check permissions for the transition. */ 2087 /* Check permissions for the transition. */
2102 rc = avc_has_perm(tsec->sid, newsid, 2088 rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
2103 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad); 2089 SECCLASS_PROCESS, PROCESS__TRANSITION, &ad);
2104 if (rc) 2090 if (rc)
2105 return rc; 2091 return rc;
2106 2092
2107 rc = avc_has_perm(newsid, isec->sid, 2093 rc = avc_has_perm(new_tsec->sid, isec->sid,
2108 SECCLASS_FILE, FILE__ENTRYPOINT, &ad); 2094 SECCLASS_FILE, FILE__ENTRYPOINT, &ad);
2109 if (rc) 2095 if (rc)
2110 return rc; 2096 return rc;
2111 2097
2112 /* Clear any possibly unsafe personality bits on exec: */ 2098 /* Check for shared state */
2113 current->personality &= ~PER_CLEAR_ON_SETID; 2099 if (bprm->unsafe & LSM_UNSAFE_SHARE) {
2100 rc = avc_has_perm(old_tsec->sid, new_tsec->sid,
2101 SECCLASS_PROCESS, PROCESS__SHARE,
2102 NULL);
2103 if (rc)
2104 return -EPERM;
2105 }
2106
2107 /* Make sure that anyone attempting to ptrace over a task that
2108 * changes its SID has the appropriate permit */
2109 if (bprm->unsafe &
2110 (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
2111 struct task_struct *tracer;
2112 struct task_security_struct *sec;
2113 u32 ptsid = 0;
2114
2115 rcu_read_lock();
2116 tracer = tracehook_tracer_task(current);
2117 if (likely(tracer != NULL)) {
2118 sec = __task_cred(tracer)->security;
2119 ptsid = sec->sid;
2120 }
2121 rcu_read_unlock();
2122
2123 if (ptsid != 0) {
2124 rc = avc_has_perm(ptsid, new_tsec->sid,
2125 SECCLASS_PROCESS,
2126 PROCESS__PTRACE, NULL);
2127 if (rc)
2128 return -EPERM;
2129 }
2130 }
2114 2131
2115 /* Set the security field to the new SID. */ 2132 /* Clear any possibly unsafe personality bits on exec: */
2116 bsec->sid = newsid; 2133 bprm->per_clear |= PER_CLEAR_ON_SETID;
2117 } 2134 }
2118 2135
2119 bsec->set = 1;
2120 return 0; 2136 return 0;
2121} 2137}
2122 2138
@@ -2125,7 +2141,6 @@ static int selinux_bprm_check_security(struct linux_binprm *bprm)
2125 return secondary_ops->bprm_check_security(bprm); 2141 return secondary_ops->bprm_check_security(bprm);
2126} 2142}
2127 2143
2128
2129static int selinux_bprm_secureexec(struct linux_binprm *bprm) 2144static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2130{ 2145{
2131 const struct cred *cred = current_cred(); 2146 const struct cred *cred = current_cred();
@@ -2141,19 +2156,13 @@ static int selinux_bprm_secureexec(struct linux_binprm *bprm)
2141 the noatsecure permission is granted between 2156 the noatsecure permission is granted between
2142 the two SIDs, i.e. ahp returns 0. */ 2157 the two SIDs, i.e. ahp returns 0. */
2143 atsecure = avc_has_perm(osid, sid, 2158 atsecure = avc_has_perm(osid, sid,
2144 SECCLASS_PROCESS, 2159 SECCLASS_PROCESS,
2145 PROCESS__NOATSECURE, NULL); 2160 PROCESS__NOATSECURE, NULL);
2146 } 2161 }
2147 2162
2148 return (atsecure || secondary_ops->bprm_secureexec(bprm)); 2163 return (atsecure || secondary_ops->bprm_secureexec(bprm));
2149} 2164}
2150 2165
2151static void selinux_bprm_free_security(struct linux_binprm *bprm)
2152{
2153 kfree(bprm->security);
2154 bprm->security = NULL;
2155}
2156
2157extern struct vfsmount *selinuxfs_mount; 2166extern struct vfsmount *selinuxfs_mount;
2158extern struct dentry *selinux_null; 2167extern struct dentry *selinux_null;
2159 2168
@@ -2252,108 +2261,78 @@ static inline void flush_unauthorized_files(const struct cred *cred,
2252 spin_unlock(&files->file_lock); 2261 spin_unlock(&files->file_lock);
2253} 2262}
2254 2263
2255static int selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe) 2264/*
2265 * Prepare a process for imminent new credential changes due to exec
2266 */
2267static void selinux_bprm_committing_creds(struct linux_binprm *bprm)
2256{ 2268{
2257 struct task_security_struct *tsec; 2269 struct task_security_struct *new_tsec;
2258 struct bprm_security_struct *bsec; 2270 struct rlimit *rlim, *initrlim;
2259 struct cred *new; 2271 int rc, i;
2260 u32 sid;
2261 int rc;
2262
2263 rc = secondary_ops->bprm_apply_creds(bprm, unsafe);
2264 if (rc < 0)
2265 return rc;
2266
2267 new = prepare_creds();
2268 if (!new)
2269 return -ENOMEM;
2270 2272
2271 tsec = new->security; 2273 secondary_ops->bprm_committing_creds(bprm);
2272 2274
2273 bsec = bprm->security; 2275 new_tsec = bprm->cred->security;
2274 sid = bsec->sid; 2276 if (new_tsec->sid == new_tsec->osid)
2275 2277 return;
2276 tsec->osid = tsec->sid;
2277 bsec->unsafe = 0;
2278 if (tsec->sid != sid) {
2279 /* Check for shared state. If not ok, leave SID
2280 unchanged and kill. */
2281 if (unsafe & LSM_UNSAFE_SHARE) {
2282 rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
2283 PROCESS__SHARE, NULL);
2284 if (rc) {
2285 bsec->unsafe = 1;
2286 goto out;
2287 }
2288 }
2289 2278
2290 /* Check for ptracing, and update the task SID if ok. 2279 /* Close files for which the new task SID is not authorized. */
2291 Otherwise, leave SID unchanged and kill. */ 2280 flush_unauthorized_files(bprm->cred, current->files);
2292 if (unsafe & (LSM_UNSAFE_PTRACE | LSM_UNSAFE_PTRACE_CAP)) {
2293 struct task_struct *tracer;
2294 struct task_security_struct *sec;
2295 u32 ptsid = 0;
2296 2281
2297 rcu_read_lock(); 2282 /* Always clear parent death signal on SID transitions. */
2298 tracer = tracehook_tracer_task(current); 2283 current->pdeath_signal = 0;
2299 if (likely(tracer != NULL)) {
2300 sec = __task_cred(tracer)->security;
2301 ptsid = sec->sid;
2302 }
2303 rcu_read_unlock();
2304 2284
2305 if (ptsid != 0) { 2285 /* Check whether the new SID can inherit resource limits from the old
2306 rc = avc_has_perm(ptsid, sid, SECCLASS_PROCESS, 2286 * SID. If not, reset all soft limits to the lower of the current
2307 PROCESS__PTRACE, NULL); 2287 * task's hard limit and the init task's soft limit.
2308 if (rc) { 2288 *
2309 bsec->unsafe = 1; 2289 * Note that the setting of hard limits (even to lower them) can be
2310 goto out; 2290 * controlled by the setrlimit check. The inclusion of the init task's
2311 } 2291 * soft limit into the computation is to avoid resetting soft limits
2312 } 2292 * higher than the default soft limit for cases where the default is
2293 * lower than the hard limit, e.g. RLIMIT_CORE or RLIMIT_STACK.
2294 */
2295 rc = avc_has_perm(new_tsec->osid, new_tsec->sid, SECCLASS_PROCESS,
2296 PROCESS__RLIMITINH, NULL);
2297 if (rc) {
2298 for (i = 0; i < RLIM_NLIMITS; i++) {
2299 rlim = current->signal->rlim + i;
2300 initrlim = init_task.signal->rlim + i;
2301 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2313 } 2302 }
2314 tsec->sid = sid; 2303 update_rlimit_cpu(rlim->rlim_cur);
2315 } 2304 }
2316
2317out:
2318 commit_creds(new);
2319 return 0;
2320} 2305}
2321 2306
2322/* 2307/*
2323 * called after apply_creds without the task lock held 2308 * Clean up the process immediately after the installation of new credentials
2309 * due to exec
2324 */ 2310 */
2325static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm) 2311static void selinux_bprm_committed_creds(struct linux_binprm *bprm)
2326{ 2312{
2327 const struct cred *cred = current_cred(); 2313 const struct task_security_struct *tsec = current_security();
2328 struct task_security_struct *tsec;
2329 struct rlimit *rlim, *initrlim;
2330 struct itimerval itimer; 2314 struct itimerval itimer;
2331 struct bprm_security_struct *bsec;
2332 struct sighand_struct *psig; 2315 struct sighand_struct *psig;
2316 u32 osid, sid;
2333 int rc, i; 2317 int rc, i;
2334 unsigned long flags; 2318 unsigned long flags;
2335 2319
2336 tsec = current_security(); 2320 secondary_ops->bprm_committed_creds(bprm);
2337 bsec = bprm->security;
2338 2321
2339 if (bsec->unsafe) { 2322 osid = tsec->osid;
2340 force_sig_specific(SIGKILL, current); 2323 sid = tsec->sid;
2341 return; 2324
2342 } 2325 if (sid == osid)
2343 if (tsec->osid == tsec->sid)
2344 return; 2326 return;
2345 2327
2346 /* Close files for which the new task SID is not authorized. */ 2328 /* Check whether the new SID can inherit signal state from the old SID.
2347 flush_unauthorized_files(cred, current->files); 2329 * If not, clear itimers to avoid subsequent signal generation and
2348 2330 * flush and unblock signals.
2349 /* Check whether the new SID can inherit signal state 2331 *
2350 from the old SID. If not, clear itimers to avoid 2332 * This must occur _after_ the task SID has been updated so that any
2351 subsequent signal generation and flush and unblock 2333 * kill done after the flush will be checked against the new SID.
2352 signals. This must occur _after_ the task SID has 2334 */
2353 been updated so that any kill done after the flush 2335 rc = avc_has_perm(osid, sid, SECCLASS_PROCESS, PROCESS__SIGINH, NULL);
2354 will be checked against the new SID. */
2355 rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
2356 PROCESS__SIGINH, NULL);
2357 if (rc) { 2336 if (rc) {
2358 memset(&itimer, 0, sizeof itimer); 2337 memset(&itimer, 0, sizeof itimer);
2359 for (i = 0; i < 3; i++) 2338 for (i = 0; i < 3; i++)
@@ -2366,32 +2345,8 @@ static void selinux_bprm_post_apply_creds(struct linux_binprm *bprm)
2366 spin_unlock_irq(&current->sighand->siglock); 2345 spin_unlock_irq(&current->sighand->siglock);
2367 } 2346 }
2368 2347
2369 /* Always clear parent death signal on SID transitions. */ 2348 /* Wake up the parent if it is waiting so that it can recheck
2370 current->pdeath_signal = 0; 2349 * wait permission to the new task SID. */
2371
2372 /* Check whether the new SID can inherit resource limits
2373 from the old SID. If not, reset all soft limits to
2374 the lower of the current task's hard limit and the init
2375 task's soft limit. Note that the setting of hard limits
2376 (even to lower them) can be controlled by the setrlimit
2377 check. The inclusion of the init task's soft limit into
2378 the computation is to avoid resetting soft limits higher
2379 than the default soft limit for cases where the default
2380 is lower than the hard limit, e.g. RLIMIT_CORE or
2381 RLIMIT_STACK.*/
2382 rc = avc_has_perm(tsec->osid, tsec->sid, SECCLASS_PROCESS,
2383 PROCESS__RLIMITINH, NULL);
2384 if (rc) {
2385 for (i = 0; i < RLIM_NLIMITS; i++) {
2386 rlim = current->signal->rlim + i;
2387 initrlim = init_task.signal->rlim+i;
2388 rlim->rlim_cur = min(rlim->rlim_max, initrlim->rlim_cur);
2389 }
2390 update_rlimit_cpu(rlim->rlim_cur);
2391 }
2392
2393 /* Wake up the parent if it is waiting so that it can
2394 recheck wait permission to the new task SID. */
2395 read_lock_irq(&tasklist_lock); 2350 read_lock_irq(&tasklist_lock);
2396 psig = current->parent->sighand; 2351 psig = current->parent->sighand;
2397 spin_lock_irqsave(&psig->siglock, flags); 2352 spin_lock_irqsave(&psig->siglock, flags);
@@ -5556,12 +5511,10 @@ static struct security_operations selinux_ops = {
5556 .netlink_send = selinux_netlink_send, 5511 .netlink_send = selinux_netlink_send,
5557 .netlink_recv = selinux_netlink_recv, 5512 .netlink_recv = selinux_netlink_recv,
5558 5513
5559 .bprm_alloc_security = selinux_bprm_alloc_security, 5514 .bprm_set_creds = selinux_bprm_set_creds,
5560 .bprm_free_security = selinux_bprm_free_security,
5561 .bprm_apply_creds = selinux_bprm_apply_creds,
5562 .bprm_post_apply_creds = selinux_bprm_post_apply_creds,
5563 .bprm_set_security = selinux_bprm_set_security,
5564 .bprm_check_security = selinux_bprm_check_security, 5515 .bprm_check_security = selinux_bprm_check_security,
5516 .bprm_committing_creds = selinux_bprm_committing_creds,
5517 .bprm_committed_creds = selinux_bprm_committed_creds,
5565 .bprm_secureexec = selinux_bprm_secureexec, 5518 .bprm_secureexec = selinux_bprm_secureexec,
5566 5519
5567 .sb_alloc_security = selinux_sb_alloc_security, 5520 .sb_alloc_security = selinux_sb_alloc_security,