Skip to content

Commit

Permalink
userns: Convert the audit loginuid to be a kuid
Browse files Browse the repository at this point in the history
Always store audit loginuids in type kuid_t.

Print loginuids by converting them into uids in the appropriate user
namespace, and then printing the resulting uid.

Modify audit_get_loginuid to return a kuid_t.

Modify audit_set_loginuid to take a kuid_t.

Modify /proc/<pid>/loginuid on read to convert the loginuid into the
user namespace of the opener of the file.

Modify /proc/<pid>/loginud on write to convert the loginuid
rom the user namespace of the opener of the file.

Cc: Al Viro <[email protected]>
Cc: Eric Paris <[email protected]>
Cc: Paul Moore <[email protected]> ?
Cc: David Miller <[email protected]>
Signed-off-by: Eric W. Biederman <[email protected]>
  • Loading branch information
ebiederm committed Sep 18, 2012
1 parent ca57ec0 commit e1760bd
Show file tree
Hide file tree
Showing 18 changed files with 80 additions and 66 deletions.
14 changes: 8 additions & 6 deletions drivers/tty/tty_audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ static void tty_audit_buf_put(struct tty_audit_buf *buf)
}

static void tty_audit_log(const char *description, struct task_struct *tsk,
uid_t loginuid, unsigned sessionid, int major,
kuid_t loginuid, unsigned sessionid, int major,
int minor, unsigned char *data, size_t size)
{
struct audit_buffer *ab;
Expand All @@ -73,7 +73,9 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,

audit_log_format(ab, "%s pid=%u uid=%u auid=%u ses=%u "
"major=%d minor=%d comm=", description,
tsk->pid, uid, loginuid, sessionid,
tsk->pid, uid,
from_kuid(&init_user_ns, loginuid),
sessionid,
major, minor);
get_task_comm(name, tsk);
audit_log_untrustedstring(ab, name);
Expand All @@ -89,7 +91,7 @@ static void tty_audit_log(const char *description, struct task_struct *tsk,
* Generate an audit message from the contents of @buf, which is owned by
* @tsk with @loginuid. @buf->mutex must be locked.
*/
static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
static void tty_audit_buf_push(struct task_struct *tsk, kuid_t loginuid,
unsigned int sessionid,
struct tty_audit_buf *buf)
{
Expand All @@ -112,7 +114,7 @@ static void tty_audit_buf_push(struct task_struct *tsk, uid_t loginuid,
*/
static void tty_audit_buf_push_current(struct tty_audit_buf *buf)
{
uid_t auid = audit_get_loginuid(current);
kuid_t auid = audit_get_loginuid(current);
unsigned int sessionid = audit_get_sessionid(current);
tty_audit_buf_push(current, auid, sessionid, buf);
}
Expand Down Expand Up @@ -179,7 +181,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
}

if (should_audit && audit_enabled) {
uid_t auid;
kuid_t auid;
unsigned int sessionid;

auid = audit_get_loginuid(current);
Expand All @@ -199,7 +201,7 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)
* reference to the tty audit buffer if available.
* Flush the buffer or return an appropriate error code.
*/
int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
int tty_audit_push_task(struct task_struct *tsk, kuid_t loginuid, u32 sessionid)
{
struct tty_audit_buf *buf = ERR_PTR(-EPERM);
unsigned long flags;
Expand Down
12 changes: 10 additions & 2 deletions fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -1089,7 +1089,8 @@ static ssize_t proc_loginuid_read(struct file * file, char __user * buf,
if (!task)
return -ESRCH;
length = scnprintf(tmpbuf, TMPBUFLEN, "%u",
audit_get_loginuid(task));
from_kuid(file->f_cred->user_ns,
audit_get_loginuid(task)));
put_task_struct(task);
return simple_read_from_buffer(buf, count, ppos, tmpbuf, length);
}
Expand All @@ -1101,6 +1102,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
char *page, *tmp;
ssize_t length;
uid_t loginuid;
kuid_t kloginuid;

rcu_read_lock();
if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) {
Expand Down Expand Up @@ -1130,7 +1132,13 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
goto out_free_page;

}
length = audit_set_loginuid(loginuid);
kloginuid = make_kuid(file->f_cred->user_ns, loginuid);
if (!uid_valid(kloginuid)) {
length = -EINVAL;
goto out_free_page;
}

length = audit_set_loginuid(kloginuid);
if (likely(length == 0))
length = count;

Expand Down
6 changes: 3 additions & 3 deletions include/linux/audit.h
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ static inline void audit_ptrace(struct task_struct *t)
extern unsigned int audit_serial(void);
extern int auditsc_get_stamp(struct audit_context *ctx,
struct timespec *t, unsigned int *serial);
extern int audit_set_loginuid(uid_t loginuid);
extern int audit_set_loginuid(kuid_t loginuid);
#define audit_get_loginuid(t) ((t)->loginuid)
#define audit_get_sessionid(t) ((t)->sessionid)
extern void audit_log_task_context(struct audit_buffer *ab);
Expand Down Expand Up @@ -639,7 +639,7 @@ extern int audit_signals;
#define audit_core_dumps(i) do { ; } while (0)
#define audit_seccomp(i,s,c) do { ; } while (0)
#define auditsc_get_stamp(c,t,s) (0)
#define audit_get_loginuid(t) (-1)
#define audit_get_loginuid(t) (INVALID_UID)
#define audit_get_sessionid(t) (-1)
#define audit_log_task_context(b) do { ; } while (0)
#define audit_ipc_obj(i) ((void)0)
Expand Down Expand Up @@ -705,7 +705,7 @@ extern int audit_update_lsm_rules(void);
extern int audit_filter_user(void);
extern int audit_filter_type(int type);
extern int audit_receive_filter(int type, int pid, int seq,
void *data, size_t datasz, uid_t loginuid,
void *data, size_t datasz, kuid_t loginuid,
u32 sessionid, u32 sid);
extern int audit_enabled;
#else
Expand Down
2 changes: 1 addition & 1 deletion include/linux/init_task.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ extern struct group_info init_groups;

#ifdef CONFIG_AUDITSYSCALL
#define INIT_IDS \
.loginuid = -1, \
.loginuid = INVALID_UID, \
.sessionid = -1,
#else
#define INIT_IDS
Expand Down
2 changes: 1 addition & 1 deletion include/linux/sched.h
Original file line number Diff line number Diff line change
Expand Up @@ -1426,7 +1426,7 @@ struct task_struct {

struct audit_context *audit_context;
#ifdef CONFIG_AUDITSYSCALL
uid_t loginuid;
kuid_t loginuid;
unsigned int sessionid;
#endif
struct seccomp seccomp;
Expand Down
4 changes: 2 additions & 2 deletions include/linux/tty.h
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ extern void tty_audit_fork(struct signal_struct *sig);
extern void tty_audit_tiocsti(struct tty_struct *tty, char ch);
extern void tty_audit_push(struct tty_struct *tty);
extern int tty_audit_push_task(struct task_struct *tsk,
uid_t loginuid, u32 sessionid);
kuid_t loginuid, u32 sessionid);
#else
static inline void tty_audit_add_data(struct tty_struct *tty,
unsigned char *data, size_t size)
Expand All @@ -572,7 +572,7 @@ static inline void tty_audit_push(struct tty_struct *tty)
{
}
static inline int tty_audit_push_task(struct task_struct *tsk,
uid_t loginuid, u32 sessionid)
kuid_t loginuid, u32 sessionid)
{
return 0;
}
Expand Down
2 changes: 1 addition & 1 deletion include/net/netlabel.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ struct cipso_v4_doi;
/* NetLabel audit information */
struct netlbl_audit {
u32 secid;
uid_t loginuid;
kuid_t loginuid;
u32 sessionid;
};

Expand Down
23 changes: 12 additions & 11 deletions include/net/xfrm.h
Original file line number Diff line number Diff line change
Expand Up @@ -662,7 +662,7 @@ struct xfrm_spi_skb_cb {
/* Audit Information */
struct xfrm_audit {
u32 secid;
uid_t loginuid;
kuid_t loginuid;
u32 sessionid;
};

Expand All @@ -681,13 +681,14 @@ static inline struct audit_buffer *xfrm_audit_start(const char *op)
return audit_buf;
}

static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid,
static inline void xfrm_audit_helper_usrinfo(kuid_t auid, u32 ses, u32 secid,
struct audit_buffer *audit_buf)
{
char *secctx;
u32 secctx_len;

audit_log_format(audit_buf, " auid=%u ses=%u", auid, ses);
audit_log_format(audit_buf, " auid=%u ses=%u",
from_kuid(&init_user_ns, auid), ses);
if (secid != 0 &&
security_secid_to_secctx(secid, &secctx, &secctx_len) == 0) {
audit_log_format(audit_buf, " subj=%s", secctx);
Expand All @@ -697,13 +698,13 @@ static inline void xfrm_audit_helper_usrinfo(uid_t auid, u32 ses, u32 secid,
}

extern void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
u32 auid, u32 ses, u32 secid);
kuid_t auid, u32 ses, u32 secid);
extern void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
u32 auid, u32 ses, u32 secid);
kuid_t auid, u32 ses, u32 secid);
extern void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid);
kuid_t auid, u32 ses, u32 secid);
extern void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid);
kuid_t auid, u32 ses, u32 secid);
extern void xfrm_audit_state_replay_overflow(struct xfrm_state *x,
struct sk_buff *skb);
extern void xfrm_audit_state_replay(struct xfrm_state *x,
Expand All @@ -716,22 +717,22 @@ extern void xfrm_audit_state_icvfail(struct xfrm_state *x,
#else

static inline void xfrm_audit_policy_add(struct xfrm_policy *xp, int result,
u32 auid, u32 ses, u32 secid)
kuid_t auid, u32 ses, u32 secid)
{
}

static inline void xfrm_audit_policy_delete(struct xfrm_policy *xp, int result,
u32 auid, u32 ses, u32 secid)
kuid_t auid, u32 ses, u32 secid)
{
}

