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
391#define audit_signals 0391#define audit_signals 0
392#endif /* CONFIG_AUDITSYSCALL */392#endif /* CONFIG_AUDITSYSCALL */
393 393
394static inline bool audit_loginuid_set(struct task_struct *tsk)
395{
396 return uid_valid(audit_get_loginuid(tsk));
397}
398
394#ifdef CONFIG_AUDIT399#ifdef CONFIG_AUDIT
395/* These are defined in audit.c */400/* These are defined in audit.c */
396 /* Public API */401 /* Public API */
include/uapi/linux/audit.h+1−0
@@ -246,6 +246,7 @@ · 245 unmodified lines
246#define AUDIT_OBJ_TYPE 21246#define AUDIT_OBJ_TYPE 21
247#define AUDIT_OBJ_LEV_LOW 22247#define AUDIT_OBJ_LEV_LOW 22
248#define AUDIT_OBJ_LEV_HIGH 23248#define AUDIT_OBJ_LEV_HIGH 23
249#define AUDIT_LOGINUID_SET 24
249 250
250 /* These are ONLY useful when checking251 /* These are ONLY useful when checking
251 * at syscall exit time (AUDIT_AT_EXIT). */252 * 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
365 case AUDIT_DIR:365 case AUDIT_DIR:
366 case AUDIT_FILTERKEY:366 case AUDIT_FILTERKEY:
367 break;367 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 */
369 case AUDIT_ARCH:372 case AUDIT_ARCH:
370 if (f->op != Audit_not_equal && f->op != Audit_equal)373 if (f->op != Audit_not_equal && f->op != Audit_equal)
371 return -EINVAL;374 return -EINVAL;
@@ -419,17 +422,23 @@ static struct audit_entry *audit_data_to_entry(struct audit_rule_data *data, · 47 unmodified lines
419 f->lsm_str = NULL;422 f->lsm_str = NULL;
420 f->lsm_rule = NULL;423 f->lsm_rule = NULL;
421 424
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
422 err = audit_field_valid(entry, f);431 err = audit_field_valid(entry, f);
423 if (err)432 if (err)
424 goto exit_free;433 goto exit_free;
425 434
426 err = -EINVAL;435 err = -EINVAL;
427 switch (f->type) {436 switch (f->type) {
437 case AUDIT_LOGINUID:
428 case AUDIT_UID:438 case AUDIT_UID:
429 case AUDIT_EUID:439 case AUDIT_EUID:
430 case AUDIT_SUID:440 case AUDIT_SUID:
431 case AUDIT_FSUID:441 case AUDIT_FSUID:
432 case AUDIT_LOGINUID:
433 case AUDIT_OBJ_UID:442 case AUDIT_OBJ_UID:
434 f->uid = make_kuid(current_user_ns(), f->val);443 f->uid = make_kuid(current_user_ns(), f->val);
435 if (!uid_valid(f->uid))444 if (!uid_valid(f->uid))
@@ -1222,6 +1231,10 @@ static int audit_filter_user_rules(struct audit_krule *rule, int type, · 786 unmodified lines
1222 result = audit_uid_comparator(audit_get_loginuid(current),1231 result = audit_uid_comparator(audit_get_loginuid(current),
1223 f->op, f->uid);1232 f->op, f->uid);
1224 break;1233 break;
1234 case AUDIT_LOGINUID_SET:
1235 result = audit_comparator(audit_loginuid_set(current),
1236 f->op, f->val);
1237 break;
1225 case AUDIT_MSGTYPE:1238 case AUDIT_MSGTYPE:
1226 result = audit_comparator(type, f->op, f->val);1239 result = audit_comparator(type, f->op, f->val);
1227 break;1240 break;
kernel/auditsc.c+4−1
@@ -613,6 +613,9 @@ static int audit_filter_rules(struct task_struct *tsk, · 612 unmodified lines
613 if (ctx)613 if (ctx)
614 result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);614 result = audit_uid_comparator(tsk->loginuid, f->op, f->uid);
615 break;615 break;
616 case AUDIT_LOGINUID_SET:
617 result = audit_comparator(audit_loginuid_set(tsk), f->op, f->val);
618 break;
616 case AUDIT_SUBJ_USER:619 case AUDIT_SUBJ_USER:
617 case AUDIT_SUBJ_ROLE:620 case AUDIT_SUBJ_ROLE:
618 case AUDIT_SUBJ_TYPE:621 case AUDIT_SUBJ_TYPE:
@@ -1970,7 +1973,7 @@ int audit_set_loginuid(kuid_t loginuid) · 1351 unmodified lines
1970 unsigned int sessionid;1973 unsigned int sessionid;
1971 1974
1972#ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE1975#ifdef CONFIG_AUDIT_LOGINUID_IMMUTABLE
1973 if (uid_valid(task->loginuid))1976 if (audit_loginuid_set(task))
1974 return -EPERM;1977 return -EPERM;
1975#else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */1978#else /* CONFIG_AUDIT_LOGINUID_IMMUTABLE */
1976 if (!capable(CAP_AUDIT_CONTROL))1979 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