mac80211: fix ibss race
[safe/jmp/linux-2.6] / net / core / scm.c
index 4681d8f..b7ba91b 100644 (file)
 
 static __inline__ int scm_check_creds(struct ucred *creds)
 {
+       const struct cred *cred = current_cred();
+
        if ((creds->pid == task_tgid_vnr(current) || capable(CAP_SYS_ADMIN)) &&
-           ((creds->uid == current_uid()   || creds->uid == current_euid() ||
-             creds->uid == current_suid()) || capable(CAP_SETUID)) &&
-           ((creds->gid == current_gid()   || creds->gid == current_egid() ||
-             creds->gid == current_sgid()) || capable(CAP_SETGID))) {
+           ((creds->uid == cred->uid   || creds->uid == cred->euid ||
+             creds->uid == cred->suid) || capable(CAP_SETUID)) &&
+           ((creds->gid == cred->gid   || creds->gid == cred->egid ||
+             creds->gid == cred->sgid) || capable(CAP_SETGID))) {
               return 0;
        }
        return -EPERM;
@@ -106,9 +108,25 @@ void __scm_destroy(struct scm_cookie *scm)
 
        if (fpl) {
                scm->fp = NULL;
-               for (i=fpl->count-1; i>=0; i--)
-                       fput(fpl->fp[i]);
-               kfree(fpl);
+               if (current->scm_work_list) {
+                       list_add_tail(&fpl->list, current->scm_work_list);
+               } else {
+                       LIST_HEAD(work_list);
+
+                       current->scm_work_list = &work_list;
+
+                       list_add(&fpl->list, &work_list);
+                       while (!list_empty(&work_list)) {
+                               fpl = list_first_entry(&work_list, struct scm_fp_list, list);
+
+                               list_del(&fpl->list);
+                               for (i=fpl->count-1; i>=0; i--)
+                                       fput(fpl->fp[i]);
+                               kfree(fpl);
+                       }
+
+                       current->scm_work_list = NULL;
+               }
        }
 }