Skip to content

Commit 39030e1

Browse files
thomas-cedenomicah-morton
authored andcommitted
security: Add LSM hooks to set*gid syscalls
The SafeSetID LSM uses the security_task_fix_setuid hook to filter set*uid() syscalls according to its configured security policy. In preparation for adding analagous support in the LSM for set*gid() syscalls, we add the requisite hook here. Tested by putting print statements in the security_task_fix_setgid hook and seeing them get hit during kernel boot. Signed-off-by: Thomas Cedeno <[email protected]> Signed-off-by: Micah Morton <[email protected]>
1 parent 3d77e6a commit 39030e1

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

include/linux/lsm_hook_defs.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,8 @@ LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf,
190190
loff_t size, enum kernel_read_file_id id)
191191
LSM_HOOK(int, 0, task_fix_setuid, struct cred *new, const struct cred *old,
192192
int flags)
193+
LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old,
194+
int flags)
193195
LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
194196
LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
195197
LSM_HOOK(int, 0, task_getsid, struct task_struct *p)

include/linux/lsm_hooks.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -651,6 +651,15 @@
651651
* @old is the set of credentials that are being replaces
652652
* @flags contains one of the LSM_SETID_* values.
653653
* Return 0 on success.
654+
* @task_fix_setgid:
655+
* Update the module's state after setting one or more of the group
656+
* identity attributes of the current process. The @flags parameter
657+
* indicates which of the set*gid system calls invoked this hook.
658+
* @new is the set of credentials that will be installed. Modifications
659+
* should be made to this rather than to @current->cred.
660+
* @old is the set of credentials that are being replaced.
661+
* @flags contains one of the LSM_SETID_* values.
662+
* Return 0 on success.
654663
* @task_setpgid:
655664
* Check permission before setting the process group identifier of the
656665
* process @p to @pgid.

include/linux/security.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,8 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
389389
enum kernel_read_file_id id);
390390
int security_task_fix_setuid(struct cred *new, const struct cred *old,
391391
int flags);
392+
int security_task_fix_setgid(struct cred *new, const struct cred *old,
393+
int flags);
392394
int security_task_setpgid(struct task_struct *p, pid_t pgid);
393395
int security_task_getpgid(struct task_struct *p);
394396
int security_task_getsid(struct task_struct *p);
@@ -1027,6 +1029,13 @@ static inline int security_task_fix_setuid(struct cred *new,
10271029
return cap_task_fix_setuid(new, old, flags);
10281030
}
10291031

1032+
static inline int security_task_fix_setgid(struct cred *new,
1033+
const struct cred *old,
1034+
int flags)
1035+
{
1036+
return 0;
1037+
}
1038+
10301039
static inline int security_task_setpgid(struct task_struct *p, pid_t pgid)
10311040
{
10321041
return 0;

kernel/sys.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,6 +393,10 @@ long __sys_setregid(gid_t rgid, gid_t egid)
393393
new->sgid = new->egid;
394394
new->fsgid = new->egid;
395395

396+
retval = security_task_fix_setgid(new, old, LSM_SETID_RE);
397+
if (retval < 0)
398+
goto error;
399+
396400
return commit_creds(new);
397401

398402
error:
@@ -435,6 +439,10 @@ long __sys_setgid(gid_t gid)
435439
else
436440
goto error;
437441

442+
retval = security_task_fix_setgid(new, old, LSM_SETID_ID);
443+
if (retval < 0)
444+
goto error;
445+
438446
return commit_creds(new);
439447

440448
error:
@@ -756,6 +764,10 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
756764
new->sgid = ksgid;
757765
new->fsgid = new->egid;
758766

767+
retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
768+
if (retval < 0)
769+
goto error;
770+
759771
return commit_creds(new);
760772

761773
error:
@@ -862,7 +874,8 @@ long __sys_setfsgid(gid_t gid)
862874
ns_capable(old->user_ns, CAP_SETGID)) {
863875
if (!gid_eq(kgid, old->fsgid)) {
864876
new->fsgid = kgid;
865-
goto change_okay;
877+
if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
878+
goto change_okay;
866879
}
867880
}
868881

security/security.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1685,6 +1685,12 @@ int security_task_fix_setuid(struct cred *new, const struct cred *old,
16851685
return call_int_hook(task_fix_setuid, 0, new, old, flags);
16861686
}
16871687

1688+
int security_task_fix_setgid(struct cred *new, const struct cred *old,
1689+
int flags)
1690+
{
1691+
return call_int_hook(task_fix_setgid, 0, new, old, flags);
1692+
}
1693+
16881694
int security_task_setpgid(struct task_struct *p, pid_t pgid)
16891695
{
16901696
return call_int_hook(task_setpgid, 0, p, pgid);

0 commit comments

Comments
 (0)