Blame src/arch-ppc64.c

Packit 56e23f
/**
Packit 56e23f
 * Enhanced Seccomp PPC64 Specific Code
Packit 56e23f
 *
Packit 56e23f
 * Copyright (c) 2014 Red Hat <pmoore@redhat.com>
Packit 56e23f
 * Author: Paul Moore <paul@paul-moore.com>
Packit 56e23f
 *
Packit 56e23f
 */
Packit 56e23f
Packit 56e23f
/*
Packit 56e23f
 * This library is free software; you can redistribute it and/or modify it
Packit 56e23f
 * under the terms of version 2.1 of the GNU Lesser General Public License as
Packit 56e23f
 * published by the Free Software Foundation.
Packit 56e23f
 *
Packit 56e23f
 * This library is distributed in the hope that it will be useful, but WITHOUT
Packit 56e23f
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
Packit 56e23f
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
Packit 56e23f
 * for more details.
Packit 56e23f
 *
Packit 56e23f
 * You should have received a copy of the GNU Lesser General Public License
Packit 56e23f
 * along with this library; if not, see <http://www.gnu.org/licenses>.
Packit 56e23f
 */
Packit 56e23f
Packit Service 10c312
#include <stdlib.h>
Packit Service 10c312
#include <errno.h>
Packit Service 10c312
#include <string.h>
Packit 56e23f
#include <linux/audit.h>
Packit 56e23f
Packit Service 10c312
#include "db.h"
Packit 56e23f
#include "arch.h"
Packit 56e23f
#include "arch-ppc64.h"
Packit 56e23f
Packit Service 10c312
/* ppc64 syscall numbers */
Packit Service 10c312
#define __ppc64_NR_socketcall		102
Packit Service 10c312
#define __ppc64_NR_ipc			117
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * Resolve a syscall name to a number
Packit Service 10c312
 * @param name the syscall name
Packit Service 10c312
 *
Packit Service 10c312
 * Resolve the given syscall name to the syscall number using the syscall table.
Packit Service 10c312
 * Returns the syscall number on success, including negative pseudo syscall
Packit Service 10c312
 * numbers; returns __NR_SCMP_ERROR on failure.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
