summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2017-05-02 10:16:05 -0400
committerPaul Moore <paul@paul-moore.com>2017-05-02 10:16:05 -0400
commitb6c7c115c2ce679ac536f0adf0ff518fcd939196 (patch)
tree0c7671fe200ec777495bec8c830ef17c12e76255 /kernel
parent45a0642b4d021a2f50d5db9c191b5bfe60bfa1c7 (diff)
audit: store the auditd PID as a pid struct instead of pid_t
This is arguably the right thing to do, and will make it easier when we start supporting multiple audit daemons in different namespaces. Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/audit.c84
-rw-r--r--kernel/audit.h2
2 files changed, 58 insertions, 28 deletions
diff --git a/kernel/audit.c b/kernel/audit.c
index b40f3c4727e1..a2f7803a68d0 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -58,6 +58,7 @@
58#include <linux/rcupdate.h> 58#include <linux/rcupdate.h>
59#include <linux/mutex.h> 59#include <linux/mutex.h>
60#include <linux/gfp.h> 60#include <linux/gfp.h>
61#include <linux/pid.h>
61 62
62#include <linux/audit.h> 63#include <linux/audit.h>
63 64
@@ -117,7 +118,7 @@ struct audit_net {
117 * or the included spinlock for writing. 118 * or the included spinlock for writing.
118 */ 119 */
119static struct auditd_connection { 120static struct auditd_connection {
120 int pid; 121 struct pid *pid;
121 u32 portid; 122 u32 portid;
122 struct net *net; 123 struct net *net;
123 spinlock_t lock; 124 spinlock_t lock;
@@ -220,18 +221,41 @@ struct audit_reply {
220 * Description: 221 * Description:
221 * Return 1 if the task is a registered audit daemon, 0 otherwise. 222 * Return 1 if the task is a registered audit daemon, 0 otherwise.
222 */ 223 */
223int auditd_test_task(const struct task_struct *task) 224int auditd_test_task(struct task_struct *task)
224{ 225{
225 int rc; 226 int rc;
226 227
227 rcu_read_lock(); 228 rcu_read_lock();
228 rc = (auditd_conn.pid && task->tgid == auditd_conn.pid ? 1 : 0); 229 rc = (auditd_conn.pid && auditd_conn.pid == task_tgid(task) ? 1 : 0);
229 rcu_read_unlock(); 230 rcu_read_unlock();
230 231
231 return rc; 232 return rc;
232} 233}
233 234
234/** 235/**
236 * auditd_pid_vnr - Return the auditd PID relative to the namespace
237 * @auditd: the auditd connection
238 *
239 * Description:
240 * Returns the PID in relation to the namespace, 0 on failure. This function
241 * takes the RCU read lock internally, but if the caller needs to protect the
242 * auditd_connection pointer it should take the RCU read lock as well.
243 */
244static pid_t auditd_pid_vnr(const struct auditd_connection *auditd)
245{
246 pid_t pid;
247
248 rcu_read_lock();
249 if (!auditd || !auditd->pid)
250 pid = 0;
251 else
252 pid = pid_vnr(auditd->pid);
253 rcu_read_unlock();
254
255 return pid;
256}
257
258/**
235 * audit_get_sk - Return the audit socket for the given network namespace 259 * audit_get_sk - Return the audit socket for the given network namespace
236 * @net: the destination network namespace 260 * @net: the destination network namespace
237 * 261 *
@@ -428,12 +452,17 @@ static int audit_set_failure(u32 state)
428 * This function will obtain and drop network namespace references as 452 * This function will obtain and drop network namespace references as
429 * necessary. 453 * necessary.
430 */ 454 */
431static void auditd_set(int pid, u32 portid, struct net *net) 455static void auditd_set(struct pid *pid, u32 portid, struct net *net)
432{ 456{
433 unsigned long flags; 457 unsigned long flags;
434 458
435 spin_lock_irqsave(&auditd_conn.lock, flags); 459 spin_lock_irqsave(&auditd_conn.lock, flags);
436 auditd_conn.pid = pid; 460 if (auditd_conn.pid)
461 put_pid(auditd_conn.pid);
462 if (pid)
463 auditd_conn.pid = get_pid(pid);
464 else
465 auditd_conn.pid = NULL;
437 auditd_conn.portid = portid; 466 auditd_conn.portid = portid;
438 if (auditd_conn.net) 467 if (auditd_conn.net)
439 put_net(auditd_conn.net); 468 put_net(auditd_conn.net);
@@ -1059,11 +1088,13 @@ static int audit_set_feature(struct sk_buff *skb)
1059 return 0; 1088 return 0;
1060} 1089}
1061 1090
1062static int audit_replace(pid_t pid) 1091static int audit_replace(struct pid *pid)
1063{ 1092{
1093 pid_t pvnr;
1064 struct sk_buff *skb; 1094 struct sk_buff *skb;
1065 1095
1066 skb = audit_make_reply(0, AUDIT_REPLACE, 0, 0, &pid, sizeof(pid)); 1096 pvnr = pid_vnr(pid);
1097 skb = audit_make_reply(0, AUDIT_REPLACE, 0, 0, &pvnr, sizeof(pvnr));
1067 if (!skb) 1098 if (!skb)
1068 return -ENOMEM; 1099 return -ENOMEM;
1069 return auditd_send_unicast_skb(skb); 1100 return auditd_send_unicast_skb(skb);
@@ -1093,9 +1124,9 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1093 memset(&s, 0, sizeof(s)); 1124 memset(&s, 0, sizeof(s));
1094 s.enabled = audit_enabled; 1125 s.enabled = audit_enabled;
1095 s.failure = audit_failure; 1126 s.failure = audit_failure;
1096 rcu_read_lock(); 1127 /* NOTE: use pid_vnr() so the PID is relative to the current
1097 s.pid = auditd_conn.pid; 1128 * namespace */
1098 rcu_read_unlock(); 1129 s.pid = auditd_pid_vnr(&auditd_conn);
1099 s.rate_limit = audit_rate_limit; 1130 s.rate_limit = audit_rate_limit;
1100 s.backlog_limit = audit_backlog_limit; 1131 s.backlog_limit = audit_backlog_limit;
1101 s.lost = atomic_read(&audit_lost); 1132 s.lost = atomic_read(&audit_lost);
@@ -1121,36 +1152,36 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1121 return err; 1152 return err;
1122 } 1153 }
1123 if (s.mask & AUDIT_STATUS_PID) { 1154 if (s.mask & AUDIT_STATUS_PID) {
1124 /* NOTE: we are using task_tgid_vnr() below because 1155 /* NOTE: we are using the vnr PID functions below
1125 * the s.pid value is relative to the namespace 1156 * because the s.pid value is relative to the
1126 * of the caller; at present this doesn't matter 1157 * namespace of the caller; at present this
1127 * much since you can really only run auditd 1158 * doesn't matter much since you can really only
1128 * from the initial pid namespace, but something 1159 * run auditd from the initial pid namespace, but
1129 * to keep in mind if this changes */ 1160 * something to keep in mind if this changes */
1130 int new_pid = s.pid; 1161 pid_t new_pid = s.pid;
1131 pid_t auditd_pid; 1162 pid_t auditd_pid;
1132 pid_t requesting_pid = task_tgid_vnr(current); 1163 struct pid *req_pid = task_tgid(current);
1164
1165 /* sanity check - PID values must match */
1166 if (new_pid != pid_vnr(req_pid))
1167 return -EINVAL;
1133 1168
1134 /* test the auditd connection */ 1169 /* test the auditd connection */
1135 audit_replace(requesting_pid); 1170 audit_replace(req_pid);
1136 1171
1137 rcu_read_lock(); 1172 auditd_pid = auditd_pid_vnr(&auditd_conn);
1138 auditd_pid = auditd_conn.pid;
1139 /* only the current auditd can unregister itself */ 1173 /* only the current auditd can unregister itself */
1140 if ((!new_pid) && (requesting_pid != auditd_pid)) { 1174 if ((!new_pid) && (new_pid != auditd_pid)) {
1141 rcu_read_unlock();
1142 audit_log_config_change("audit_pid", new_pid, 1175 audit_log_config_change("audit_pid", new_pid,
1143 auditd_pid, 0); 1176 auditd_pid, 0);
1144 return -EACCES; 1177 return -EACCES;
1145 } 1178 }
1146 /* replacing a healthy auditd is not allowed */ 1179 /* replacing a healthy auditd is not allowed */
1147 if (auditd_pid && new_pid) { 1180 if (auditd_pid && new_pid) {
1148 rcu_read_unlock();
1149 audit_log_config_change("audit_pid", new_pid, 1181 audit_log_config_change("audit_pid", new_pid,
1150 auditd_pid, 0); 1182 auditd_pid, 0);
1151 return -EEXIST; 1183 return -EEXIST;
1152 } 1184 }
1153 rcu_read_unlock();
1154 1185
1155 if (audit_enabled != AUDIT_OFF) 1186 if (audit_enabled != AUDIT_OFF)
1156 audit_log_config_change("audit_pid", new_pid, 1187 audit_log_config_change("audit_pid", new_pid,
@@ -1158,8 +1189,7 @@ static int audit_receive_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1158 1189
1159 if (new_pid) { 1190 if (new_pid) {
1160 /* register a new auditd connection */ 1191 /* register a new auditd connection */
1161 auditd_set(new_pid, 1192 auditd_set(req_pid, NETLINK_CB(skb).portid,
1162 NETLINK_CB(skb).portid,
1163 sock_net(NETLINK_CB(skb).sk)); 1193 sock_net(NETLINK_CB(skb).sk));
1164 /* try to process any backlog */ 1194 /* try to process any backlog */
1165 wake_up_interruptible(&kauditd_wait); 1195 wake_up_interruptible(&kauditd_wait);
diff --git a/kernel/audit.h b/kernel/audit.h
index 18f3c2deeccf..4987ea2a4702 100644
--- a/kernel/audit.h
+++ b/kernel/audit.h
@@ -218,7 +218,7 @@ extern void audit_log_name(struct audit_context *context,
218 struct audit_names *n, const struct path *path, 218 struct audit_names *n, const struct path *path,
219 int record_num, int *call_panic); 219 int record_num, int *call_panic);
220 220
221extern int auditd_test_task(const struct task_struct *task); 221extern int auditd_test_task(struct task_struct *task);
222 222
223#define AUDIT_INODE_BUCKETS 32 223#define AUDIT_INODE_BUCKETS 32
224extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS]; 224extern struct list_head audit_inode_hash[AUDIT_INODE_BUCKETS];