Пример #1
0
umode_t
gr_acl_umask(void)
{
	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	return current->role->umask;
}
Пример #2
0
static int gr_log_start(int audit)
{
	char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
	char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
	char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;
#if (CONFIG_GRKERNSEC_FLOODTIME > 0 && CONFIG_GRKERNSEC_FLOODBURST > 0)
	unsigned long curr_secs = get_seconds();

	if (audit == GR_DO_AUDIT)
		goto set_fmt;

	if (!grsec_alert_wtime || time_after(curr_secs, grsec_alert_wtime + CONFIG_GRKERNSEC_FLOODTIME)) {
		grsec_alert_wtime = curr_secs;
		grsec_alert_fyet = 0;
	} else if (time_before_eq(curr_secs, grsec_alert_wtime + CONFIG_GRKERNSEC_FLOODTIME)
		    && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
		grsec_alert_fyet++;
	} else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
		grsec_alert_wtime = curr_secs;
		grsec_alert_fyet++;
		printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
		return FLOODING;
	}
	else return FLOODING;

set_fmt:
#endif
	memset(buf, 0, PAGE_SIZE);
	if (current->signal->curr_ip && gr_acl_is_enabled()) {
		sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: (%.64s:%c:%.950s) ");
		snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
	} else if (current->signal->curr_ip) {
		sprintf(fmt, "%s%s", loglevel, "grsec: From %pI4: ");
		snprintf(buf, PAGE_SIZE - 1, fmt, &current->signal->curr_ip);
	} else if (gr_acl_is_enabled()) {
		sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
		snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
	} else {
		sprintf(fmt, "%s%s", loglevel, "grsec: ");
		strcpy(buf, fmt);
	}

	return NO_FLOODING;
}
Пример #3
0
int
gr_acl_handle_rename(struct dentry *new_dentry,
		     struct dentry *parent_dentry,
		     const struct vfsmount *parent_mnt,
		     struct dentry *old_dentry,
		     struct inode *old_parent_inode,
		     struct vfsmount *old_mnt, const struct filename *newname, unsigned int flags)
{
	__u32 comp1, comp2;
	int error = 0;

	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	if (flags & RENAME_EXCHANGE) {
		comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, parent_mnt);
		comp2 =
		    gr_search_file(old_dentry,
				   GR_READ | GR_WRITE | GR_AUDIT_READ |
				   GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
	} else if (d_is_negative(new_dentry)) {
		comp1 = gr_check_create(new_dentry, parent_dentry, parent_mnt,
					GR_READ | GR_WRITE | GR_CREATE | GR_AUDIT_READ |
					GR_AUDIT_WRITE | GR_AUDIT_CREATE | GR_SUPPRESS);
		comp2 = gr_search_file(old_dentry, GR_READ | GR_WRITE |
				       GR_DELETE | GR_AUDIT_DELETE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, old_mnt);
	} else {
		comp1 = gr_search_file(new_dentry, GR_READ | GR_WRITE |
				       GR_CREATE | GR_DELETE |
				       GR_AUDIT_CREATE | GR_AUDIT_DELETE |
				       GR_AUDIT_READ | GR_AUDIT_WRITE |
				       GR_SUPPRESS, parent_mnt);
		comp2 =
		    gr_search_file(old_dentry,
				   GR_READ | GR_WRITE | GR_AUDIT_READ |
				   GR_DELETE | GR_AUDIT_DELETE |
				   GR_AUDIT_WRITE | GR_SUPPRESS, old_mnt);
	}