static inline void xfrm_audit_state_add(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid)
kuid_t auid, u32 ses, u32 secid)
{
}

static inline void xfrm_audit_state_delete(struct xfrm_state *x, int result,
u32 auid, u32 ses, u32 secid)
kuid_t auid, u32 ses, u32 secid)
{
}

Expand Down
20 changes: 10 additions & 10 deletions kernel/audit.c
Original file line number Diff line number Diff line change
Expand Up @@ -265,15 +265,15 @@ void audit_log_lost(const char *message)
}

static int audit_log_config_change(char *function_name, int new, int old,
uid_t loginuid, u32 sessionid, u32 sid,
kuid_t loginuid, u32 sessionid, u32 sid,
int allow_changes)
{
struct audit_buffer *ab;
int rc = 0;

ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
audit_log_format(ab, "%s=%d old=%d auid=%u ses=%u", function_name, new,
old, loginuid, sessionid);
old, from_kuid(&init_user_ns, loginuid), sessionid);
if (sid) {
char *ctx = NULL;
u32 len;
Expand All @@ -293,7 +293,7 @@ static int audit_log_config_change(char *function_name, int new, int old,
}

static int audit_do_config_change(char *function_name, int *to_change,
int new, uid_t loginuid, u32 sessionid,
int new, kuid_t loginuid, u32 sessionid,
u32 sid)
{
int allow_changes, rc = 0, old = *to_change;
Expand All @@ -320,21 +320,21 @@ static int audit_do_config_change(char *function_name, int *to_change,
return rc;
}

static int audit_set_rate_limit(int limit, uid_t loginuid, u32 sessionid,
static int audit_set_rate_limit(int limit, kuid_t loginuid, u32 sessionid,
u32 sid)
{
return audit_do_config_change("audit_rate_limit", &audit_rate_limit,
limit, loginuid, sessionid, sid);
}

static int audit_set_backlog_limit(int limit, uid_t loginuid, u32 sessionid,
static int audit_set_backlog_limit(int limit, kuid_t loginuid, u32 sessionid,
u32 sid)
{
return audit_do_config_change("audit_backlog_limit", &audit_backlog_limit,
limit, loginuid, sessionid, sid);
}

static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid)
static int audit_set_enabled(int state, kuid_t loginuid, u32 sessionid, u32 sid)
{
int rc;
if (state < AUDIT_OFF || state > AUDIT_LOCKED)
Expand All @@ -349,7 +349,7 @@ static int audit_set_enabled(int state, uid_t loginuid, u32 sessionid, u32 sid)
return rc;
}

static int audit_set_failure(int state, uid_t loginuid, u32 sessionid, u32 sid)
static int audit_set_failure(int state, kuid_t loginuid, u32 sessionid, u32 sid)
{
if (state != AUDIT_FAIL_SILENT
&& state != AUDIT_FAIL_PRINTK
Expand Down Expand Up @@ -607,7 +607,7 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type)
}

static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
uid_t auid, u32 ses, u32 sid)
kuid_t auid, u32 ses, u32 sid)
{
int rc = 0;
char *ctx = NULL;
Expand All @@ -622,7 +622,7 @@ static int audit_log_common_recv_msg(struct audit_buffer **ab, u16 msg_type,
audit_log_format(*ab, "pid=%d uid=%u auid=%u ses=%u",
task_tgid_vnr(current),
from_kuid(&init_user_ns, current_uid()),
auid, ses);
from_kuid(&init_user_ns, auid), ses);
if (sid) {
rc = security_secid_to_secctx(sid, &ctx, &len);
if (rc)
Expand All @@ -644,7 +644,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
int err;
struct audit_buffer *ab;
u16 msg_type = nlh->nlmsg_type;
uid_t loginuid; /* loginuid of sender */
kuid_t loginuid; /* loginuid of sender */
u32 sessionid;
struct audit_sig_info *sig_data;
char *ctx = NULL;
Expand Down
2 changes: 1 addition & 1 deletion kernel/audit_watch.c
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ static void audit_watch_log_rule_change(struct audit_krule *r, struct audit_watc
struct audit_buffer *ab;
ab = audit_log_start(NULL, GFP_NOFS, AUDIT_CONFIG_CHANGE);
audit_log_format(ab, "auid=%u ses=%u op=",
audit_get_loginuid(current),
from_kuid(&init_user_ns, audit_get_loginuid(current)),
audit_get_sessionid(current));
audit_log_string(ab, op);
audit_log_format(ab, " path=");
Expand Down
7 changes: 4 additions & 3 deletions kernel/auditfilter.c
Original file line number Diff line number Diff line change
Expand Up @@ -1109,7 +1109,7 @@ static void audit_list_rules(int pid, int seq, struct sk_buff_head *q)
}

/* Log rule additions and removals */
static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
static void audit_log_rule_change(kuid_t loginuid, u32 sessionid, u32 sid,
char *action, struct audit_krule *rule,
int res)
{
Expand All @@ -1121,7 +1121,8 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
ab = audit_log_start(NULL, GFP_KERNEL, AUDIT_CONFIG_CHANGE);
if (!ab)
return;
audit_log_format(ab, "auid=%u ses=%u", loginuid, sessionid);
audit_log_format(ab, "auid=%u ses=%u",
from_kuid(&init_user_ns, loginuid), sessionid);
if (sid) {
char *ctx = NULL;
u32 len;
Expand Down Expand Up @@ -1152,7 +1153,7 @@ static void audit_log_rule_change(uid_t loginuid, u32 sessionid, u32 sid,
* @sid: SE Linux Security ID of sender
*/
int audit_receive_filter(int type, int pid, int seq, void *data,
size_t datasz, uid_t loginuid, u32 sessionid, u32 sid)
size_t datasz, kuid_t loginuid, u32 sessionid, u32 sid)
{
struct task_struct *tsk;
struct audit_netlink_list *dest;
Expand Down
Loading

0 comments on commit e1760bd

Please sign in to comment.