Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 847f8776 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'audit.b64' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/audit-current:
  audit mmap
  audit: make link()/linkat() match "attribute change" predicate
  audit: Use rcu for task lookup protection
  audit: Do not send uninitialized data for AUDIT_TTY_GET
  audit: Call tty_audit_push_task() outside preempt disabled
  in untag_chunk() we need to do alloc_chunk() a bit earlier
  audit: make functions static
  Audit: add support to match lsm labels on user audit messages
parents 79346507 120a795d
Loading
Loading
Loading
Loading
+28 −10
Original line number Diff line number Diff line
@@ -189,24 +189,42 @@ void tty_audit_tiocsti(struct tty_struct *tty, char ch)

/**
 * tty_audit_push_task	-	Flush task's pending audit data
 * @tsk:		task pointer
 * @loginuid:		sender login uid
 * @sessionid:		sender session id
 *
 * Called with a ref on @tsk held. Try to lock sighand and get a
 * reference to the tty audit buffer if available.
 * Flush the buffer or return an appropriate error code.
 */
void tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
int tty_audit_push_task(struct task_struct *tsk, uid_t loginuid, u32 sessionid)
{
	struct tty_audit_buf *buf;
	struct tty_audit_buf *buf = ERR_PTR(-EPERM);
	unsigned long flags;

	if (!lock_task_sighand(tsk, &flags))
		return -ESRCH;

	spin_lock_irq(&tsk->sighand->siglock);
	if (tsk->signal->audit_tty) {
		buf = tsk->signal->tty_audit_buf;
		if (buf)
			atomic_inc(&buf->count);
	spin_unlock_irq(&tsk->sighand->siglock);
	if (!buf)
		return;
	}
	unlock_task_sighand(tsk, &flags);

	/*
	 * Return 0 when signal->audit_tty set
	 * but tsk->signal->tty_audit_buf == NULL.
	 */
	if (!buf || IS_ERR(buf))
		return PTR_ERR(buf);

	mutex_lock(&buf->mutex);
	tty_audit_buf_push(tsk, loginuid, sessionid, buf);
	mutex_unlock(&buf->mutex);

	tty_audit_buf_put(buf);
	return 0;
}

/**
+4 −0
Original line number Diff line number Diff line
@@ -20,3 +20,7 @@ __NR_chown32,
__NR_fchown32,
__NR_lchown32,
#endif
__NR_link,
#ifdef __NR_linkat
__NR_linkat,
#endif
+9 −0
Original line number Diff line number Diff line
@@ -102,6 +102,7 @@
#define AUDIT_EOE		1320	/* End of multi-record event */
#define AUDIT_BPRM_FCAPS	1321	/* Information about fcaps increasing perms */
#define AUDIT_CAPSET		1322	/* Record showing argument to sys_capset */
#define AUDIT_MMAP		1323	/* Record showing descriptor and flags in mmap */

#define AUDIT_AVC		1400	/* SE Linux avc denial or grant */
#define AUDIT_SELINUX_ERR	1401	/* Internal SE Linux Errors */
@@ -478,6 +479,7 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
				  const struct cred *new,
				  const struct cred *old);
extern void __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);
extern void __audit_mmap_fd(int fd, int flags);

static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
@@ -531,6 +533,12 @@ static inline void audit_log_capset(pid_t pid, const struct cred *new,
		__audit_log_capset(pid, new, old);
}

static inline void audit_mmap_fd(int fd, int flags)
{
	if (unlikely(!audit_dummy_context()))
		__audit_mmap_fd(fd, flags);
}

