netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Add audit uid to netlink credentials
@ 2005-02-04 16:58 Serge E. Hallyn
  2005-02-08  6:04 ` Patrick McHardy
  2005-02-09 14:17 ` David Woodhouse
  0 siblings, 2 replies; 29+ messages in thread
From: Serge E. Hallyn @ 2005-02-04 16:58 UTC (permalink / raw)
  To: netdev, davem, kuznet; +Cc: linux-audit


Most audit control messages are sent over netlink.  In order to properly
log the identity of the sender of audit control messages, we would like
to add the loginuid to the netlink_creds structure, as per the attached
patch.

thanks,
-serge

Signed-off-by: Serge Hallyn <serue@us.ibm.com>
Index: linux-2.6.10/include/linux/audit.h
===================================================================
--- linux-2.6.10.orig/include/linux/audit.h	2005-01-27 10:46:57.887036520 -0600
+++ linux-2.6.10/include/linux/audit.h	2005-01-27 10:51:37.408542792 -0600
@@ -145,7 +145,7 @@ extern void audit_inode(const char *name
 
 				/* Private API (for audit.c only) */
 extern int  audit_receive_filter(int type, int pid, int uid, int seq,
-				 void *data);
+				 void *data, uid_t loginuid);
 extern void audit_get_stamp(struct audit_context *ctx,
 			    struct timespec *t, int *serial);
 extern int  audit_set_loginuid(struct audit_context *ctx, uid_t loginuid);
@@ -179,10 +179,10 @@ extern void		    audit_log_d_path(struct
 					     const char *prefix,
 					     struct dentry *dentry,
 					     struct vfsmount *vfsmnt);
-extern int		    audit_set_rate_limit(int limit);
-extern int		    audit_set_backlog_limit(int limit);
-extern int		    audit_set_enabled(int state);
-extern int		    audit_set_failure(int state);
+extern int		    audit_set_rate_limit(int limit, uid_t loginuid);
+extern int		    audit_set_backlog_limit(int limit, uid_t loginuid);
+extern int		    audit_set_enabled(int state, uid_t loginuid);
+extern int		    audit_set_failure(int state, uid_t loginuid);
 
 				/* Private API (for auditsc.c only) */
 extern void		    audit_send_reply(int pid, int seq, int type,
Index: linux-2.6.10/include/linux/netlink.h
===================================================================
--- linux-2.6.10.orig/include/linux/netlink.h	2005-01-27 10:46:57.888036368 -0600
+++ linux-2.6.10/include/linux/netlink.h	2005-01-27 10:51:37.409542640 -0600
@@ -110,6 +110,7 @@ struct netlink_skb_parms
 	__u32			dst_pid;
 	__u32			dst_groups;
 	kernel_cap_t		eff_cap;
+	__u32			loginuid;	/* Login (audit) uid */
 };
 
 #define NETLINK_CB(skb)		(*(struct netlink_skb_parms*)&((skb)->cb))
Index: linux-2.6.10/kernel/audit.c
===================================================================
--- linux-2.6.10.orig/kernel/audit.c	2005-01-27 10:46:57.888036368 -0600
+++ linux-2.6.10/kernel/audit.c	2005-01-27 10:52:28.753737136 -0600
@@ -236,36 +236,36 @@ void audit_log_lost(const char *message)
 
 }
 
-int audit_set_rate_limit(int limit)
+int audit_set_rate_limit(int limit, uid_t loginuid)
 {
 	int old		 = audit_rate_limit;
 	audit_rate_limit = limit;
-	audit_log(current->audit_context, "audit_rate_limit=%d old=%d",
-		  audit_rate_limit, old);
+	audit_log(NULL, "audit_rate_limit=%d old=%d by loginuid %u",
+			audit_rate_limit, old, loginuid);
 	return old;
 }
 