	if (RENAME_CHECK_SUCCESS(comp1, comp2) &&
	    ((comp1 & GR_AUDITS) || (comp2 & GR_AUDITS)))
		gr_log_fs_rbac_str(GR_DO_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
	else if (!RENAME_CHECK_SUCCESS(comp1, comp2) && !(comp1 & GR_SUPPRESS)
		 && !(comp2 & GR_SUPPRESS)) {
		gr_log_fs_rbac_str(GR_DONT_AUDIT, GR_RENAME_ACL_MSG, old_dentry, old_mnt, newname->name);
		error = -EACCES;
	} else if (unlikely(!RENAME_CHECK_SUCCESS(comp1, comp2)))
		error = -EACCES;

	return error;
}
Пример #4
0
int
gr_acl_handle_procpidmem(const struct task_struct *task)
{
	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	if (task != current && task->acl->mode & GR_PROTPROCFD)
		return -EACCES;

	return 0;
}
Пример #5
0
static int gr_log_start(int audit)
{
	char *loglevel = (audit == GR_DO_AUDIT) ? KERN_INFO : KERN_ALERT;
	char *fmt = (audit == GR_DO_AUDIT) ? gr_audit_log_fmt : gr_alert_log_fmt;
	char *buf = (audit == GR_DO_AUDIT) ? gr_audit_log_buf : gr_alert_log_buf;

	if (audit == GR_DO_AUDIT)
		goto set_fmt;

	if (!grsec_alert_wtime || jiffies - grsec_alert_wtime > CONFIG_GRKERNSEC_FLOODTIME * HZ) {
		grsec_alert_wtime = jiffies;
		grsec_alert_fyet = 0;
	} else if ((jiffies - grsec_alert_wtime < CONFIG_GRKERNSEC_FLOODTIME * HZ) && (grsec_alert_fyet < CONFIG_GRKERNSEC_FLOODBURST)) {
		grsec_alert_fyet++;
	} else if (grsec_alert_fyet == CONFIG_GRKERNSEC_FLOODBURST) {
		grsec_alert_wtime = jiffies;
		grsec_alert_fyet++;
		printk(KERN_ALERT "grsec: more alerts, logging disabled for %d seconds\n", CONFIG_GRKERNSEC_FLOODTIME);
		return FLOODING;
	} else return FLOODING;

set_fmt:
	memset(buf, 0, PAGE_SIZE);
	if (current->signal->curr_ip && gr_acl_is_enabled()) {
		sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: (%.64s:%c:%.950s) ");
		snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip), current->role->rolename, gr_roletype_to_char(), current->acl->filename);
	} else if (current->signal->curr_ip) {
		sprintf(fmt, "%s%s", loglevel, "grsec: From %u.%u.%u.%u: ");
		snprintf(buf, PAGE_SIZE - 1, fmt, NIPQUAD(current->signal->curr_ip));
	} else if (gr_acl_is_enabled()) {
		sprintf(fmt, "%s%s", loglevel, "grsec: (%.64s:%c:%.950s) ");
		snprintf(buf, PAGE_SIZE - 1, fmt, current->role->rolename, gr_roletype_to_char(), current->acl->filename);
	} else {
		sprintf(fmt, "%s%s", loglevel, "grsec: ");
		strcpy(buf, fmt);
	}

	return NO_FLOODING;
}
Пример #6
0
int
gr_acl_handle_procpidmem(const struct task_struct *task)
{
	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	if (task != current && (task->acl->mode & GR_PROTPROCFD) &&
	    !(current->acl->mode & GR_POVERRIDE) &&
	    !(current->role->roletype & GR_ROLE_GOD))
		return -EACCES;

	return 0;
}
Пример #7
0
void
gr_handle_crash(struct task_struct *task, const int sig)
{
	struct acl_subject_label *curr;
	struct acl_subject_label *curr2;
	struct task_struct *tsk, *tsk2;
	const struct cred *cred;
	const struct cred *cred2;

	if (sig != SIGSEGV && sig != SIGKILL && sig != SIGBUS && sig != SIGILL)
		return;

	if (unlikely(!gr_acl_is_enabled()))
		return;

	curr = task->acl;

	if (!(curr->resmask & (1 << GR_CRASH_RES)))
		return;

	if (time_before_eq(curr->expires, get_seconds())) {
		curr->expires = 0;
		curr->crashes = 0;
	}

	curr->crashes++;

	if (!curr->expires)
		curr->expires = get_seconds() + curr->res[GR_CRASH_RES].rlim_max;

	if ((curr->crashes >= curr->res[GR_CRASH_RES].rlim_cur) &&
	    time_after(curr->expires, get_seconds())) {
		rcu_read_lock();
		cred = __task_cred(task);
		if (cred->uid && proc_is_setxid(cred)) {
			gr_log_crash1(GR_DONT_AUDIT, GR_SEGVSTART_ACL_MSG, task, curr->res[GR_CRASH_RES].rlim_max);
			spin_lock(&gr_uid_lock);
			gr_insert_uid(cred->uid, curr->expires);
			spin_unlock(&gr_uid_lock);
			curr->expires = 0;
			curr->crashes = 0;
			read_lock(&tasklist_lock);
			do_each_thread(tsk2, tsk) {
				cred2 = __task_cred(tsk);
				if (tsk != task && cred2->uid == cred->uid)
					gr_fake_force_sig(SIGKILL, tsk);
			} while_each_thread(tsk2, tsk);
Пример #8
0
void
gr_acl_handle_exit(void)
{
	u16 id;
	char *rolename;

	if (unlikely(current->acl_sp_role && gr_acl_is_enabled() &&
	    !(current->role->roletype & GR_ROLE_PERSIST))) {
		id = current->acl_role_id;
		rolename = current->role->rolename;
		gr_set_acls(1);
		gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
	}

	gr_put_exec_file(current);
	return;
}
Пример #9
0
void
gr_log_resource(const struct task_struct *task,
		const int res, const unsigned long wanted, const int gt)
{
	const struct cred *cred;
	unsigned long rlim;

	if (!gr_acl_is_enabled() && !grsec_resource_logging)
		return;

	// not yet supported resource
	if (unlikely(!restab_log[res]))
		return;

	if (res == RLIMIT_CPU || res == RLIMIT_RTTIME)
		rlim = task->signal->rlim[res].rlim_max;
	else
		rlim = task->signal->rlim[res].rlim_cur;
	if (likely((rlim == RLIM_INFINITY) || (gt && wanted <= rlim) || (!gt && wanted < rlim)))
		return;

	rcu_read_lock();
	cred = __task_cred(task);

	if (res == RLIMIT_NPROC && 
	    (cap_raised(cred->cap_effective, CAP_SYS_ADMIN) || 
	     cap_raised(cred->cap_effective, CAP_SYS_RESOURCE)))
		goto out_rcu_unlock;
	else if (res == RLIMIT_MEMLOCK &&
		 cap_raised(cred->cap_effective, CAP_IPC_LOCK))
		goto out_rcu_unlock;
	else if (res == RLIMIT_NICE && cap_raised(cred->cap_effective, CAP_SYS_NICE))
		goto out_rcu_unlock;
	rcu_read_unlock();

	gr_log_res_ulong2_str(GR_DONT_AUDIT, GR_RESOURCE_MSG, task, wanted, restab_log[res], rlim);

	return;
out_rcu_unlock:
	rcu_read_unlock();
	return;
}
Пример #10
0
void
gr_acl_handle_exit(void)
{
	u16 id;
	char *rolename;
	struct file *exec_file;

	if (unlikely(current->acl_sp_role && gr_acl_is_enabled())) {
		id = current->acl_role_id;
		rolename = current->role->rolename;
		gr_set_acls(1);
		gr_log_str_int(GR_DONT_AUDIT_GOOD, GR_SPROLEL_ACL_MSG, rolename, id);
	}

	write_lock(&grsec_exec_file_lock);
	exec_file = current->exec_file;
	current->exec_file = NULL;
	write_unlock(&grsec_exec_file_lock);

	if (exec_file)
		fput(exec_file);
}
Пример #11
0
int
gr_check_crash_uid(const uid_t uid)
{
	int loc;
	int ret = 0;

	if (unlikely(!gr_acl_is_enabled()))
		return 0;

	spin_lock(&gr_uid_lock);
	loc = gr_find_uid(uid);

	if (loc < 0)
		goto out_unlock;

	if (time_before_eq(uid_set[loc].expires, get_seconds()))
		gr_remove_uid(loc);
	else
		ret = 1;

out_unlock:
	spin_unlock(&gr_uid_lock);
	return ret;
}