int ppc64_syscall_resolve_name_munge(const char *name)
Packit Service 10c312
{
Packit Service 10c312
	if (strcmp(name, "accept") == 0)
Packit Service 10c312
		return __PNR_accept;
Packit Service 10c312
	if (strcmp(name, "accept4") == 0)
Packit Service 10c312
		return __PNR_accept4;
Packit Service 10c312
	else if (strcmp(name, "bind") == 0)
Packit Service 10c312
		return __PNR_bind;
Packit Service 10c312
	else if (strcmp(name, "connect") == 0)
Packit Service 10c312
		return __PNR_connect;
Packit Service 10c312
	else if (strcmp(name, "getpeername") == 0)
Packit Service 10c312
		return __PNR_getpeername;
Packit Service 10c312
	else if (strcmp(name, "getsockname") == 0)
Packit Service 10c312
		return __PNR_getsockname;
Packit Service 10c312
	else if (strcmp(name, "getsockopt") == 0)
Packit Service 10c312
		return __PNR_getsockopt;
Packit Service 10c312
	else if (strcmp(name, "listen") == 0)
Packit Service 10c312
		return __PNR_listen;
Packit Service 10c312
	else if (strcmp(name, "msgctl") == 0)
Packit Service 10c312
		return __PNR_msgctl;
Packit Service 10c312
	else if (strcmp(name, "msgget") == 0)
Packit Service 10c312
		return __PNR_msgget;
Packit Service 10c312
	else if (strcmp(name, "msgrcv") == 0)
Packit Service 10c312
		return __PNR_msgrcv;
Packit Service 10c312
	else if (strcmp(name, "msgsnd") == 0)
Packit Service 10c312
		return __PNR_msgsnd;
Packit Service 10c312
	else if (strcmp(name, "recv") == 0)
Packit Service 10c312
		return __PNR_recv;
Packit Service 10c312
	else if (strcmp(name, "recvfrom") == 0)
Packit Service 10c312
		return __PNR_recvfrom;
Packit Service 10c312
	else if (strcmp(name, "recvmsg") == 0)
Packit Service 10c312
		return __PNR_recvmsg;
Packit Service 10c312
	else if (strcmp(name, "recvmmsg") == 0)
Packit Service 10c312
		return __PNR_recvmmsg;
Packit Service 10c312
	else if (strcmp(name, "semctl") == 0)
Packit Service 10c312
		return __PNR_semctl;
Packit Service 10c312
	else if (strcmp(name, "semget") == 0)
Packit Service 10c312
		return __PNR_semget;
Packit Service 10c312
	else if (strcmp(name, "semtimedop") == 0)
Packit Service 10c312
		return __PNR_semtimedop;
Packit Service 10c312
	else if (strcmp(name, "send") == 0)
Packit Service 10c312
		return __PNR_send;
Packit Service 10c312
	else if (strcmp(name, "sendmsg") == 0)
Packit Service 10c312
		return __PNR_sendmsg;
Packit Service 10c312
	else if (strcmp(name, "sendmmsg") == 0)
Packit Service 10c312
		return __PNR_sendmmsg;
Packit Service 10c312
	else if (strcmp(name, "sendto") == 0)
Packit Service 10c312
		return __PNR_sendto;
Packit Service 10c312
	else if (strcmp(name, "setsockopt") == 0)
Packit Service 10c312
		return __PNR_setsockopt;
Packit Service 10c312
	else if (strcmp(name, "shmat") == 0)
Packit Service 10c312
		return __PNR_shmat;
Packit Service 10c312
	else if (strcmp(name, "shmdt") == 0)
Packit Service 10c312
		return __PNR_shmdt;
Packit Service 10c312
	else if (strcmp(name, "shmget") == 0)
Packit Service 10c312
		return __PNR_shmget;
Packit Service 10c312
	else if (strcmp(name, "shmctl") == 0)
Packit Service 10c312
		return __PNR_shmctl;
Packit Service 10c312
	else if (strcmp(name, "shutdown") == 0)
Packit Service 10c312
		return __PNR_shutdown;
Packit Service 10c312
	else if (strcmp(name, "socket") == 0)
Packit Service 10c312
		return __PNR_socket;
Packit Service 10c312
	else if (strcmp(name, "socketpair") == 0)
Packit Service 10c312
		return __PNR_socketpair;
Packit Service 10c312
Packit Service 10c312
	return ppc64_syscall_resolve_name(name);
Packit Service 10c312
}
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * Resolve a syscall number to a name
Packit Service 10c312
 * @param num the syscall number
Packit Service 10c312
 *
Packit Service 10c312
 * Resolve the given syscall number to the syscall name using the syscall table.
Packit Service 10c312
 * Returns a pointer to the syscall name string on success, including pseudo
Packit Service 10c312
 * syscall names; returns NULL on failure.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