-int audit_set_backlog_limit(int limit)
+int audit_set_backlog_limit(int limit, uid_t loginuid)
 {
 	int old		 = audit_backlog_limit;
 	audit_backlog_limit = limit;
-	audit_log(current->audit_context, "audit_backlog_limit=%d old=%d",
-		  audit_backlog_limit, old);
+	audit_log(NULL, "audit_backlog_limit=%d old=%d by loginuid %u",
+			audit_backlog_limit, old, loginuid);
 	return old;
 }
 
-int audit_set_enabled(int state)
+int audit_set_enabled(int state, uid_t loginuid)
 {
 	int old		 = audit_enabled;
 	if (state != 0 && state != 1)
 		return -EINVAL;
 	audit_enabled = state;
-	audit_log(current->audit_context, "audit_enabled=%d old=%d",
-		  audit_enabled, old);
+	audit_log(NULL, "audit_enabled=%d old=%d by loginuid %u",
+		  audit_enabled, old, loginuid);
 	return old;
 }
 
-int audit_set_failure(int state)
+int audit_set_failure(int state, uid_t loginuid)
 {
 	int old		 = audit_failure;
 	if (state != AUDIT_FAIL_SILENT
@@ -273,8 +273,8 @@ int audit_set_failure(int state)
 	    && state != AUDIT_FAIL_PANIC)
 		return -EINVAL;
 	audit_failure = state;
-	audit_log(current->audit_context, "audit_failure=%d old=%d",
-		  audit_failure, old);
+	audit_log(NULL, "audit_failure=%d old=%d by loginuid %u",
+		  audit_failure, old, loginuid);
 	return old;
 }
 
