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

Commit a33e6751 authored by Al Viro's avatar Al Viro
Browse files

sanitize audit_ipc_obj()



* get rid of allocations
* make it return void
* simplify callers

Signed-off-by: default avatarAl Viro <viro@zeniv.linux.org.uk>
parent f3298dc4
Loading
Loading
Loading
Loading
+4 −5
Original line number Diff line number Diff line
@@ -443,7 +443,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);
@@ -460,11 +460,10 @@ extern int __audit_log_bprm_fcaps(struct linux_binprm *bprm,
				  const struct cred *old);
extern int __audit_log_capset(pid_t pid, const struct cred *new, const struct cred *old);

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)
{
@@ -546,7 +545,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)
+1 −3
Original line number Diff line number Diff line
@@ -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)) {
			uid_t euid = current_euid();
+3 −6
Original line number Diff line number Diff line
@@ -624,10 +624,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> */
	uid_t euid = current_euid();
	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 (euid == ipcp->cuid ||
@@ -803,9 +802,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,
+37 −51
Original line number Diff line number Diff line
@@ -247,6 +247,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
@@ -605,19 +611,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;
				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:
@@ -1228,7 +1227,7 @@ static void audit_log_fcaps(struct audit_buffer *ab, struct audit_names *name)
		audit_log_format(ab, " cap_fe=%d cap_fver=%x", name->fcap.fE, name->fcap_ver);
}

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;
@@ -1245,6 +1244,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);
}
@@ -1363,26 +1379,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,
@@ -1427,7 +1423,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);
@@ -2349,25 +2345,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;
}

/**