Merge tag 'LSM-add-setgid-hook-5.8-author-fix' of git://github.com/micah-morton/linux
authorLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Jun 2020 18:39:31 +0000 (11:39 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sun, 14 Jun 2020 18:39:31 +0000 (11:39 -0700)
Pull SafeSetID update from Micah Morton:
 "Add additional LSM hooks for SafeSetID

  SafeSetID is capable of making allow/deny decisions for set*uid calls
  on a system, and we want to add similar functionality for set*gid
  calls.

  The work to do that is not yet complete, so probably won't make it in
  for v5.8, but we are looking to get this simple patch in for v5.8
  since we have it ready.

  We are planning on the rest of the work for extending the SafeSetID
  LSM being merged during the v5.9 merge window"

* tag 'LSM-add-setgid-hook-5.8-author-fix' of git://github.com/micah-morton/linux:
  security: Add LSM hooks to set*gid syscalls

include/linux/lsm_hook_defs.h
include/linux/lsm_hooks.h
include/linux/security.h
kernel/sys.c
security/security.c

index 4a3d70baa7f11deaf15622f758e54ad88d182808..6791813cd439c085ea9703d30b176fc08147f9b0 100644 (file)
@@ -191,6 +191,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 73d87955e26b8f3d897c066ffe1070b39df98944..95b7c1d320621824a4b4f8c73edc5718a0c89c8d 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 469fa91f8cf8c2c0d67b6a77089973903b49e7ef..0a0a03b36a3bb178c5ff62cfd96cc7973c4412cb 100644 (file)
@@ -392,6 +392,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);
@@ -1036,6 +1038,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 fd46865b46bae4e4727b891e481ec90c63e9fac1..00a96746e28a5b1ae19bb2508f93476a943406bb 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 2a652e59c413f6d85644d48a7541a8122b6535db..0ce3e73edd4227cc2b76b40a34b79e7945cd0190 100644 (file)
@@ -1696,6 +1696,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);