[PATCH 3/15] sanitize audit_ipc_obj()
by Al Viro
* get rid of allocations
* make it return void
* simplify callers
Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk>
---
include/linux/audit.h | 9 ++---
ipc/shm.c | 4 +--
ipc/util.c | 9 ++---
kernel/auditsc.c | 88 ++++++++++++++++++++----------------------------
4 files changed, 45 insertions(+), 65 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index e59feb9..97598f0 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -441,7 +441,7 @@ extern int audit_set_loginuid(struct task_struct *task, uid_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);
-extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
+extern void __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern int audit_bprm(struct linux_binprm *bprm);
extern void audit_socketcall(int nargs, unsigned long *args);
@@ -454,11 +454,10 @@ extern int __audit_mq_timedreceive(mqd_t mqdes, size_t msg_len, unsigned int __u
extern int __audit_mq_notify(mqd_t mqdes, const struct sigevent __user *u_notification);
extern int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat);
-static inline int audit_ipc_obj(struct kern_ipc_perm *ipcp)
+static inline void audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
if (unlikely(!audit_dummy_context()))
- return __audit_ipc_obj(ipcp);
- return 0;
+ __audit_ipc_obj(ipcp);
}
static inline int audit_fd_pair(int fd1, int fd2)
{
@@ -522,7 +521,7 @@ extern int audit_signals;
#define audit_get_loginuid(t) (-1)
#define audit_get_sessionid(t) (-1)
#define audit_log_task_context(b) do { ; } while (0)
-#define audit_ipc_obj(i) ({ 0; })
+#define audit_ipc_obj(i) ((void)0)
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
#define audit_bprm(p) ({ 0; })
#define audit_socketcall(n,a) ((void)0)
diff --git a/ipc/shm.c b/ipc/shm.c
index 867e5d6..e40065e 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -747,9 +747,7 @@ asmlinkage long sys_shmctl(int shmid, int cmd, struct shmid_ds __user *buf)
goto out;
}
- err = audit_ipc_obj(&(shp->shm_perm));
- if (err)
- goto out_unlock;
+ audit_ipc_obj(&(shp->shm_perm));
if (!capable(CAP_IPC_LOCK)) {
err = -EPERM;
diff --git a/ipc/util.c b/ipc/util.c
index 361fd1c..0aa8ed8 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -620,10 +620,9 @@ void ipc_rcu_putref(void *ptr)
int ipcperms (struct kern_ipc_perm *ipcp, short flag)
{ /* flag will most probably be 0 or S_...UGO from <linux/stat.h> */
- int requested_mode, granted_mode, err;
+ int requested_mode, granted_mode;
- if (unlikely((err = audit_ipc_obj(ipcp))))
- return err;
+ audit_ipc_obj(ipcp);
requested_mode = (flag >> 6) | (flag >> 3) | flag;
granted_mode = ipcp->mode;
if (current->euid == ipcp->cuid || current->euid == ipcp->uid)
@@ -797,9 +796,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
goto out_up;
}
- err = audit_ipc_obj(ipcp);
- if (err)
- goto out_unlock;
+ audit_ipc_obj(ipcp);
if (cmd == IPC_SET) {
err = audit_ipc_set_perm(extra_perm, perm->uid,
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 1d53aa8..c136047 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -221,6 +221,12 @@ struct audit_context {
int nargs;
long args[6];
} socketcall;
+ struct {
+ uid_t uid;
+ gid_t gid;
+ mode_t mode;
+ u32 osid;
+ } ipc;
};
#if AUDIT_DEBUG
@@ -578,19 +584,12 @@ static int audit_filter_rules(struct task_struct *tsk,
}
}
/* Find ipc objects that match */
- if (ctx) {
- struct audit_aux_data *aux;
- for (aux = ctx->aux; aux;
- aux = aux->next) {
- if (aux->type == AUDIT_IPC) {
- struct audit_aux_data_ipcctl *axi = (void *)aux;
- if (security_audit_rule_match(axi->osid, f->type, f->op, f->lsm_rule, ctx)) {
- ++result;
- break;
- }
- }
- }
- }
+ if (!ctx || ctx->type != AUDIT_IPC)
+ break;
+ if (security_audit_rule_match(ctx->ipc.osid,
+ f->type, f->op,
+ f->lsm_rule, ctx))
+ ++result;
}
break;
case AUDIT_ARG0:
@@ -1169,7 +1168,7 @@ static void audit_log_execve_info(struct audit_context *context,
kfree(buf);
}
-static void show_special(struct audit_context *context)
+static void show_special(struct audit_context *context, int *call_panic)
{
struct audit_buffer *ab;
int i;
@@ -1186,6 +1185,23 @@ static void show_special(struct audit_context *context)
audit_log_format(ab, " a%d=%lx", i,
context->socketcall.args[i]);
break; }
+ case AUDIT_IPC: {
+ u32 osid = context->ipc.osid;
+
+ audit_log_format(ab, "ouid=%u ogid=%u mode=%#o",
+ context->ipc.uid, context->ipc.gid, context->ipc.mode);
+ if (osid) {
+ char *ctx = NULL;
+ u32 len;
+ if (security_secid_to_secctx(osid, &ctx, &len)) {
+ audit_log_format(ab, " osid=%u", osid);
+ *call_panic = 1;
+ } else {
+ audit_log_format(ab, " obj=%s", ctx);
+ security_release_secctx(ctx, len);
+ }
+ }
+ break; }
}
audit_log_end(ab);
}
@@ -1302,26 +1318,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
axi->mqstat.mq_msgsize, axi->mqstat.mq_curmsgs);
break; }
- case AUDIT_IPC: {
- struct audit_aux_data_ipcctl *axi = (void *)aux;
- audit_log_format(ab,
- "ouid=%u ogid=%u mode=%#o",
- axi->uid, axi->gid, axi->mode);
- if (axi->osid != 0) {
- char *ctx = NULL;
- u32 len;
- if (security_secid_to_secctx(
- axi->osid, &ctx, &len)) {
- audit_log_format(ab, " osid=%u",
- axi->osid);
- call_panic = 1;
- } else {
- audit_log_format(ab, " obj=%s", ctx);
- security_release_secctx(ctx, len);
- }
- }
- break; }
-
case AUDIT_IPC_SET_PERM: {
struct audit_aux_data_ipcctl *axi = (void *)aux;
audit_log_format(ab,
@@ -1344,7 +1340,7 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
}
if (context->type)
- show_special(context);
+ show_special(context, &call_panic);
if (context->sockaddr_len) {
ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
@@ -2235,25 +2231,15 @@ int __audit_mq_getsetattr(mqd_t mqdes, struct mq_attr *mqstat)
* audit_ipc_obj - record audit data for ipc object
* @ipcp: ipc permissions
*
- * Returns 0 for success or NULL context or < 0 on error.
*/
-int __audit_ipc_obj(struct kern_ipc_perm *ipcp)
+void __audit_ipc_obj(struct kern_ipc_perm *ipcp)
{
- struct audit_aux_data_ipcctl *ax;
struct audit_context *context = current->audit_context;
-
- ax = kmalloc(sizeof(*ax), GFP_ATOMIC);
- if (!ax)
- return -ENOMEM;
-
- ax->uid = ipcp->uid;
- ax->gid = ipcp->gid;
- ax->mode = ipcp->mode;
- security_ipc_getsecid(ipcp, &ax->osid);
- ax->d.type = AUDIT_IPC;
- ax->d.next = context->aux;
- context->aux = (void *)ax;
- return 0;
+ context->ipc.uid = ipcp->uid;
+ context->ipc.gid = ipcp->gid;
+ context->ipc.mode = ipcp->mode;
+ security_ipc_getsecid(ipcp, &context->ipc.osid);
+ context->type = AUDIT_IPC;
}
/**
--
1.5.6.5
15 years, 10 months
[PATCH 2/15] sanitize audit_socketcall
by Al Viro
* don't bother with allocations
* now that it can't fail, make it return void
Signed-off-by: Al Viro <viro(a)zeniv.linux.org.uk>
---
include/linux/audit.h | 4 +-
kernel/auditsc.c | 66 ++++++++++++++++++++++++++++--------------------
net/socket.c | 4 +--
3 files changed, 41 insertions(+), 33 deletions(-)
diff --git a/include/linux/audit.h b/include/linux/audit.h
index 8f0672d..e59feb9 100644
--- a/include/linux/audit.h
+++ b/include/linux/audit.h
@@ -444,7 +444,7 @@ extern void audit_log_task_context(struct audit_buffer *ab);
extern int __audit_ipc_obj(struct kern_ipc_perm *ipcp);
extern int __audit_ipc_set_perm(unsigned long qbytes, uid_t uid, gid_t gid, mode_t mode);
extern int audit_bprm(struct linux_binprm *bprm);
-extern int audit_socketcall(int nargs, unsigned long *args);
+extern void audit_socketcall(int nargs, unsigned long *args);
extern int audit_sockaddr(int len, void *addr);
extern int __audit_fd_pair(int fd1, int fd2);
extern int audit_set_macxattr(const char *name);
@@ -525,7 +525,7 @@ extern int audit_signals;
#define audit_ipc_obj(i) ({ 0; })
#define audit_ipc_set_perm(q,u,g,m) ({ 0; })
#define audit_bprm(p) ({ 0; })
-#define audit_socketcall(n,a) ({ 0; })
+#define audit_socketcall(n,a) ((void)0)
#define audit_fd_pair(n,a) ({ 0; })
#define audit_sockaddr(len, addr) ({ 0; })
#define audit_set_macxattr(n) do { ; } while (0)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index aca9ddb..1d53aa8 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -156,12 +156,6 @@ struct audit_aux_data_execve {
struct mm_struct *mm;
};
-struct audit_aux_data_socketcall {
- struct audit_aux_data d;
- int nargs;
- unsigned long args[0];
-};
-
struct audit_aux_data_fd_pair {
struct audit_aux_data d;
int fd[2];
@@ -221,6 +215,14 @@ struct audit_context {
struct audit_tree_refs *trees, *first_trees;
int tree_count;
+ int type;
+ union {
+ struct {
+ int nargs;
+ long args[6];
+ } socketcall;
+ };
+
#if AUDIT_DEBUG
int put_count;
int ino_count;
@@ -1167,6 +1169,27 @@ static void audit_log_execve_info(struct audit_context *context,
kfree(buf);
}
+static void show_special(struct audit_context *context)
+{
+ struct audit_buffer *ab;
+ int i;
+
+ ab = audit_log_start(context, GFP_KERNEL, context->type);
+ if (!ab)
+ return;
+
+ switch (context->type) {
+ case AUDIT_SOCKETCALL: {
+ int nargs = context->socketcall.nargs;
+ audit_log_format(ab, "nargs=%d", nargs);
+ for (i = 0; i < nargs; i++)
+ audit_log_format(ab, " a%d=%lx", i,
+ context->socketcall.args[i]);
+ break; }
+ }
+ audit_log_end(ab);
+}
+
static void audit_log_exit(struct audit_context *context, struct task_struct *tsk)
{
int i, call_panic = 0;
@@ -1311,13 +1334,6 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_execve_info(context, &ab, axi);
break; }
- case AUDIT_SOCKETCALL: {
- struct audit_aux_data_socketcall *axs = (void *)aux;
- audit_log_format(ab, "nargs=%d", axs->nargs);
- for (i=0; i<axs->nargs; i++)
- audit_log_format(ab, " a%d=%lx", i, axs->args[i]);
- break; }
-
case AUDIT_FD_PAIR: {
struct audit_aux_data_fd_pair *axs = (void *)aux;
audit_log_format(ab, "fd0=%d fd1=%d", axs->fd[0], axs->fd[1]);
@@ -1327,6 +1343,9 @@ static void audit_log_exit(struct audit_context *context, struct task_struct *ts
audit_log_end(ab);
}
+ if (context->type)
+ show_special(context);
+
if (context->sockaddr_len) {
ab = audit_log_start(context, GFP_KERNEL, AUDIT_SOCKADDR);
if (ab) {
@@ -1604,6 +1623,7 @@ void audit_syscall_exit(int valid, long return_code)
context->target_pid = 0;
context->target_sid = 0;
context->sockaddr_len = 0;
+ context->type = 0;
kfree(context->filterkey);
context->filterkey = NULL;
tsk->audit_context = context;
@@ -2292,27 +2312,17 @@ int audit_bprm(struct linux_binprm *bprm)
* @nargs: number of args
* @args: args array
*
- * Returns 0 for success or NULL context or < 0 on error.
*/
-int audit_socketcall(int nargs, unsigned long *args)
+void audit_socketcall(int nargs, unsigned long *args)
{
- struct audit_aux_data_socketcall *ax;
struct audit_context *context = current->audit_context;
if (likely(!context || context->dummy))
- return 0;
-
- ax = kmalloc(sizeof(*ax) + nargs * sizeof(unsigned long), GFP_KERNEL);
- if (!ax)
- return -ENOMEM;
-
- ax->nargs = nargs;
- memcpy(ax->args, args, nargs * sizeof(unsigned long));
+ return;
- ax->d.type = AUDIT_SOCKETCALL;
- ax->d.next = context->aux;
- context->aux = (void *)ax;
- return 0;
+ context->type = AUDIT_SOCKETCALL;
+ context->socketcall.nargs = nargs;
+ memcpy(context->socketcall.args, args, nargs * sizeof(unsigned long));
}
/**
diff --git a/net/socket.c b/net/socket.c
index 92764d8..aba5a50 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -2066,9 +2066,7 @@ asmlinkage long sys_socketcall(int call, unsigned long __user *args)
if (copy_from_user(a, args, nargs[call]))
return -EFAULT;
- err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
- if (err)
- return err;
+ audit_socketcall(nargs[call] / sizeof(unsigned long), a);
a0 = a[0];
a1 = a[1];
--
1.5.6.5
15 years, 10 months
audit 1.7.10 released
by Steve Grubb
Hi,
I've just released a new version of the audit daemon. It can be downloaded
from http://people.redhat.com/sgrubb/audit It will also be in rawhide
soon. The Changelog is:
- Fix ausearch and aureport to handle out of order events
- Add line-buffer option to ausearch & timeout pipe input (Tony Jones)
- Add support in ausearch/report for tty data
- Add interpretations for epoll_ctl, lseek, and sigaction to libauparse
- In audisp-remote, allow the keyword "any" for local_port
- Man page updates
- Don't consider 0x7F to be a printable character
- Tighten parsing for -m and -w options in auditctl
- Add session query hint for aulast proof
- Fix audisp-remote to tolerate krb5 config options when not supported
- Created new aureport option for tty keystroke report
- audispd should detect backup config files and not use them
- When checking for ack in netlink interface, retry on EAGAIN a few times
- Trim a trailing whitespace from audit event written to disk
- In aureport, fix mods report to show acct acted upon
This release finally fixes the longstanding problem of grouping interlaced
audit records correctly for ausearch and aureport. Auparse still has the
problem. It turns out that the kernel does not serialize audit event records
that go together. Records from two unrelated events can be intermingled.
Previously, ausearch/report just used a change in timestamp + serial number
to distinguish the end of an event. In the process of fixing this problem, I
discovered a way to make ausearch/report run faster. My testing shows about a
25% performance improvement...but your usage may have different results.
Ausearch is now smarter about taking input from a pipe thanks to a patch from
Tony Jones. You can now do "tail -f /var/log/audit/audit.log | ausearch -i"
and it should output events based on wall clock timeout or event completion
rather than when it sees an event complete.
Perhaps the biggest improvement in this release is TTY auditing is now fully
integrated. Ausearch can interpret TTY data fields. Aureport now has a --tty
option to see TTY data as a report.
The aulast program can now tell you the ausearch command to retrieve audit
events for a specific session when you give it the --proof option.
In aureport, the account modification report was not showing the actual
account that was modified. It now does.
And lastly, I found that all audit events written to disk had a trailing space
character at the end of each record. That is now removed so that each record
is 1 byte shorter to save disk space.
Please let me know if you run across any problems with this release.
-Steve
15 years, 10 months
Bugs in audit tables
by Loredan Stancu
Hi Steve!
I found another bugs in audit tabel:
1. No rules can be added to exclude,user,entry,task tables.
2. action 'never' can't be set.
I tested with audit version 1.7.9 on gentoo system. kernel version
2.6.26-gentoo-r3
- Loredan
15 years, 10 months
Auditd and syslog.
by Chris Stringer
Hello, all.
This is my first question of the mailing list and I hope that I haven't
missed something too obvious here.
I'm new to auditd, but it sounds like it will do precisely what I wish
to do. I'd like to track user movements from the point of login to
logout. I've been figuring out most everything fine, but one question
remains that I haven't found a clear answer to. Is it possible to make
auditd use syslog to output it's logs? I'd like to use syslog to
centrally rollup the auditd logs of all of the secure systems.
If this isn't possible, is it due to security concerns? I know that the
api to use syslog is fairly simple, so the lack of the feature shouldn't
be complexity.
I did do searches for this information, so I apologize if I missed this
question elsewhere.
Thanks for your time..
-Chris S.
15 years, 10 months
[Fwd: Re: Rules order]
by Loredan Stancu
On Monday 08 December 2008 05:11:45 pm you wrote:
> As you can see rule with 'never' action is first introduced but in exit
> table they are in reverse order.
Anything with a path or dir in it actually winds up on a hidden filter inside
the audit system. It runs from the exit filter, but it is distinct. I am
asking Al Viro what his thoughts are about this. This would have been a good
email for the mail list so that everyone can see Al's response.
-Steve
15 years, 10 months
[Fwd: Rules order]
by Loredan Stancu
Hi,
I added the following rules:
# ./sbin/auditctl -a exit,never -F path=/usr/bin/vim -F perm=x -F uid=0
# ./sbin/auditctl -a exit,always -F uid=0 -F success=1 -S execve -S open
-k root_exec
# ./sbin/auditctl -l
LIST_RULES: exit,always uid=0 success=1 (0x1) key=root_exec
syscall=open,execve
LIST_RULES: exit,never watch=/usr/bin/vim perm=x uid=0
As you can see rule with 'never' action is first introduced but in exit
table they are in reverse order. No matter in what order the rules are
inserted form command line in the exit table rules with 'never' action
are appended to the end of list making no effects.
--
Loredan Stancu | system administrator | admin(a)myclar.ro
MyClar Connection | http://www.myclar.ro | loredan.stancu(a)myclar.ro
15 years, 10 months
audit and krb5
by Loredan Stancu
Hi again,
I'm trying to setup audit and krb5. I have a few questions about this:
1. It if necessary to have krb5 daemon up to work with audit?
I used kadmin.local to add a principal and to add a keytab but when I try
to start audit it says that no principal match was found.
Can you please give me an example how can I set krb5 to work with auditd?
Thx,
Loredan
15 years, 11 months
audisp resend question
by LC Bruzenak
Steve or DJ,
Have you guys thought about how I can re-send submitter events from a
client to a master auditd after failure?
I'm thinking of the case where the aggregating/collector machine has
failed and the clients then shut down as configured.
Say the problem on the collector is fixed and it comes back up.
Then we bring up the client sender machine(s).
I haven't tested this but I do not think the missed events will get sent
right?
How can I try to resend the events to the collector? I apologize if
there is a way I've missed. I think it would be possible to write the
events to a separate file and resend those on restart. But even if there
is a manual/semi-manual way to do this it beats nothing in my case.
Thx,
LCB.
--
LC (Lenny) Bruzenak
lenny(a)magitekltd.com
15 years, 11 months
Re: audisp-prelude problems
by Loredan Stancu
On the same topic, I sow that audisp-remote plugin can send events remote
using a secure connection(transport = ssl in audisp-remote.conf file).
When using tcp as a transport method events arrive to the a aggregation
auditd but when using ssl no event arrive?
How can I use a secure connection to transmit events?
> On Thursday 04 December 2008 09:57:54 Loredan Stancu wrote:
>> Now I'll have to user audisp-remote plugin to centralize events.
>
> One further refinement to what I said yesterday about remote logging. You
> probably want to set the local_port value to something < 1024 in the
> remote
> configuration files. Then in the aggregating auditd, set the
> tcp_client_ports to
> the same thing.
>
> This is a security feature to prevent random user space apps from trying
> audit
> log injection attacks. For experimenting or casual use you don't need to
> set
> these up, but for production use you must.
>
> If you use kerberos authentication, then you have even more protection.
> But
> setting up kerberos for this is a little more than I want to explain.
>
> -Steve
>
15 years, 11 months