Use new qssb_append_*_syscall functions, remove old fields
Αυτή η υποβολή περιλαμβάνεται σε:
		
							
								
								
									
										79
									
								
								qssb.h
									
									
									
									
									
								
							
							
						
						
									
										79
									
								
								qssb.h
									
									
									
									
									
								
							| @@ -212,8 +212,6 @@ struct qssb_policy | ||||
| 	/* Bind mounts all paths in path_policies into the chroot and applies | ||||
| 	 non-landlock policies */ | ||||
| 	int mount_path_policies_to_chroot; | ||||
| 	int *blacklisted_syscalls; | ||||
| 	int *whitelisted_syscalls; | ||||
| 	char chroot_target_path[PATH_MAX]; | ||||
| 	const char *chdir_path; | ||||
|  | ||||
| @@ -283,7 +281,6 @@ int qssb_append_denied_syscalls(struct qssb_policy *qssb_policy, int *syscalls, | ||||
| struct qssb_policy *qssb_init_policy() | ||||
| { | ||||
| 	struct qssb_policy *result = (struct qssb_policy *) calloc(1, sizeof(struct qssb_policy)); | ||||
| 	result->blacklisted_syscalls = default_blacklisted_syscals; | ||||
| 	result->drop_caps = 1; | ||||
| 	result->not_dumpable = 1; | ||||
| 	result->no_new_privs = 1; | ||||
| @@ -632,13 +629,13 @@ static int drop_caps() | ||||
| /* | ||||
|  * Enables the per_syscall seccomp action for system calls | ||||
|  * | ||||
|  * syscalls: array of system calls numbers. -1 must be the last entry. | ||||
|  * syscalls: array of system calls numbers. | ||||
|  * per_syscall: action to apply for each system call | ||||
|  * default_action: the default action at the end | ||||
|  * | ||||
|  * @returns: 0 on success, -1 on error | ||||
|  */ | ||||
| static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int default_action) | ||||
| static int seccomp_enable(int *syscalls, size_t n, unsigned int per_syscall, unsigned int default_action) | ||||
| { | ||||
| 	struct sock_filter filter[1024] = | ||||
| 	{ | ||||
| @@ -646,15 +643,13 @@ static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int | ||||
| 	}; | ||||
|  | ||||
| 	unsigned short int current_filter_index = 1; | ||||
| 	while(*syscalls >= 0) | ||||
| 	for(size_t i = 0; i < n; i++) | ||||
| 	{ | ||||
| 		unsigned int sysc = (unsigned int) *syscalls; | ||||
| 		unsigned int sysc = (unsigned int) syscalls[i]; | ||||
| 		struct sock_filter syscall = BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, sysc, 0, 1); | ||||
| 		struct sock_filter action = BPF_STMT(BPF_RET+BPF_K, per_syscall); | ||||
| 		filter[current_filter_index++] = syscall; | ||||
| 		filter[current_filter_index++] = action; | ||||
|  | ||||
| 		++syscalls; | ||||
| 	} | ||||
|  | ||||
| 	struct sock_filter da = BPF_STMT(BPF_RET+BPF_K, default_action); | ||||
| @@ -678,21 +673,21 @@ static int seccomp_enable(int *syscalls, unsigned int per_syscall, unsigned int | ||||
| /* | ||||
|  * Blacklists the specified systemcalls. | ||||
|  * | ||||
|  * syscalls: array of system calls numbers. -1 must be the last entry. | ||||
|  * syscalls: array of system calls numbers. | ||||
|  */ | ||||
| static int seccomp_enable_blacklist(int *syscalls) | ||||
| static int seccomp_enable_blacklist(int *syscalls, size_t n) | ||||
| { | ||||
| 	return seccomp_enable(syscalls, SECCOMP_RET_KILL, SECCOMP_RET_ALLOW); | ||||
| 	return seccomp_enable(syscalls, n, SECCOMP_RET_KILL, SECCOMP_RET_ALLOW); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Whitelists the specified systemcalls. | ||||
|  * | ||||
|  * syscalls: array of system calls numbers. -1 must be the last entry. | ||||
|  * syscalls: array of system calls numbers. | ||||
|  */ | ||||
| static int seccomp_enable_whitelist(int *syscalls) | ||||
| static int seccomp_enable_whitelist(int *syscalls, size_t n) | ||||
| { | ||||
| 	return seccomp_enable(syscalls, SECCOMP_RET_ALLOW, SECCOMP_RET_KILL); | ||||
| 	return seccomp_enable(syscalls, n, SECCOMP_RET_ALLOW, SECCOMP_RET_KILL); | ||||
| } | ||||
|  | ||||
| #if HAVE_LANDLOCK == 1 | ||||
| @@ -814,9 +809,9 @@ static int landlock_prepare_ruleset(struct qssb_path_policy *policies) | ||||
| /* Checks for illogical or dangerous combinations */ | ||||
| static int check_policy_sanity(struct qssb_policy *policy) | ||||
| { | ||||
| 	if(policy->blacklisted_syscalls != NULL && policy->whitelisted_syscalls != NULL) | ||||
| 	if(policy->denied_syscalls.used > 0 && policy->allowed_syscalls.used > 0) | ||||
| 	{ | ||||
| 		QSSB_LOG_ERROR("Error: Cannot mix blacklisted and whitelisted systemcalls\n"); | ||||
| 		QSSB_LOG_ERROR("Error: Cannot mix allowed and denied systemcalls in policy\n"); | ||||
| 		return -EINVAL; | ||||
| 	} | ||||
|  | ||||
| @@ -836,7 +831,7 @@ static int check_policy_sanity(struct qssb_policy *policy) | ||||
|  | ||||
| 	if(policy->no_new_privs != 1) | ||||
| 	{ | ||||
| 		if(policy->blacklisted_syscalls != NULL || policy->whitelisted_syscalls != NULL) | ||||
| 		if(policy->allowed_syscalls.used > 0 || policy->denied_syscalls.used > 0) | ||||
| 		{ | ||||
| 			QSSB_LOG_ERROR("no_new_privs = 1 is required for seccomp filtering!\n"); | ||||
| 			return -1; | ||||
| @@ -902,37 +897,15 @@ static int enable_no_fs(struct qssb_policy *policy) | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		if(policy->whitelisted_syscalls == NULL) | ||||
| 		if(policy->allowed_syscalls.used == 0) | ||||
| 		{ | ||||
| 			if(policy->blacklisted_syscalls == NULL) | ||||
| 			{ | ||||
| 				policy->blacklisted_syscalls = fs_access_syscalls; | ||||
| 			} | ||||
| 			else | ||||
| 			{ | ||||
| 				size_t nbl = 0; | ||||
| 				size_t nfs = sizeof(fs_access_syscalls)/sizeof(fs_access_syscalls[0]); | ||||
| 				int *tmp = policy->blacklisted_syscalls; | ||||
| 				while(*tmp != -1) | ||||
| 				{ | ||||
| 					++nbl; | ||||
| 					++tmp; | ||||
| 				} | ||||
| 				size_t n = (nbl + nfs) + 1; | ||||
| 				tmp = (int *) calloc(n, sizeof(int)); | ||||
| 				int *tmp_begin = tmp; | ||||
| 				if(tmp == NULL) | ||||
| 				{ | ||||
| 					QSSB_LOG_ERROR("Failed to expand blacklisted syscall array\n"); | ||||
| 					return -1; | ||||
| 				} | ||||
| 				memcpy(tmp, policy->blacklisted_syscalls, nbl*sizeof(int)); | ||||
| 				tmp+=nbl; | ||||
| 				memcpy(tmp, fs_access_syscalls, nfs*sizeof(int)); | ||||
| 				tmp+=(nfs+1); | ||||
| 				*tmp = -1; | ||||
| 			size_t fs_access_syscalls_count = sizeof(fs_access_syscalls)/sizeof(fs_access_syscalls[0]); | ||||
|  | ||||
| 				policy->blacklisted_syscalls = tmp_begin; | ||||
| 			int ret = qssb_append_denied_syscalls(policy, fs_access_syscalls, fs_access_syscalls_count); | ||||
| 			if(ret != 0) | ||||
| 			{ | ||||
| 				QSSB_LOG_ERROR("Failed to add system calls to blacklist\n"); | ||||
| 				return -1; | ||||
| 			} | ||||
| 		} | ||||
| 		return 0; | ||||
| @@ -1085,18 +1058,22 @@ int qssb_enable_policy(struct qssb_policy *policy) | ||||
| 	close(landlock_ruleset_fd); | ||||
| #endif | ||||
|  | ||||
| 	if(policy->whitelisted_syscalls != NULL) | ||||
| 	if(policy->allowed_syscalls.used > 0) | ||||
| 	{ | ||||
| 		if(seccomp_enable_whitelist(policy->whitelisted_syscalls) <0) | ||||
| 		int *syscalls = (int *)policy->allowed_syscalls.data; | ||||
| 		size_t n = policy->allowed_syscalls.used / sizeof(int); | ||||
| 		if(seccomp_enable_whitelist(syscalls, n) < 0) | ||||
| 		{ | ||||
| 			QSSB_LOG_ERROR("seccomp_enable_whitelist failed\n"); | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	if(policy->blacklisted_syscalls != NULL) | ||||
| 	if(policy->denied_syscalls.used > 0) | ||||
| 	{ | ||||
| 		if(seccomp_enable_blacklist(policy->blacklisted_syscalls) <0) | ||||
| 		int *syscalls = (int *)policy->denied_syscalls.data; | ||||
| 		size_t n = policy->denied_syscalls.used / sizeof(int); | ||||
| 		if(seccomp_enable_blacklist(syscalls, n) < 0) | ||||
| 		{ | ||||
| 			QSSB_LOG_ERROR("seccomp_enable_blacklist failed\n"); | ||||
| 			return -1; | ||||
|   | ||||
							
								
								
									
										18
									
								
								test.c
									
									
									
									
									
								
							
							
						
						
									
										18
									
								
								test.c
									
									
									
									
									
								
							| @@ -15,9 +15,11 @@ int test_default_main(int argc, char *argv[]) | ||||
| int test_both_syscalls(int argc, char *argv[]) | ||||
| { | ||||
| 	struct qssb_policy *policy = qssb_init_policy(); | ||||
| 	int bla[] = { 1,2,3}; | ||||
| 	policy->blacklisted_syscalls = &bla; | ||||
| 	policy->whitelisted_syscalls = &bla; | ||||
| 	int syscalls[] = {1,2,3}; | ||||
|  | ||||
| 	qssb_append_denied_syscalls(policy, syscalls, 3); | ||||
| 	qssb_append_allowed_syscalls(policy, syscalls, 3); | ||||
|  | ||||
| 	int ret = qssb_enable_policy(policy); | ||||
| 	if(ret != 0) | ||||
| 	{ | ||||
| @@ -29,8 +31,9 @@ int test_both_syscalls(int argc, char *argv[]) | ||||
| int test_seccomp_blacklisted(int argc, char *argv[]) | ||||
| { | ||||
| 	struct qssb_policy *policy = qssb_init_policy(); | ||||
| 	int blacklisted[] = { QSSB_SYS(getuid) }; | ||||
| 	policy->blacklisted_syscalls = blacklisted; | ||||
|  | ||||
| 	qssb_append_denied_syscall(policy, QSSB_SYS(getuid)); | ||||
|  | ||||
| 	int ret = qssb_enable_policy(policy); | ||||
| 	uid_t pid = geteuid(); | ||||
| 	pid = getuid(); | ||||
| @@ -40,8 +43,9 @@ int test_seccomp_blacklisted(int argc, char *argv[]) | ||||
| int test_seccomp_blacklisted_call_permitted(int argc, char *argv[]) | ||||
| { | ||||
| 	struct qssb_policy *policy = qssb_init_policy(); | ||||
| 	int blacklisted[] = { QSSB_SYS(getuid) }; | ||||
| 	policy->blacklisted_syscalls = blacklisted; | ||||
|  | ||||
| 	qssb_append_denied_syscall(policy, QSSB_SYS(getuid)); | ||||
|  | ||||
| 	int ret = qssb_enable_policy(policy); | ||||
| 	//geteuid is not blacklisted, so must succeed | ||||
| 	uid_t pid = geteuid(); | ||||
|   | ||||
		Αναφορά σε νέο ζήτημα
	
	Block a user