This is a new audit feature which only grants processes with CAP_AUDIT_CONTROL the ability to unset their loginuid. They cannot directly set it from a valid uid to another valid uid. The ability to unset the loginuid is nice because a priviledged task, like that of container creation, can unset the loginuid and then priv is not needed inside the container when a login daemon needs to set the loginuid.
Unified · Split
| @@ -386,7 +386,8 @@ struct audit_features { · 385 unmodified lines | ||
| 386 | 386 | __u32 lock; /* which features to lock */ |
| 387 | 387 | }; |
| 388 | 388 | |
| 389 | −#define AUDIT_LAST_FEATURE -1 | |
| 389 | +#define AUDIT_FEATURE_ONLY_UNSET_LOGINUID 0 | |
| 390 | +#define AUDIT_LAST_FEATURE AUDIT_FEATURE_ONLY_UNSET_LOGINUID | |
| 390 | 391 | |
| 391 | 392 | #define audit_feature_valid(x) ((x) >= 0 && (x) <= AUDIT_LAST_FEATURE) |
| 392 | 393 | #define AUDIT_FEATURE_TO_MASK(x) (1 << ((x) & 31)) /* mask for __u32 */ |
| @@ -144,7 +144,8 @@ static struct audit_features af = {.vers = AUDIT_FEATURE_VERSION, · 143 unmodified lines | ||
| 144 | 144 | .features = 0, |
| 145 | 145 | .lock = 0,}; |
| 146 | 146 | |
| 147 | −static char *audit_feature_names[0] = { | |
| 147 | +static char *audit_feature_names[1] = { | |
| 148 | + "only_unset_loginuid", | |
| 148 | 149 | }; |
| 149 | 150 | |
| 150 | 151 | |
| @@ -1974,6 +1974,9 @@ static int audit_set_loginuid_perm(kuid_t loginuid) · 1973 unmodified lines | ||
| 1974 | 1974 | /* it is set, you need permission */ |
| 1975 | 1975 | if (!capable(CAP_AUDIT_CONTROL)) |
| 1976 | 1976 | return -EPERM; |
| 1977 | + /* reject if this is not an unset and we don't allow that */ | |
| 1978 | + if (is_audit_feature_set(AUDIT_FEATURE_ONLY_UNSET_LOGINUID) && uid_valid(loginuid)) | |
| 1979 | + return -EPERM; | |
| 1977 | 1980 | return 0; |
| 1978 | 1981 | } |
| 1979 | 1982 | |