const char *ppc64_syscall_resolve_num_munge(int num)
Packit Service 10c312
{
Packit Service 10c312
	if (num == __PNR_accept)
Packit Service 10c312
		return "accept";
Packit Service 10c312
	else if (num == __PNR_accept4)
Packit Service 10c312
		return "accept4";
Packit Service 10c312
	else if (num == __PNR_bind)
Packit Service 10c312
		return "bind";
Packit Service 10c312
	else if (num == __PNR_connect)
Packit Service 10c312
		return "connect";
Packit Service 10c312
	else if (num == __PNR_getpeername)
Packit Service 10c312
		return "getpeername";
Packit Service 10c312
	else if (num == __PNR_getsockname)
Packit Service 10c312
		return "getsockname";
Packit Service 10c312
	else if (num == __PNR_getsockopt)
Packit Service 10c312
		return "getsockopt";
Packit Service 10c312
	else if (num == __PNR_listen)
Packit Service 10c312
		return "listen";
Packit Service 10c312
	else if (num == __PNR_msgctl)
Packit Service 10c312
		return "msgctl";
Packit Service 10c312
	else if (num == __PNR_msgget)
Packit Service 10c312
		return "msgget";
Packit Service 10c312
	else if (num == __PNR_msgrcv)
Packit Service 10c312
		return "msgrcv";
Packit Service 10c312
	else if (num == __PNR_msgsnd)
Packit Service 10c312
		return "msgsnd";
Packit Service 10c312
	else if (num == __PNR_recv)
Packit Service 10c312
		return "recv";
Packit Service 10c312
	else if (num == __PNR_recvfrom)
Packit Service 10c312
		return "recvfrom";
Packit Service 10c312
	else if (num == __PNR_recvmsg)
Packit Service 10c312
		return "recvmsg";
Packit Service 10c312
	else if (num == __PNR_recvmmsg)
Packit Service 10c312
		return "recvmmsg";
Packit Service 10c312
	else if (num == __PNR_semctl)
Packit Service 10c312
		return "semctl";
Packit Service 10c312
	else if (num == __PNR_semget)
Packit Service 10c312
		return "semget";
Packit Service 10c312
	else if (num == __PNR_semtimedop)
Packit Service 10c312
		return "semtimedop";
Packit Service 10c312
	else if (num == __PNR_send)
Packit Service 10c312
		return "send";
Packit Service 10c312
	else if (num == __PNR_sendmsg)
Packit Service 10c312
		return "sendmsg";
Packit Service 10c312
	else if (num == __PNR_sendmmsg)
Packit Service 10c312
		return "sendmmsg";
Packit Service 10c312
	else if (num == __PNR_sendto)
Packit Service 10c312
		return "sendto";
Packit Service 10c312
	else if (num == __PNR_setsockopt)
Packit Service 10c312
		return "setsockopt";
Packit Service 10c312
	else if (num == __PNR_shmat)
Packit Service 10c312
		return "shmat";
Packit Service 10c312
	else if (num == __PNR_shmdt)
Packit Service 10c312
		return "shmdt";
Packit Service 10c312
	else if (num == __PNR_shmget)
Packit Service 10c312
		return "shmget";
Packit Service 10c312
	else if (num == __PNR_shmctl)
Packit Service 10c312
		return "shmctl";
Packit Service 10c312
	else if (num == __PNR_shutdown)
Packit Service 10c312
		return "shutdown";
Packit Service 10c312
	else if (num == __PNR_socket)
Packit Service 10c312
		return "socket";
Packit Service 10c312
	else if (num == __PNR_socketpair)
Packit Service 10c312
		return "socketpair";
Packit Service 10c312
Packit Service 10c312
	return ppc64_syscall_resolve_num(num);
Packit Service 10c312
}
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * Convert a multiplexed pseudo socket syscall into a direct syscall
Packit Service 10c312
 * @param syscall the multiplexed pseudo syscall number
Packit Service 10c312
 *
Packit Service 10c312
 * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
Packit Service 10c312
 * no related syscall, or __NR_SCMP_ERROR otherwise.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
