]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - kernel/auditsc.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/horms/ipvs...
[karo-tx-linux.git] / kernel / auditsc.c
index 4b96415527b8664753e18cb169f0de9f391f9314..ff4798fcb4884d371f5b393c11dbcd8c585e1fbb 100644 (file)
@@ -113,8 +113,8 @@ struct audit_names {
        unsigned long   ino;
        dev_t           dev;
        umode_t         mode;
-       uid_t           uid;
-       gid_t           gid;
+       kuid_t          uid;
+       kgid_t          gid;
        dev_t           rdev;
        u32             osid;
        struct audit_cap_data fcap;
@@ -149,8 +149,8 @@ struct audit_aux_data_execve {
 struct audit_aux_data_pids {
        struct audit_aux_data   d;
        pid_t                   target_pid[AUDIT_AUX_PIDS];
-       uid_t                   target_auid[AUDIT_AUX_PIDS];
-       uid_t                   target_uid[AUDIT_AUX_PIDS];
+       kuid_t                  target_auid[AUDIT_AUX_PIDS];
+       kuid_t                  target_uid[AUDIT_AUX_PIDS];
        unsigned int            target_sessionid[AUDIT_AUX_PIDS];
        u32                     target_sid[AUDIT_AUX_PIDS];
        char                    target_comm[AUDIT_AUX_PIDS][TASK_COMM_LEN];
@@ -208,14 +208,14 @@ struct audit_context {
        size_t sockaddr_len;
                                /* Save things to print about task_struct */
        pid_t               pid, ppid;
-       uid_t               uid, euid, suid, fsuid;
-       gid_t               gid, egid, sgid, fsgid;
+       kuid_t              uid, euid, suid, fsuid;
+       kgid_t              gid, egid, sgid, fsgid;
        unsigned long       personality;
        int                 arch;
 
        pid_t               target_pid;
-       uid_t               target_auid;
-       uid_t               target_uid;
+       kuid_t              target_auid;
+       kuid_t              target_uid;
        unsigned int        target_sessionid;
        u32                 target_sid;
        char                target_comm[TASK_COMM_LEN];
@@ -231,8 +231,8 @@ struct audit_context {
                        long args[6];
                } socketcall;
                struct {
-                       uid_t                   uid;
-                       gid_t                   gid;
+                       kuid_t                  uid;
+                       kgid_t                  gid;
                        umode_t                 mode;
                        u32                     osid;
                        int                     has_perm;
@@ -464,37 +464,47 @@ static int match_tree_refs(struct audit_context *ctx, struct audit_tree *tree)
        return 0;
 }
 
-static int audit_compare_id(uid_t uid1,
-                           struct audit_names *name,
-                           unsigned long name_offset,
-                           struct audit_field *f,
-                           struct audit_context *ctx)
+static int audit_compare_uid(kuid_t uid,
+                            struct audit_names *name,
+                            struct audit_field *f,
+                            struct audit_context *ctx)
 {
        struct audit_names *n;
-       unsigned long addr;
-       uid_t uid2;
        int rc;
-
-       BUILD_BUG_ON(sizeof(uid_t) != sizeof(gid_t));
-
        if (name) {
-               addr = (unsigned long)name;
-               addr += name_offset;
-
-               uid2 = *(uid_t *)addr;
-               rc = audit_comparator(uid1, f->op, uid2);
+               rc = audit_uid_comparator(uid, f->op, name->uid);
                if (rc)
                        return rc;
        }
-
        if (ctx) {
                list_for_each_entry(n, &ctx->names_list, list) {
-                       addr = (unsigned long)n;
-                       addr += name_offset;
-
-                       uid2 = *(uid_t *)addr;
+                       rc = audit_uid_comparator(uid, f->op, n->uid);
+                       if (rc)
+                               return rc;
+               }
+       }
+       return 0;
+}
 
-                       rc = audit_comparator(uid1, f->op, uid2);
+static int audit_compare_gid(kgid_t gid,
+                            struct audit_names *name,
+                            struct audit_field *f,
+                            struct audit_context *ctx)
+{
+       struct audit_names *n;
+       int rc;
+       if (name) {
+               rc = audit_gid_comparator(gid, f->op, name->gid);
+               if (rc)
+                       return rc;
+       }
+       if (ctx) {
+               list_for_each_entry(n, &ctx->names_list, list) {
+                       rc = audit_gid_comparator(gid, f->op, n->gid);
                        if (rc)
                                return rc;
                }
@@ -511,80 +521,62 @@ static int audit_field_compare(struct task_struct *tsk,
        switch (f->val) {
        /* process to file object comparisons */
        case AUDIT_COMPARE_UID_TO_OBJ_UID:
-               return audit_compare_id(cred->uid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->uid, name, f, ctx);
        case AUDIT_COMPARE_GID_TO_OBJ_GID:
-               return audit_compare_id(cred->gid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->gid, name, f, ctx);
        case AUDIT_COMPARE_EUID_TO_OBJ_UID:
-               return audit_compare_id(cred->euid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->euid, name, f, ctx);
        case AUDIT_COMPARE_EGID_TO_OBJ_GID:
-               return audit_compare_id(cred->egid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->egid, name, f, ctx);
        case AUDIT_COMPARE_AUID_TO_OBJ_UID:
-               return audit_compare_id(tsk->loginuid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(tsk->loginuid, name, f, ctx);
        case AUDIT_COMPARE_SUID_TO_OBJ_UID:
-               return audit_compare_id(cred->suid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->suid, name, f, ctx);
        case AUDIT_COMPARE_SGID_TO_OBJ_GID:
-               return audit_compare_id(cred->sgid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->sgid, name, f, ctx);
        case AUDIT_COMPARE_FSUID_TO_OBJ_UID:
-               return audit_compare_id(cred->fsuid,
-                                       name, offsetof(struct audit_names, uid),
-                                       f, ctx);
+               return audit_compare_uid(cred->fsuid, name, f, ctx);
        case AUDIT_COMPARE_FSGID_TO_OBJ_GID:
-               return audit_compare_id(cred->fsgid,
-                                       name, offsetof(struct audit_names, gid),
-                                       f, ctx);
+               return audit_compare_gid(cred->fsgid, name, f, ctx);
        /* uid comparisons */
        case AUDIT_COMPARE_UID_TO_AUID:
-               return audit_comparator(cred->uid, f->op, tsk->loginuid);
+               return audit_uid_comparator(cred->uid, f->op, tsk->loginuid);
        case AUDIT_COMPARE_UID_TO_EUID:
-               return audit_comparator(cred->uid, f->op, cred->euid);
+               return audit_uid_comparator(cred->uid, f->op, cred->euid);
        case AUDIT_COMPARE_UID_TO_SUID:
-               return audit_comparator(cred->uid, f->op, cred->suid);
+               return audit_uid_comparator(cred->uid, f->op, cred->suid);
        case AUDIT_COMPARE_UID_TO_FSUID:
-               return audit_comparator(cred->uid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->uid, f->op, cred->fsuid);
        /* auid comparisons */
        case AUDIT_COMPARE_AUID_TO_EUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->euid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->euid);
        case AUDIT_COMPARE_AUID_TO_SUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->suid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->suid);
        case AUDIT_COMPARE_AUID_TO_FSUID:
-               return audit_comparator(tsk->loginuid, f->op, cred->fsuid);
+               return audit_uid_comparator(tsk->loginuid, f->op, cred->fsuid);
        /* euid comparisons */
        case AUDIT_COMPARE_EUID_TO_SUID:
-               return audit_comparator(cred->euid, f->op, cred->suid);
+               return audit_uid_comparator(cred->euid, f->op, cred->suid);
        case AUDIT_COMPARE_EUID_TO_FSUID:
-               return audit_comparator(cred->euid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->euid, f->op, cred->fsuid);
        /* suid comparisons */
        case AUDIT_COMPARE_SUID_TO_FSUID:
-               return audit_comparator(cred->suid, f->op, cred->fsuid);
+               return audit_uid_comparator(cred->suid, f->op, cred->fsuid);
        /* gid comparisons */
        case AUDIT_COMPARE_GID_TO_EGID:
-               return audit_comparator(cred->gid, f->op, cred->egid);
+               return audit_gid_comparator(cred->gid, f->op, cred->egid);
        case AUDIT_COMPARE_GID_TO_SGID:
-               return audit_comparator(cred->gid, f->op, cred->sgid);
+               return audit_gid_comparator(cred->gid, f->op, cred->sgid);
        case AUDIT_COMPARE_GID_TO_FSGID:
-               return audit_comparator(cred->gid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->gid, f->op, cred->fsgid);
        /* egid comparisons */
        case AUDIT_COMPARE_EGID_TO_SGID:
-               return audit_comparator(cred->egid, f->op, cred->sgid);
+               return audit_gid_comparator(cred->egid, f->op, cred->sgid);
        case AUDIT_COMPARE_EGID_TO_FSGID:
-               return audit_comparator(cred->egid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->egid, f->op, cred->fsgid);
        /* sgid comparison */
        case AUDIT_COMPARE_SGID_TO_FSGID:
-               return audit_comparator(cred->sgid, f->op, cred->fsgid);
+               return audit_gid_comparator(cred->sgid, f->op, cred->fsgid);
        default:
                WARN(1, "Missing AUDIT_COMPARE define.  Report as a bug\n");
                return 0;
@@ -630,28 +622,28 @@ static int audit_filter_rules(struct task_struct *tsk,
                        }
                        break;
                case AUDIT_UID:
-                       result = audit_comparator(cred->uid, f->op, f->val);
+                       result = audit_uid_comparator(cred->uid, f->op, f->uid);
                        break;
                case AUDIT_EUID:
-                       result = audit_comparator(cred->euid, f->op, f->val);
+                       result = audit_uid_comparator(cred->euid, f->op, f->uid);
                        break;
                case AUDIT_SUID:
-                       result = audit_comparator(cred->suid, f->op, f->val);
+                       result = audit_uid_comparator(cred->suid, f->op, f->uid);
                        break;
                case AUDIT_FSUID:
-                       result = audit_comparator(cred->fsuid, f->op, f->val);
+                       result = audit_uid_comparator(cred->fsuid, f->op, f->uid);
                        break;
                case AUDIT_GID:
-                       result = audit_comparator(cred->gid, f->op, f->val);
+                       result = audit_gid_comparator(cred->gid, f->op, f->gid);
                        break;
                case AUDIT_EGID:
-                       result = audit_comparator(cred->egid, f->op, f->val);
+                       result = audit_gid_comparator(cred->egid, f->op, f->gid);
                        break;
                case AUDIT_SGID:
-                       result = audit_comparator(cred->sgid, f->op, f->val);
+                       result = audit_gid_comparator(cred->sgid, f->op, f->gid);
                        break;
                case AUDIT_FSGID:
-                       result = audit_comparator(cred->fsgid, f->op, f->val);
+                       result = audit_gid_comparator(cred->fsgid, f->op, f->gid);
                        break;
                case AUDIT_PERS:
                        result = audit_comparator(tsk->personality, f->op, f->val);
@@ -717,10 +709,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_OBJ_UID:
                        if (name) {
-                               result = audit_comparator(name->uid, f->op, f->val);
+                               result = audit_uid_comparator(name->uid, f->op, f->uid);
                        } else if (ctx) {
                                list_for_each_entry(n, &ctx->names_list, list) {
-                                       if (audit_comparator(n->uid, f->op, f->val)) {
+                                       if (audit_uid_comparator(n->uid, f->op, f->uid)) {
                                                ++result;
                                                break;
                                        }
@@ -729,10 +721,10 @@ static int audit_filter_rules(struct task_struct *tsk,
                        break;
                case AUDIT_OBJ_GID:
                        if (name) {
-                               result = audit_comparator(name->gid, f->op, f->val);
+                               result = audit_gid_comparator(name->gid, f->op, f->gid);
                        } else if (ctx) {
                                list_for_each_entry(n, &ctx->names_list, list) {
-                                       if (audit_comparator(n->gid, f->op, f->val)) {
+                                       if (audit_gid_comparator(n->gid, f->op, f->gid)) {
                                                ++result;
                                                break;
                                        }
@@ -750,7 +742,7 @@ static int audit_filter_rules(struct task_struct *tsk,
                case AUDIT_LOGINUID:
                        result = 0;
                        if (ctx)
-                               result = audit_comparator(tsk->loginuid, f->op, f->val);
+                               result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
                        break;
                case AUDIT_SUBJ_USER:
                case AUDIT_SUBJ_ROLE:
@@ -1184,7 +1176,7 @@ static void audit_log_task_info(struct audit_buffer *ab, struct task_struct *tsk
 }
 
 static int audit_log_pid_context(struct audit_context *context, pid_t pid,
-                                uid_t auid, uid_t uid, unsigned int sessionid,
+                                kuid_t auid, kuid_t uid, unsigned int sessionid,
                                 u32 sid, char *comm)
 {
        struct audit_buffer *ab;
@@ -1196,8 +1188,9 @@ static int audit_log_pid_context(struct audit_context *context, pid_t pid,
        if (!ab)
                return rc;
 
-       audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid, auid,
-                        uid, sessionid);
+       audit_log_format(ab, "opid=%d oauid=%d ouid=%d oses=%d", pid,
+                        from_kuid(&init_user_ns, auid),
+                        from_kuid(&init_user_ns, uid), sessionid);
        if (security_secid_to_secctx(sid, &ctx, &len)) {
                audit_log_format(ab, " obj=(none)");
                rc = 1;
@@ -1447,7 +1440,9 @@ static void show_special(struct audit_context *context, int *call_panic)
                u32 osid = context->ipc.osid;
 
                audit_log_format(ab, "ouid=%u ogid=%u mode=%#ho",
-                        context->ipc.uid, context->ipc.gid, context->ipc.mode);
+                                from_kuid(&init_user_ns, context->ipc.uid),
+                                from_kgid(&init_user_ns, context->ipc.gid),
+                                context->ipc.mode);
                if (osid) {
                        char *ctx = NULL;
                        u32 len;
@@ -1560,8 +1555,8 @@ static void audit_log_name(struct audit_context *context, struct audit_names *n,
                                 MAJOR(n->dev),
                                 MINOR(n->dev),
                                 n->mode,
-                                n->uid,
-                                n->gid,
+                                from_kuid(&init_user_ns, n->uid),
+                                from_kgid(&init_user_ns, n->gid),
                                 MAJOR(n->rdev),
                                 MINOR(n->rdev));
        }
@@ -1638,11 +1633,16 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
                  context->name_count,
                  context->ppid,
                  context->pid,
-                 tsk->loginuid,
-                 context->uid,
-                 context->gid,
-                 context->euid, context->suid, context->fsuid,
-                 context->egid, context->sgid, context->fsgid, tty,
+                 from_kuid(&init_user_ns, tsk->loginuid),
+                 from_kuid(&init_user_ns, context->uid),
+                 from_kgid(&init_user_ns, context->gid),
+                 from_kuid(&init_user_ns, context->euid),
+                 from_kuid(&init_user_ns, context->suid),
+                 from_kuid(&init_user_ns, context->fsuid),
+                 from_kgid(&init_user_ns, context->egid),
+                 from_kgid(&init_user_ns, context->sgid),
+                 from_kgid(&init_user_ns, context->fsgid),
+                 tty,
                  tsk->sessionid);
 
 
@@ -2299,14 +2299,14 @@ static atomic_t session_id = ATOMIC_INIT(0);
  *
  * Called (set) from fs/proc/base.c::proc_loginuid_write().
  */
-int audit_set_loginuid(uid_t loginuid)
+int audit_set_loginuid(kuid_t loginuid)
 {
        struct task_struct *task = current;
        struct audit_context *context = task->audit_context;
        unsigned int sessionid;
 
 #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE
-       if (task->loginuid != -1)
+       if (uid_valid(task->loginuid))
                return -EPERM;
 #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
        if (!capable(CAP_AUDIT_CONTROL))
@@ -2322,8 +2322,10 @@ int audit_set_loginuid(uid_t loginuid)
                        audit_log_format(ab, "login pid=%d uid=%u "
                                "old auid=%u new auid=%u"
                                " old ses=%u new ses=%u",
-                               task->pid, task_uid(task),
-                               task->loginuid, loginuid,
+                               task->pid,
+                               from_kuid(&init_user_ns, task_uid(task)),
+                               from_kuid(&init_user_ns, task->loginuid),
+                               from_kuid(&init_user_ns, loginuid),
                                task->sessionid, sessionid);
                        audit_log_end(ab);
                }
@@ -2546,12 +2548,12 @@ int __audit_signal_info(int sig, struct task_struct *t)
        struct audit_aux_data_pids *axp;
        struct task_struct *tsk = current;
        struct audit_context *ctx = tsk->audit_context;
-       uid_t uid = current_uid(), t_uid = task_uid(t);
+       kuid_t uid = current_uid(), t_uid = task_uid(t);
 
        if (audit_pid && t->tgid == audit_pid) {
                if (sig == SIGTERM || sig == SIGHUP || sig == SIGUSR1 || sig == SIGUSR2) {
                        audit_sig_pid = tsk->pid;
-                       if (tsk->loginuid != -1)
+                       if (uid_valid(tsk->loginuid))
                                audit_sig_uid = tsk->loginuid;
                        else
                                audit_sig_uid = uid;
@@ -2672,8 +2674,8 @@ void __audit_mmap_fd(int fd, int flags)
 
 static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
 {
-       uid_t auid, uid;
-       gid_t gid;
+       kuid_t auid, uid;
+       kgid_t gid;
        unsigned int sessionid;
 
        auid = audit_get_loginuid(current);
@@ -2681,7 +2683,10 @@ static void audit_log_abend(struct audit_buffer *ab, char *reason, long signr)
        current_uid_gid(&uid, &gid);
 
        audit_log_format(ab, "auid=%u uid=%u gid=%u ses=%u",
-                        auid, uid, gid, sessionid);
+                        from_kuid(&init_user_ns, auid),
+                        from_kuid(&init_user_ns, uid),
+                        from_kgid(&init_user_ns, gid),
+                        sessionid);
        audit_log_task_context(ab);
        audit_log_format(ab, " pid=%d comm=", current->pid);
        audit_log_untrustedstring(ab, current->comm);