security: Add LSM hooks to set*gid syscalls
authorThomas Cedeno <thomascedeno@google.com>
Tue, 9 Jun 2020 17:22:13 +0000 (10:22 -0700)
committerMicah Morton <mortonm@chromium.org>
Sun, 14 Jun 2020 17:52:02 +0000 (10:52 -0700)
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 <thomascedeno@google.com>
Signed-off-by: Micah Morton <mortonm@chromium.org>
include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
include/linux/security.h
kernel/sys.c
security/security.c

index 5616b25..2a5a53a 100644 (file)
@@ -190,6 +190,8 @@ LSM_HOOK(int, 0, kernel_post_read_file, struct file *file, char *buf,
         loff_t size, enum kernel_read_file_id id)
 LSM_HOOK(int, 0, task_fix_setuid, struct cred *new, const struct cred *old,
         int flags)
+LSM_HOOK(int, 0, task_fix_setgid, struct cred *new, const struct cred * old,
+        int flags)
 LSM_HOOK(int, 0, task_setpgid, struct task_struct *p, pid_t pgid)
 LSM_HOOK(int, 0, task_getpgid, struct task_struct *p)
 LSM_HOOK(int, 0, task_getsid, struct task_struct *p)
index 988ca0d..b20132b 100644 (file)
  *     @old is the set of credentials that are being replaces
  *     @flags contains one of the LSM_SETID_* values.
  *     Return 0 on success.
+ * @task_fix_setgid:
+ *     Update the module's state after setting one or more of the group
+ *     identity attributes of the current process.  The @flags parameter
+ *     indicates which of the set*gid system calls invoked this hook.
+ *     @new is the set of credentials that will be installed.  Modifications
+ *     should be made to this rather than to @current->cred.
+ *     @old is the set of credentials that are being replaced.
+ *     @flags contains one of the LSM_SETID_* values.
+ *     Return 0 on success.
  * @task_setpgid:
  *     Check permission before setting the process group identifier of the
  *     process @p to @pgid.
index a8d9310..88749bf 100644 (file)
@@ -389,6 +389,8 @@ int security_kernel_post_read_file(struct file *file, char *buf, loff_t size,
                                   enum kernel_read_file_id id);
 int security_task_fix_setuid(struct cred *new, const struct cred *old,
                             int flags);
+int security_task_fix_setgid(struct cred *new, const struct cred *old,
+                            int flags);
 int security_task_setpgid(struct task_struct *p, pid_t pgid);
 int security_task_getpgid(struct task_struct *p);
 int security_task_getsid(struct task_struct *p);
@@ -1027,6 +1029,13 @@ static inline int security_task_fix_setuid(struct cred *new,
        return cap_task_fix_setuid(new, old, flags);
 }
 
+static inline int security_task_fix_setgid(struct cred *new,
+                                          const struct cred *old,
+                                          int flags)
+{
+       return 0;
+}
+
 static inline int security_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return 0;
index d325f3a..f5c06c4 100644 (file)
@@ -393,6 +393,10 @@ long __sys_setregid(gid_t rgid, gid_t egid)
                new->sgid = new->egid;
        new->fsgid = new->egid;
 
+       retval = security_task_fix_setgid(new, old, LSM_SETID_RE);
+       if (retval < 0)
+               goto error;
+
        return commit_creds(new);
 
 error:
@@ -435,6 +439,10 @@ long __sys_setgid(gid_t gid)
        else
                goto error;
 
+       retval = security_task_fix_setgid(new, old, LSM_SETID_ID);
+       if (retval < 0)
+               goto error;
+
        return commit_creds(new);
 
 error:
@@ -756,6 +764,10 @@ long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
                new->sgid = ksgid;
        new->fsgid = new->egid;
 
+       retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
+       if (retval < 0)
+               goto error;
+
        return commit_creds(new);
 
 error:
@@ -862,7 +874,8 @@ long __sys_setfsgid(gid_t gid)
            ns_capable(old->user_ns, CAP_SETGID)) {
                if (!gid_eq(kgid, old->fsgid)) {
                        new->fsgid = kgid;
-                       goto change_okay;
+                       if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
+                               goto change_okay;
                }
        }
 
index 51de970..5d4ad6f 100644 (file)
@@ -1685,6 +1685,12 @@ int security_task_fix_setuid(struct cred *new, const struct cred *old,
        return call_int_hook(task_fix_setuid, 0, new, old, flags);
 }
 
+int security_task_fix_setgid(struct cred *new, const struct cred *old,
+                                int flags)
+{
+       return call_int_hook(task_fix_setgid, 0, new, old, flags);
+}
+
 int security_task_setpgid(struct task_struct *p, pid_t pgid)
 {
        return call_int_hook(task_setpgid, 0, p, pgid);