static int _ppc64_syscall_demux(int syscall)
Packit Service 10c312
{
Packit Service 10c312
	switch (syscall) {
Packit Service 10c312
	case -101:
Packit Service 10c312
		/* socket */
Packit Service 10c312
		return 326;
Packit Service 10c312
	case -102:
Packit Service 10c312
		/* bind */
Packit Service 10c312
		return 327;
Packit Service 10c312
	case -103:
Packit Service 10c312
		/* connect */
Packit Service 10c312
		return 328;
Packit Service 10c312
	case -104:
Packit Service 10c312
		/* listen */
Packit Service 10c312
		return 329;
Packit Service 10c312
	case -105:
Packit Service 10c312
		/* accept */
Packit Service 10c312
		return 330;
Packit Service 10c312
	case -106:
Packit Service 10c312
		/* getsockname */
Packit Service 10c312
		return 331;
Packit Service 10c312
	case -107:
Packit Service 10c312
		/* getpeername */
Packit Service 10c312
		return 332;
Packit Service 10c312
	case -108:
Packit Service 10c312
		/* socketpair */
Packit Service 10c312
		return 333;
Packit Service 10c312
	case -109:
Packit Service 10c312
		/* send */
Packit Service 10c312
		return 334;
Packit Service 10c312
	case -110:
Packit Service 10c312
		/* recv */
Packit Service 10c312
		return 336;
Packit Service 10c312
	case -111:
Packit Service 10c312
		/* sendto */
Packit Service 10c312
		return 335;
Packit Service 10c312
	case -112:
Packit Service 10c312
		/* recvfrom */
Packit Service 10c312
		return 337;
Packit Service 10c312
	case -113:
Packit Service 10c312
		/* shutdown */
Packit Service 10c312
		return 338;
Packit Service 10c312
	case -114:
Packit Service 10c312
		/* setsockopt */
Packit Service 10c312
		return 339;
Packit Service 10c312
	case -115:
Packit Service 10c312
		/* getsockopt */
Packit Service 10c312
		return 340;
Packit Service 10c312
	case -116:
Packit Service 10c312
		/* sendmsg */
Packit Service 10c312
		return 341;
Packit Service 10c312
	case -117:
Packit Service 10c312
		/* recvmsg */
Packit Service 10c312
		return 342;
Packit Service 10c312
	case -118:
Packit Service 10c312
		/* accept4 */
Packit Service 10c312
		return 344;
Packit Service 10c312
	case -119:
Packit Service 10c312
		/* recvmmsg */
Packit Service 10c312
		return 343;
Packit Service 10c312
	case -120:
Packit Service 10c312
		/* sendmmsg */
Packit Service 10c312
		return 349;
Packit Service 10c312
	case -201:
Packit Service 10c312
		/* semop - not defined */
Packit Service 10c312
		return __NR_SCMP_UNDEF;
Packit Service 10c312
	case -202:
Packit Service 10c312
		/* semget */
Packit Service 10c312
		return 393;
Packit Service 10c312
	case -203:
Packit Service 10c312
		/* semctl */
Packit Service 10c312
		return 394;
Packit Service 10c312
	case -204:
Packit Service 10c312
		/* semtimedop */
Packit Service 10c312
		return 392;
Packit Service 10c312
	case -211:
Packit Service 10c312
		/* msgsnd */
Packit Service 10c312
		return 400;
Packit Service 10c312
	case -212:
Packit Service 10c312
		/* msgrcv */
Packit Service 10c312
		return 401;
Packit Service 10c312
	case -213:
Packit Service 10c312
		/* msgget */
Packit Service 10c312
		return 399;
Packit Service 10c312
	case -214:
Packit Service 10c312
		/* msgctl */
Packit Service 10c312
		return 402;
Packit Service 10c312
	case -221:
Packit Service 10c312
		/* shmat */
Packit Service 10c312
		return 397;
Packit Service 10c312
	case -222:
Packit Service 10c312
		/* shmdt */
Packit Service 10c312
		return 398;
Packit Service 10c312
	case -223:
Packit Service 10c312
		/* shmget */
Packit Service 10c312
		return 395;
Packit Service 10c312
	case -224:
Packit Service 10c312
		/* shmctl */
Packit Service 10c312
		return 396;
Packit Service 10c312
	}
Packit Service 10c312
Packit Service 10c312
	return __NR_SCMP_ERROR;
Packit Service 10c312
}
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * Convert a direct socket syscall into multiplexed pseudo socket syscall
Packit Service 10c312
 * @param syscall the direct syscall
Packit Service 10c312
 *
Packit Service 10c312
 * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
Packit Service 10c312
 * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