extern int audit_n_rules;
extern int audit_signals;
#else
@@ -564,6 +572,7 @@ extern int audit_signals;
#define audit_mq_getsetattr(d,s) ((void)0)
#define audit_log_bprm_fcaps(b, ncr, ocr) ({ 0; })
#define audit_log_capset(pid, ncr, ocr) ((void)0)
#define audit_mmap_fd(fd, flags) ((void)0)
#define audit_ptrace(t) ((void)0)
#define audit_n_rules 0
#define audit_signals 0
+5 −4
Original line number Diff line number Diff line
@@ -541,7 +541,7 @@ extern void tty_audit_exit(void);
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 void tty_audit_push_task(struct task_struct *tsk,
extern int tty_audit_push_task(struct task_struct *tsk,
			       uid_t loginuid, u32 sessionid);
#else
static inline void tty_audit_add_data(struct tty_struct *tty,
@@ -560,9 +560,10 @@ static inline void tty_audit_fork(struct signal_struct *sig)
static inline void tty_audit_push(struct tty_struct *tty)
{
}
static inline void tty_audit_push_task(struct task_struct *tsk,
static inline int tty_audit_push_task(struct task_struct *tsk,
				      uid_t loginuid, u32 sessionid)
{
	return 0;
}
#endif

+30 −37
Original line number Diff line number Diff line
@@ -467,23 +467,16 @@ static int audit_prepare_user_tty(pid_t pid, uid_t loginuid, u32 sessionid)
	struct task_struct *tsk;
	int err;

	read_lock(&tasklist_lock);
	rcu_read_lock();
	tsk = find_task_by_vpid(pid);
	err = -ESRCH;
	if (!tsk)
		goto out;
	err = 0;

	spin_lock_irq(&tsk->sighand->siglock);
	if (!tsk->signal->audit_tty)
		err = -EPERM;
	spin_unlock_irq(&tsk->sighand->siglock);
	if (err)
		goto out;

	tty_audit_push_task(tsk, loginuid, sessionid);
out:
	read_unlock(&tasklist_lock);
	if (!tsk) {
		rcu_read_unlock();
		return -ESRCH;
	}
	get_task_struct(tsk);
	rcu_read_unlock();
	err = tty_audit_push_task(tsk, loginuid, sessionid);
	put_task_struct(tsk);
	return err;
}

@@ -506,7 +499,7 @@ int audit_send_list(void *_dest)
}

struct sk_buff *audit_make_reply(int pid, int seq, int type, int done,
				 int multi, void *payload, int size)
				 int multi, const void *payload, int size)
{
	struct sk_buff	*skb;
	struct nlmsghdr	*nlh;
@@ -555,8 +548,8 @@ static int audit_send_reply_thread(void *arg)
 * Allocates an skb, builds the netlink message, and sends it to the pid.
 * No failure notifications.
 */
void audit_send_reply(int pid, int seq, int type, int done, int multi,
		      void *payload, int size)
static void audit_send_reply(int pid, int seq, int type, int done, int multi,
			     const void *payload, int size)
{
	struct sk_buff *skb;
	struct task_struct *tsk;
@@ -880,40 +873,40 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
	case AUDIT_TTY_GET: {
		struct audit_tty_status s;
		struct task_struct *tsk;
		unsigned long flags;

		read_lock(&tasklist_lock);
		rcu_read_lock();
		tsk = find_task_by_vpid(pid);
		if (!tsk)
			err = -ESRCH;
		else {
			spin_lock_irq(&tsk->sighand->siglock);
		if (tsk && lock_task_sighand(tsk, &flags)) {
			s.enabled = tsk->signal->audit_tty != 0;
			spin_unlock_irq(&tsk->sighand->siglock);
		}
		read_unlock(&tasklist_lock);
		audit_send_reply(NETLINK_CB(skb).pid, seq, AUDIT_TTY_GET, 0, 0,
				 &s, sizeof(s));
			unlock_task_sighand(tsk, &flags);
		} else
			err = -ESRCH;
		rcu_read_unlock();

		if (!err)
			audit_send_reply(NETLINK_CB(skb).pid, seq,
					 AUDIT_TTY_GET, 0, 0, &s, sizeof(s));
		break;
	}
	case AUDIT_TTY_SET: {
		struct audit_tty_status *s;
		struct task_struct *tsk;
		unsigned long flags;

		if (nlh->nlmsg_len < sizeof(struct audit_tty_status))
			return -EINVAL;
		s = data;
		if (s->enabled != 0 && s->enabled != 1)
			return -EINVAL;
		read_lock(&tasklist_lock);
		rcu_read_lock();
		tsk = find_task_by_vpid(pid);
		if (!tsk)
			err = -ESRCH;
		else {
			spin_lock_irq(&tsk->sighand->siglock);
		if (tsk && lock_task_sighand(tsk, &flags)) {
			tsk->signal->audit_tty = s->enabled != 0;
			spin_unlock_irq(&tsk->sighand->siglock);
		}
		read_unlock(&tasklist_lock);
			unlock_task_sighand(tsk, &flags);
		} else
			err = -ESRCH;
		rcu_read_unlock();
		break;
	}
	default:
Loading