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)
 
  *     @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.
 
                                   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);
        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;
 
                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:
        else
                goto error;
 
+       retval = security_task_fix_setgid(new, old, LSM_SETID_ID);
+       if (retval < 0)
+               goto error;
+
        return commit_creds(new);
 
 error:
                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:
            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;
                }
        }
 
 
        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);