static int _ppc64_syscall_mux(int syscall)
Packit Service 10c312
{
Packit Service 10c312
	switch (syscall) {
Packit Service 10c312
	case 326:
Packit Service 10c312
		/* socket */
Packit Service 10c312
		return -101;
Packit Service 10c312
	case 327:
Packit Service 10c312
		/* bind */
Packit Service 10c312
		return -102;
Packit Service 10c312
	case 328:
Packit Service 10c312
		/* connect */
Packit Service 10c312
		return -103;
Packit Service 10c312
	case 329:
Packit Service 10c312
		/* listen */
Packit Service 10c312
		return -104;
Packit Service 10c312
	case 330:
Packit Service 10c312
		/* accept */
Packit Service 10c312
		return -105;
Packit Service 10c312
	case 331:
Packit Service 10c312
		/* getsockname */
Packit Service 10c312
		return -106;
Packit Service 10c312
	case 332:
Packit Service 10c312
		/* getpeername */
Packit Service 10c312
		return -107;
Packit Service 10c312
	case 333:
Packit Service 10c312
		/* socketpair */
Packit Service 10c312
		return -108;
Packit Service 10c312
	case 334:
Packit Service 10c312
		/* send */
Packit Service 10c312
		return -109;
Packit Service 10c312
	case 335:
Packit Service 10c312
		/* sendto */
Packit Service 10c312
		return -111;
Packit Service 10c312
	case 336:
Packit Service 10c312
		/* recv */
Packit Service 10c312
		return -110;
Packit Service 10c312
	case 337:
Packit Service 10c312
		/* recvfrom */
Packit Service 10c312
		return -112;
Packit Service 10c312
	case 338:
Packit Service 10c312
		/* shutdown */
Packit Service 10c312
		return -113;
Packit Service 10c312
	case 339:
Packit Service 10c312
		/* setsockopt */
Packit Service 10c312
		return -114;
Packit Service 10c312
	case 340:
Packit Service 10c312
		/* getsockopt */
Packit Service 10c312
		return -115;
Packit Service 10c312
	case 341:
Packit Service 10c312
		/* sendmsg */
Packit Service 10c312
		return -116;
Packit Service 10c312
	case 342:
Packit Service 10c312
		/* recvmsg */
Packit Service 10c312
		return -117;
Packit Service 10c312
	case 343:
Packit Service 10c312
		/* recvmmsg */
Packit Service 10c312
		return -119;
Packit Service 10c312
	case 344:
Packit Service 10c312
		/* accept4 */
Packit Service 10c312
		return -118;
Packit Service 10c312
	case 349:
Packit Service 10c312
		/* sendmmsg */
Packit Service 10c312
		return -120;
Packit Service 10c312
	case 392:
Packit Service 10c312
		/* semtimedop */
Packit Service 10c312
		return -204;
Packit Service 10c312
	case 393:
Packit Service 10c312
		/* semget */
Packit Service 10c312
		return -202;
Packit Service 10c312
	case 394:
Packit Service 10c312
		/* semctl */
Packit Service 10c312
		return -203;
Packit Service 10c312
	case 395:
Packit Service 10c312
		/* shmget */
Packit Service 10c312
		return -223;
Packit Service 10c312
	case 396:
Packit Service 10c312
		/* shmctl */
Packit Service 10c312
		return -224;
Packit Service 10c312
	case 397:
Packit Service 10c312
		/* shmat */
Packit Service 10c312
		return -221;
Packit Service 10c312
	case 398:
Packit Service 10c312
		/* shmdt */
Packit Service 10c312
		return -222;
Packit Service 10c312
	case 399:
Packit Service 10c312
		/* msgget */
Packit Service 10c312
		return -213;
Packit Service 10c312
	case 400:
Packit Service 10c312
		/* msgsnd */
Packit Service 10c312
		return -211;
Packit Service 10c312
	case 401:
Packit Service 10c312
		/* msgrcv */
Packit Service 10c312
		return -212;
Packit Service 10c312
	case 402:
Packit Service 10c312
		/* msgctl */
Packit Service 10c312
		return -214;
Packit Service 10c312
	}
Packit Service 10c312
Packit Service 10c312
	return __NR_SCMP_ERROR;
Packit Service 10c312
}
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * Rewrite a syscall value to match the architecture
Packit Service 10c312
 * @param syscall the syscall number
Packit Service 10c312
 *
Packit Service 10c312
 * Syscalls can vary across different architectures so this function rewrites