@@ -341,6 +341,7 @@ static int audit_receive_msg(struct sk_b
 	int			err;
 	struct audit_buffer	*ab;
 	u16			msg_type = nlh->nlmsg_type;
+	uid_t			loginuid; /* loginuid of sender */
 
 	err = audit_netlink_ok(NETLINK_CB(skb).eff_cap, msg_type);
 	if (err)
@@ -348,6 +349,7 @@ static int audit_receive_msg(struct sk_b
 
 	pid  = NETLINK_CREDS(skb)->pid;
 	uid  = NETLINK_CREDS(skb)->uid;
+	loginuid = NETLINK_CB(skb).loginuid;
 	seq  = nlh->nlmsg_seq;
 	data = NLMSG_DATA(nlh);
 
@@ -368,31 +370,33 @@ static int audit_receive_msg(struct sk_b
 			return -EINVAL;
 		status_get   = (struct audit_status *)data;
 		if (status_get->mask & AUDIT_STATUS_ENABLED) {
-			err = audit_set_enabled(status_get->enabled);
+			err = audit_set_enabled(status_get->enabled, loginuid);
 			if (err < 0) return err;
 		}
 		if (status_get->mask & AUDIT_STATUS_FAILURE) {
-			err = audit_set_failure(status_get->failure);
+			err = audit_set_failure(status_get->failure, loginuid);
 			if (err < 0) return err;
 		}
 		if (status_get->mask & AUDIT_STATUS_PID) {
 			int old   = audit_pid;
 			audit_pid = status_get->pid;
-			audit_log(current->audit_context,
-				  "audit_pid=%d old=%d", audit_pid, old);
+			audit_log(NULL, "audit_pid=%d old=%d by loginuid %u",
+				  audit_pid, old, loginuid);
 		}
 		if (status_get->mask & AUDIT_STATUS_RATE_LIMIT)
-			audit_set_rate_limit(status_get->rate_limit);
+			audit_set_rate_limit(status_get->rate_limit, loginuid);
 		if (status_get->mask & AUDIT_STATUS_BACKLOG_LIMIT)
-			audit_set_backlog_limit(status_get->backlog_limit);
+			audit_set_backlog_limit(status_get->backlog_limit,
+							loginuid);
 		break;
 	case AUDIT_USER:
 		ab = audit_log_start(NULL);
 		if (!ab)
 			break;	/* audit_panic has been called */
 		audit_log_format(ab,
-				 "user pid=%d uid=%d length=%d msg='%.1024s'",
-				 pid, uid,
+				 "user pid=%d uid=%d loginuid=%u length=%d"
+				 " msg='%.1024s'",
+				 pid, uid, loginuid,
 				 (int)(nlh->nlmsg_len
 				       - ((char *)data - (char *)nlh)),
 				 (char *)data);
@@ -408,7 +412,7 @@ static int audit_receive_msg(struct sk_b
 	case AUDIT_LIST:
 #ifdef CONFIG_AUDITSYSCALL
 		err = audit_receive_filter(nlh->nlmsg_type, pid, uid, seq,
-					   data);
+					   data, loginuid);
 #else
 		err = -EOPNOTSUPP;
 #endif
Index: linux-2.6.10/kernel/auditsc.c
===================================================================
--- linux-2.6.10.orig/kernel/auditsc.c	2005-01-27 10:46:57.890036064 -0600
+++ linux-2.6.10/kernel/auditsc.c	2005-01-27 10:52:53.776933032 -0600
@@ -228,7 +228,8 @@ static int audit_copy_rule(struct audit_
 	return 0;
 }
 
-int audit_receive_filter(int type, int pid, int uid, int seq, void *data)
+int audit_receive_filter(int type, int pid, int uid, int seq, void *data,
+							uid_t loginuid)
 {
 	u32		   flags;
 	struct audit_entry *entry;
@@ -263,6 +264,7 @@ int audit_receive_filter(int type, int p
 			err = audit_add_rule(entry, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_add_rule(entry, &audit_extlist);
+		audit_log(NULL, "loginuid %u added an audit rule\n", loginuid);
 		break;
 	case AUDIT_DEL:
 		flags =((struct audit_rule *)data)->flags;
@@ -272,6 +274,8 @@ int audit_receive_filter(int type, int p
 			err = audit_del_rule(data, &audit_entlist);
 		if (!err && (flags & AUDIT_AT_EXIT))
 			err = audit_del_rule(data, &audit_extlist);
+		audit_log(NULL, "loginuid %u removed an audit rule\n",
+							loginuid);
 		break;
 	default:
 		return -EINVAL;
Index: linux-2.6.10/net/netlink/af_netlink.c
===================================================================
--- linux-2.6.10.orig/net/netlink/af_netlink.c	2005-01-27 10:46:57.891035912 -0600
+++ linux-2.6.10/net/netlink/af_netlink.c	2005-01-27 10:51:37.411542336 -0600
@@ -928,6 +928,7 @@ static int netlink_sendmsg(struct kiocb 
 	NETLINK_CB(skb).groups	= nlk->groups;
 	NETLINK_CB(skb).dst_pid = dst_pid;
 	NETLINK_CB(skb).dst_groups = dst_groups;
+	NETLINK_CB(skb).loginuid = audit_get_loginuid(current->audit_context);
 	memcpy(NETLINK_CREDS(skb), &siocb->scm->creds, sizeof(struct ucred));
 
 	/* What can I do? Netlink is asynchronous, so that

^ permalink raw reply	[flat|nested] 29+ messages in thread
* RE: [PATCH] Add audit uid to netlink credentials
@ 2005-02-10 14:37 Chad Hanson
  2005-02-10 14:56 ` David Woodhouse
  0 siblings, 1 reply; 29+ messages in thread
From: Chad Hanson @ 2005-02-10 14:37 UTC (permalink / raw)
  To: Linux Audit Discussion, Chris Wright; +Cc: netdev, davem, kuznet


David Woodhouse wrote:
> 
> On Wed, 2005-02-09 at 16:19 -0800, Chris Wright wrote:
> > Then it comes back to the question of how to protect loginuid.  If it
> > can be spoofed by someone with CAP_AUDIT_WRITE, then it shouldn't be
> > write protected by CAP_AUDIT_CONTROL.
> 
> I'm not sure I agree with that. With CAP_AUDIT_WRITE you _can't_ modify
> the loginuid of the audit logs of your own actions. You can only modify
> the loginuid on the messages you pull out of thin air and send. You can
> already make up the rest of the payload -- why shouldn't you be allowed
> to make up the loginuid too? You could be reporting something that
> someone _else_ has done, after all.
> 

I'm not sure I understand this logic. 

Let me start with some background. The purpose of the loginuid is to record
the original creator of the process regardless of credential changes since
login. We use a capability to protect this, so it cannot be altered by most
programs, even those which write audit records. Placing the loginuid in the
payload effectively removes the purpose of CAP_AUDIT_CONTROL from all
userland audit messages. A program may be privileged to write an audit
record, but a granular security approach would not let them have the ability
to change the loginuid as well.

In your example of a process watching daemon, why would this daemon want to
spoof the credentials of the watched process? I can think of two examples.
One you are recording information for IDS like purposes of system and
process state. This could be a good use of audit, however, I don't
understand the need to make the loginuid of the audit logs match the process
you are watching. If you really did, y0ou are a heavily privileged process
already to watch all of these other processes, simply change your loginuid
through CAP_AUDIT_CONTROL and add that to the other privileges you already
have in monitoring the system state.

-Chad

^ permalink raw reply	[flat|nested] 29+ messages in thread
* RE: [PATCH] Add audit uid to netlink credentials
@ 2005-02-10 15:16 Chad Hanson
  0 siblings, 0 replies; 29+ messages in thread
From: Chad Hanson @ 2005-02-10 15:16 UTC (permalink / raw)
  To: Linux Audit Discussion; +Cc: kuznet, davem, netdev


David Woodhouse wrote:
> 
> Perhaps I misunderstand the intent of userspace AUDIT_WRITE. Can you
> provide examples of why you _wouldn't_ want to let a dæmon which is
> already sending random unvetted AUDIT_WRITE messages also specify the
> loginuid on _those_ messages?

The loginuid is part of the process state. This is the reason you do not
want to write out this information from a userspace application, as the
process state portions of the audit record are recorded by the kernel. 

-Chad

^ permalink raw reply	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2005-02-10 19:26 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-02-04 16:58 [PATCH] Add audit uid to netlink credentials Serge E. Hallyn
2005-02-08  6:04 ` Patrick McHardy
2005-02-09 13:34   ` Stephen Smalley
2005-02-09 14:10     ` Patrick McHardy
2005-02-09 14:19     ` Alexey Kuznetsov
2005-02-09 16:49       ` Alexey Kuznetsov
2005-02-09 18:52         ` Patrick McHardy
2005-02-09 18:53           ` Stephen Smalley
2005-02-09 14:17 ` David Woodhouse
2005-02-09 14:50   ` Serge Hallyn
2005-02-09 18:23     ` Stephen Smalley
2005-02-09 18:37       ` Chris Wright
2005-02-09 18:40         ` Stephen Smalley
2005-02-09 23:38           ` Chris Wright
2005-02-09 23:56             ` David Woodhouse
2005-02-10  0:19               ` Chris Wright
2005-02-10  9:20                 ` David Woodhouse
2005-02-10 12:40                 ` Stephen Smalley
2005-02-10 12:49                   ` David Woodhouse
2005-02-10 17:14                   ` Chris Wright
2005-02-10  1:11             ` Chris Wright
2005-02-10 12:36               ` Stephen Smalley
2005-02-10 12:51                 ` Stephen Smalley
  -- strict thread matches above, loose matches on Subject: below --
2005-02-10 14:37 Chad Hanson
2005-02-10 14:56 ` David Woodhouse
2005-02-10 17:52   ` Klaus Weidner
2005-02-10 18:10     ` Casey Schaufler
2005-02-10 19:26       ` Klaus Weidner
2005-02-10 15:16 Chad Hanson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).