History

audit: Make testing for a valid loginuid explicit.

audit rule additions containing "-F auid!=4294967295" were failing with EINVAL because of a regression caused by e1760bd. Apparently some userland audit rule sets want to know if loginuid uid has been set and are using a test for auid != 4294967295 to determine that. In practice that is a horrible way to ask if a value has been set, because it relies on subtle implementation details and will break every time the uid implementation in the kernel changes. So add a clean way to test if the audit loginuid has been set, and silently convert the old idiom to the cleaner and more comprehensible new idiom.

Eric W. Biederman committed 13 years ago

Commit 780a7651 parent b24a30a4 files · +25 −3Browse files

Unified · Split

4 files
  1. include/linux/audit.h +5 −0
  2. include/uapi/linux/audit.h +1 −0
  3. kernel/auditfilter.c +15 −2
  4. kernel/auditsc.c +4 −1
include/linux/audit.h+5−0
@@ -391,6 +391,11 @@ static inline void audit_ptrace(struct task_struct *t) · 390 unmodified lines
391391 #define audit_signals 0
392392 #endif /* CONFIG_AUDITSYSCALL */
393393
394+static inline bool audit_loginuid_set(struct task_struct *tsk)
395+{
396+ return uid_valid(audit_get_loginuid(tsk));
397+}
398+
394399 #ifdef CONFIG_AUDIT
395400 /* These are defined in audit.c */
396401 /* Public API */
include/uapi/linux/audit.h+1−0
@@ -246,6 +246,7 @@ · 245 unmodified lines
246246 #define AUDIT_OBJ_TYPE 21
247247 #define AUDIT_OBJ_LEV_LOW 22
248248 #define AUDIT_OBJ_LEV_HIGH 23
249+#define AUDIT_LOGINUID_SET 24
249250
250251 /* These are ONLY useful when checking
251252 * at syscall exit time (AUDIT_AT_EXIT). */
kernel/auditfilter.c+15−2
@@ -365,7 +365,10 @@ static int audit_field_valid(struct audit_entry *entry, struct audit_field *f) · 364 unmodified lines
365365 case AUDIT_DIR:
366366 case AUDIT_FILTERKEY:
367367 break;
368− /* arch is only allowed to be = or != */
368+ case AUDIT_LOGINUID_SET:
369+ if ((f->val != 0) && (f->val != 1))
370+ return -EINVAL;
371+ /* FALL THROUGH */
369372 case AUDIT_ARCH:
370373 if (f->op != Audit_not_equal && f->op != Audit_equal)
371374 return -EINVAL;
@@ -419,17 +422,23 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, · 47 unmodified lines
419422 f->lsm_str = NULL;
420423 f->lsm_rule = NULL;
421424
425+ /* Support legacy tests for a valid loginuid */
426+ if ((f->type == AUDIT_LOGINUID) && (f->val == 4294967295)) {
427+ f->type = AUDIT_LOGINUID_SET;
428+ f->val = 0;
429+ }
430+
422431 err = audit_field_valid(entry, f);
423432 if (err)
424433 goto exit_free;
425434
426435 err = -EINVAL;
427436 switch (f->type) {
437+ case AUDIT_LOGINUID:
428438 case AUDIT_UID:
429439 case AUDIT_EUID:
430440 case AUDIT_SUID:
431441 case AUDIT_FSUID:
432− case AUDIT_LOGINUID:
433442 case AUDIT_OBJ_UID:
434443 f->uid = make_kuid(current_user_ns(), f->val);
435444 if (!uid_valid(f->uid))
@@ -1222,6 +1231,10 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, · 786 unmodified lines
12221231 result = audit_uid_comparator(audit_get_loginuid(current),
12231232 f->op, f->uid);
12241233 break;
1234+ case AUDIT_LOGINUID_SET:
1235+ result = audit_comparator(audit_loginuid_set(current),
1236+ f->op, f->val);
1237+ break;
12251238 case AUDIT_MSGTYPE:
12261239 result = audit_comparator(type, f->op, f->val);
12271240 break;
kernel/auditsc.c+4−1
@@ -613,6 +613,9 @@ static int audit_filter_rules(struct task_struct *tsk, · 612 unmodified lines
613613 if (ctx)
614614 result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
615615 break;
616+ case AUDIT_LOGINUID_SET:
617+ result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
618+ break;
616619 case AUDIT_SUBJ_USER:
617620 case AUDIT_SUBJ_ROLE:
618621 case AUDIT_SUBJ_TYPE:
@@ -1970,7 +1973,7 @@ int audit_set_loginuid(kuid_t loginuid) · 1351 unmodified lines
19701973 unsigned int sessionid;
19711974
19721975 #ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE
1973− if (uid_valid(task->loginuid))
1976+ if (audit_loginuid_set(task))
19741977 return -EPERM;
19751978 #else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
19761979 if (!capable(CAP_AUDIT_CONTROL))

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t