Packit Service 10c312
 * the syscall into the correct value for the specified architecture.  Returns
Packit Service 10c312
 * zero on success, negative values on failure.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
int ppc64_syscall_rewrite(int *syscall)
Packit Service 10c312
{
Packit Service 10c312
	int sys = *syscall;
Packit Service 10c312
Packit Service 10c312
	if (sys <= -100 && sys >= -120)
Packit Service 10c312
		*syscall = __ppc64_NR_socketcall;
Packit Service 10c312
	else if (sys <= -200 && sys >= -224)
Packit Service 10c312
		*syscall = __ppc64_NR_ipc;
Packit Service 10c312
	else if (sys < 0)
Packit Service 10c312
		return -EDOM;
Packit Service 10c312
Packit Service 10c312
	return 0;
Packit Service 10c312
}
Packit Service 10c312
Packit Service 10c312
/**
Packit Service 10c312
 * add a new rule to the ppc64 seccomp filter
Packit Service 10c312
 * @param db the seccomp filter db
Packit Service 10c312
 * @param rule the filter rule
Packit Service 10c312
 *
Packit Service 10c312
 * This function adds a new syscall filter to the seccomp filter db, making any
Packit Service 10c312
 * necessary adjustments for the ppc64 ABI.  Returns zero on success, negative
Packit Service 10c312
 * values on failure.
Packit Service 10c312
 *
Packit Service 10c312
 * It is important to note that in the case of failure the db may be corrupted,
Packit Service 10c312
 * the caller must use the transaction mechanism if the db integrity is
Packit Service 10c312
 * important.
Packit Service 10c312
 *
Packit Service 10c312
 */
Packit Service 10c312
int ppc64_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
Packit Service 10c312
{
Packit Service 10c312
	int rc = 0;
Packit Service 10c312
	unsigned int iter;
Packit Service 10c312
	int sys = rule->syscall;
Packit Service 10c312
	int sys_a, sys_b;
Packit Service 10c312
	struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
Packit Service 10c312
Packit Service 10c312
	if ((sys <= -100 && sys >= -120) || (sys >= 326 && sys <= 344) ||
Packit Service 10c312
	    (sys == 349)) {
Packit Service 10c312
		/* (-100 to -120) : multiplexed socket syscalls
Packit Service 10c312
		   (326 to 344)   : direct socket syscalls, Linux 4.3+
Packit Service 10c312
		   (349)          : sendmmsg */
Packit Service 10c312
Packit Service 10c312
		/* strict check for the multiplexed socket syscalls */
Packit Service 10c312
		for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
Packit Service 10c312
			if ((rule->args[iter].valid != 0) && (rule->strict)) {
Packit Service 10c312
				rc = -EINVAL;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* determine both the muxed and direct syscall numbers */
Packit Service 10c312
		if (sys > 0) {
Packit Service 10c312
			sys_a = _ppc64_syscall_mux(sys);
Packit Service 10c312
			if (sys_a == __NR_SCMP_ERROR) {
Packit Service 10c312
				rc = __NR_SCMP_ERROR;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
			sys_b = sys;
Packit Service 10c312
		} else {
Packit Service 10c312
			sys_a = sys;
Packit Service 10c312
			sys_b = _ppc64_syscall_demux(sys);
Packit Service 10c312
			if (sys_b == __NR_SCMP_ERROR) {
Packit Service 10c312
				rc = __NR_SCMP_ERROR;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* use rule_a for the multiplexed syscall and use rule_b for
Packit Service 10c312
		 * the direct wired syscall */
Packit Service 10c312
Packit Service 10c312
		if (sys_a == __NR_SCMP_UNDEF) {
Packit Service 10c312
			rule_a = NULL;
Packit Service 10c312
			rule_b = rule;
Packit Service 10c312
		} else if (sys_b == __NR_SCMP_UNDEF) {
Packit Service 10c312
			rule_a = rule;
Packit Service 10c312
			rule_b = NULL;
Packit Service 10c312
		} else {
Packit Service 10c312
			/* need two rules, dup the first and link together */
Packit Service 10c312
			rule_a = rule;
Packit Service 10c312
			rule_dup = db_rule_dup(rule_a);
Packit Service 10c312
			rule_b = rule_dup;
Packit Service 10c312
			if (rule_b == NULL) {
Packit Service 10c312
				rc = -ENOMEM;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
			rule_b->prev = rule_a;
Packit Service 10c312
			rule_b->next = NULL;
Packit Service 10c312
			rule_a->next = rule_b;
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* multiplexed socket syscalls */
Packit Service 10c312
		if (rule_a != NULL) {
Packit Service 10c312
			rule_a->syscall = __ppc64_NR_socketcall;
Packit Service 10c312
			rule_a->args[0].arg = 0;
Packit Service 10c312
			rule_a->args[0].op = SCMP_CMP_EQ;
Packit Service 10c312
			rule_a->args[0].mask = DATUM_MAX;
Packit Service 10c312
			rule_a->args[0].datum = (-sys_a) % 100;
Packit Service 10c312
			rule_a->args[0].valid = 1;
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* direct wired socket syscalls */
Packit Service 10c312
		if (rule_b != NULL)
Packit Service 10c312
			rule_b->syscall = sys_b;
Packit Service 10c312
Packit Service 10c312
		/* we should be protected by a transaction checkpoint */
Packit Service 10c312
		if (rule_a != NULL) {
Packit Service 10c312
			rc = db_rule_add(db, rule_a);
Packit Service 10c312
			if (rc < 0)
Packit Service 10c312
				goto add_return;
Packit Service 10c312
		}
Packit Service 10c312
		if (rule_b != NULL) {
Packit Service 10c312
			rc = db_rule_add(db, rule_b);
Packit Service 10c312
			if (rc < 0)
Packit Service 10c312
				goto add_return;
Packit Service 10c312
		}
Packit Service 10c312
	} else if ((sys <= -200 && sys >= -224) || (sys >= 392 && sys <= 402)) {
Packit Service 10c312
		/* (-200 to -224) : multiplexed ipc syscalls
Packit Service 10c312
		   (392 to 402) : direct ipc syscalls */
Packit Service 10c312
Packit Service 10c312
		/* strict check for the multiplexed socket syscalls */
Packit Service 10c312
		for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
Packit Service 10c312
			if ((rule->args[iter].valid != 0) && (rule->strict)) {
Packit Service 10c312
				rc = -EINVAL;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* determine both the muxed and direct syscall numbers */
Packit Service 10c312
		if (sys > 0) {
Packit Service 10c312
			sys_a = _ppc64_syscall_mux(sys);
Packit Service 10c312
			if (sys_a == __NR_SCMP_ERROR) {
Packit Service 10c312
				rc = __NR_SCMP_ERROR;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
			sys_b = sys;
Packit Service 10c312
		} else {
Packit Service 10c312
			sys_a = sys;
Packit Service 10c312
			sys_b = _ppc64_syscall_demux(sys);
Packit Service 10c312
			if (sys_b == __NR_SCMP_ERROR) {
Packit Service 10c312
				rc = __NR_SCMP_ERROR;
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			}
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* use rule_a for the multiplexed syscall and use rule_b for
Packit Service 10c312
		 * the direct wired syscall */
Packit Service 10c312
Packit Service 10c312
		if (sys_a == __NR_SCMP_UNDEF) {
Packit Service 10c312
			rule_a = NULL;
Packit Service 10c312
			rule_b = rule;
Packit Service 10c312
		} else if (sys_b == __NR_SCMP_UNDEF) {
Packit Service 10c312
			rule_a = rule;
Packit Service 10c312
			rule_b = NULL;
Packit Service 10c312
		} else {
Packit Service 10c312
			/* need two rules, dup the first and link together */
Packit Service 10c312
			rule_a = rule;
Packit Service 10c312
			rule_dup = db_rule_dup(rule_a);
Packit Service 10c312
			rule_b = rule_dup;
Packit Service 10c312
			if (rule_b == NULL)
Packit Service 10c312
				goto add_return;
Packit Service 10c312
			rule_b->prev = rule_a;
Packit Service 10c312
			rule_b->next = NULL;
Packit Service 10c312
			rule_a->next = rule_b;
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* multiplexed socket syscalls */
Packit Service 10c312
		if (rule_a != NULL) {
Packit Service 10c312
			rule_a->syscall = __ppc64_NR_ipc;
Packit Service 10c312
			rule_a->args[0].arg = 0;
Packit Service 10c312
			rule_a->args[0].op = SCMP_CMP_EQ;
Packit Service 10c312
			rule_a->args[0].mask = DATUM_MAX;
Packit Service 10c312
			rule_a->args[0].datum = (-sys_a) % 200;
Packit Service 10c312
			rule_a->args[0].valid = 1;
Packit Service 10c312
		}
Packit Service 10c312
Packit Service 10c312
		/* direct wired socket syscalls */
Packit Service 10c312
		if (rule_b != NULL)
Packit Service 10c312
			rule_b->syscall = sys_b;
Packit Service 10c312
Packit Service 10c312
		/* we should be protected by a transaction checkpoint */
Packit Service 10c312
		if (rule_a != NULL) {
Packit Service 10c312
			rc = db_rule_add(db, rule_a);
Packit Service 10c312
			if (rc < 0)
Packit Service 10c312
				goto add_return;
Packit Service 10c312
		}
Packit Service 10c312
		if (rule_b != NULL) {
Packit Service 10c312
			rc = db_rule_add(db, rule_b);
Packit Service 10c312
			if (rc < 0)
Packit Service 10c312
				goto add_return;
Packit Service 10c312
		}
Packit Service 10c312
	} else if (sys >= 0) {
Packit Service 10c312
		/* normal syscall processing */
Packit Service 10c312
		rc = db_rule_add(db, rule);
Packit Service 10c312
		if (rc < 0)
Packit Service 10c312
			goto add_return;
Packit Service 10c312
	} else if (rule->strict) {
Packit Service 10c312
		rc = -EDOM;
Packit Service 10c312
		goto add_return;
Packit Service 10c312
	}
Packit Service 10c312
Packit Service 10c312
add_return:
Packit Service 10c312
	if (rule_dup != NULL)
Packit Service 10c312
		free(rule_dup);
Packit Service 10c312
	return rc;
Packit Service 10c312
}
Packit Service 10c312
Packit 56e23f
const struct arch_def arch_def_ppc64 = {
Packit 56e23f
	.token = SCMP_ARCH_PPC64,
Packit 56e23f
	.token_bpf = AUDIT_ARCH_PPC64,
Packit 56e23f
	.size = ARCH_SIZE_64,
Packit 56e23f
	.endian = ARCH_ENDIAN_BIG,
Packit Service 10c312
	.syscall_resolve_name = ppc64_syscall_resolve_name_munge,
Packit Service 10c312
	.syscall_resolve_num = ppc64_syscall_resolve_num_munge,
Packit Service 10c312
	.syscall_rewrite = ppc64_syscall_rewrite,
Packit Service 10c312
	.rule_add = ppc64_rule_add,
Packit 56e23f
};
Packit 56e23f
Packit 56e23f
const struct arch_def arch_def_ppc64le = {
Packit 56e23f
	.token = SCMP_ARCH_PPC64LE,
Packit 56e23f
	.token_bpf = AUDIT_ARCH_PPC64LE,
Packit 56e23f
	.size = ARCH_SIZE_64,
Packit 56e23f
	.endian = ARCH_ENDIAN_LITTLE,
Packit Service 10c312
	.syscall_resolve_name = ppc64_syscall_resolve_name_munge,
Packit Service 10c312
	.syscall_resolve_num = ppc64_syscall_resolve_num_munge,
Packit Service 10c312
	.syscall_rewrite = ppc64_syscall_rewrite,
Packit Service 10c312
	.rule_add = ppc64_rule_add,
Packit 56e23f
};