Beispiel #1
0
static void
peek_buffer (pid_t pid, const void * ptr, char * buffer, int numwords) {
    int i;
    for (i = 0; i < numwords*sizeof(long); i += sizeof(long)) {
        *(unsigned long *)(buffer+i) = peek_long(pid, ptr+i);
    }
}
Beispiel #2
0
static int 
bw2match(device_t parent, cfdata_t cf, void *args)
{
	struct confargs *ca = args;
	int mid, p4id, peekval;
	void *p4reg;

	/* No default address support. */
	if (ca->ca_paddr == -1)
		return 0;

	/*
	 * Slight hack here:  The low four bits of the
	 * config flags, if set, restrict the match to
	 * that machine "implementation" only.
	 */
	mid = cf->cf_flags & IDM_IMPL_MASK;
	if (mid != 0 && (mid != (cpu_machine_id & IDM_IMPL_MASK)))
		return 0;

	/*
	 * Make sure something is there, and if so,
	 * see if it looks like a P4 register.
	 */
	p4reg = bus_tmapin(ca->ca_bustype, ca->ca_paddr);
	peekval = peek_long(p4reg);
	p4id = (peekval == -1) ? P4_NOTFOUND : fb_pfour_id(p4reg);
	bus_tmapout(p4reg);
	if (peekval == -1)
		return 0;

	/*
	 * The config flag 0x40 if set means we should match
	 * only on a CG? overlay plane.  We can use only the
	 * CG4 and CG8, which both have a P4 register.
	 */
	if (cf->cf_flags & 0x40) {
		switch (p4id) {
		case P4_ID_COLOR8P1:
		case P4_ID_COLOR24:
			return 1;
		case P4_NOTFOUND:
		default:
			return 0;
		}
	}

	/*
	 * OK, we are expecting a plain old BW2, and
	 * there may or may not be a P4 register.
	 */
	switch (p4id) {
	case P4_ID_BW:
	case P4_NOTFOUND:
		return 1;
	default:
#ifdef	DEBUG
		aprint_debug("bwtwo at 0x%lx match p4id=0x%x fails\n",
		    ca->ca_paddr, p4id & 0xFF);
#endif
		break;
	}

	return 0;
}
Beispiel #3
0
static int
handle_syscall(struct trace_context *ctx, pid_t pid, int syscall)
{
	int i;
	int ret;
	unsigned long arg;
	char *path;
	unsigned int flags;
	unsigned int oflags;
	const char *name;

	char at_path[PATH_MAX];
	int at_nofollow;
	int fd;
	char *fdpath;

	for (i = 0; system_calls[i].name; i++) {
		if (system_calls[i].no == syscall)
			goto found;
	}
	return 0;
found:
	flags = system_calls[i].flags;
	name = system_calls[i].name;

	if (flags & CHECK_PATH) {
		arg = ptrace(PTRACE_PEEKUSER, pid, REG_ARG1, 0);
		path = get_str(pid, arg);
		if (flags & OPEN_MODE) {
			oflags = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
			if (!(oflags & O_WRONLY || oflags & O_RDWR)) return 0;
		}
		ret = path_arg_writable(ctx, pid, path, name, flags & DONT_FOLLOW);
		if (ret) return ret;
	}

	if (flags & CHECK_PATH2) {
		arg = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
		path = get_str(pid, arg);
		ret = path_arg_writable(ctx, pid, path, name, flags & DONT_FOLLOW);
		if (ret) return ret;
	}

	if (flags & AT_FAMILY_12) {
		arg = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
		path = get_str(pid, arg);

		if(flags & AT_FLW_ARG5) //for linkat() call
			at_nofollow = (ptrace(PTRACE_PEEKUSER, pid, REG_ARG5, 0) & AT_SYMLINK_FOLLOW) ? 0 : 1;
		else if (flags & AT_FLW_ARG5) //for fchownat() and fchmodat() calls
			at_nofollow = (ptrace(PTRACE_PEEKUSER, pid, REG_ARG5, 0) & AT_SYMLINK_NOFOLLOW) ? 1 : 0;
		else if(flags & AT_NOFLW_ARG4) //for utimensat() call
			at_nofollow = (ptrace(PTRACE_PEEKUSER, pid, REG_ARG4, 0) & AT_SYMLINK_NOFOLLOW) ? 1 : 0;
		else
			at_nofollow = flags & DONT_FOLLOW;

		if (flags & OPEN_MODE) {
			oflags = ptrace(PTRACE_PEEKUSER, pid, REG_ARG3, 0);
			if (!(oflags & O_WRONLY || oflags & O_RDWR)) return 0;
		}

		if(path[0] != '/' && *path != 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG1, 0);
			fdpath = get_pid_fd_path(pid, fd);
			sprintf(at_path, "%s/%s", fdpath, path);
			ret = path_arg_writable(ctx, pid, at_path, name, at_nofollow);
		} else if (path[0] != '/' && *path == 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG1, 0);
			fdpath = get_pid_fd_path(pid, fd);
			ret = path_arg_writable(ctx, pid, fdpath, name, at_nofollow);
		} else
			ret = path_arg_writable(ctx, pid, path, name, at_nofollow);

		if (ret) return ret;
	}

	if (flags & AT_FAMILY_23) {
		arg = ptrace(PTRACE_PEEKUSER, pid, REG_ARG3, 0);
		path = get_str(pid, arg);

		if(path[0] != '/' && *path != 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
			fdpath = get_pid_fd_path(pid, fd);
			sprintf(at_path, "%s/%s", fdpath, path);
			ret = path_arg_writable(ctx, pid, at_path, name, flags & DONT_FOLLOW);
		} else if (path[0] != '/' && *path == 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
			fdpath = get_pid_fd_path(pid, fd);
			ret = path_arg_writable(ctx, pid, fdpath, name, flags & DONT_FOLLOW);
		} else
			ret = path_arg_writable(ctx, pid, path, name, flags & DONT_FOLLOW);
		if (ret) return ret;
	} else if (flags & AT_FAMILY_34) {
		arg = ptrace(PTRACE_PEEKUSER, pid, REG_ARG4, 0);
		path = get_str(pid, arg);

		if(path[0] != '/' && *path != 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG3, 0);
			fdpath = get_pid_fd_path(pid, fd);
			sprintf(at_path, "%s/%s", fdpath, path);
			ret = path_arg_writable(ctx, pid, at_path, name, flags & DONT_FOLLOW);
		} else if (path[0] != '/' && *path == 0) {
			fd = ptrace(PTRACE_PEEKUSER, pid, REG_ARG3, 0);
			fdpath = get_pid_fd_path(pid, fd);
			ret = path_arg_writable(ctx, pid, fdpath, name, flags & DONT_FOLLOW);
		} else
			ret = path_arg_writable(ctx, pid, path, name, flags & DONT_FOLLOW);

		if (ret) return ret;
	}

    if (flags & CONNECT_CALL && !ctx->network_allowed) {
        const struct sockaddr_in * connect_to = (const struct sockaddr_in *)
                                                    ptrace(PTRACE_PEEKUSER, pid, REG_ARG2, 0);
        unsigned short * family_pos = (void*)&(connect_to->sin_family);
        unsigned short family = ptrace(PTRACE_PEEKDATA, pid, family_pos, 0) & 0xFFFF;
        if (family == AF_INET) {
            unsigned long host = peek_long(pid, &connect_to->sin_addr);
            unsigned short port = htons(peek_short(pid, &connect_to->sin_port));
            char buffer[15 + 1 + 5 + 1]; // ip + : + 65535 + \0
            snprintf(buffer, sizeof(buffer), "%s:%hu", inet_ntoa(*(struct in_addr *)&host), port);
            catbox_retval_add_violation(ctx, name, "", buffer);
        } else if (family == AF_LOCAL) {
            const struct sockaddr_un * local_struct = (const struct sockaddr_un *) connect_to;
            const char socket_name[UNIX_PATH_MAX];
            peek_buffer(pid, &local_struct->sun_path, socket_name, UNIX_PATH_MAX / sizeof(long));
            catbox_retval_add_violation(ctx, name, "", socket_name);
        } else if (family == AF_INET6) {
            const struct sockaddr_in6 * v6_struct = (const struct sockaddr_in6 *) connect_to;
            unsigned short port = htons(peek_short(pid, &v6_struct->sin6_port));
            unsigned char v6_addr[16];
            peek_buffer(pid, &v6_struct->sin6_addr, v6_addr, 16 / sizeof(long));

            char ip_buffer[INET6_ADDRSTRLEN + 1 + 5 + 1] = {0}; // v6_addr + : + 65535 + \0
            inet_ntop(AF_INET6, v6_addr, ip_buffer, sizeof(ip_buffer));
            snprintf(ip_buffer + strlen(ip_buffer), 1+5+1, ":%hu", port); // : + 65535 + \0
            catbox_retval_add_violation(ctx, name, "", ip_buffer);
        } else if (family == AF_UNSPEC) {
            // ignore this. it's a noop mostly
        } else {
            catbox_retval_add_violation(ctx, name, "", "unknown");
        }
        return -EACCES;
    }

	if (flags & NET_CALL && !ctx->network_allowed) {
        catbox_retval_add_violation(ctx, name, "", "");
		return -EACCES;
	}

return 0;
    //below we only trap changes to owner/mode within the fishbowl. 
    // The rest are taken care of in the above blocks
    if(0 & LOG_OWNER) {
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, pid, 0, &regs);
//        const char* path = get_str(pid, regs.ebx);
//        uid_t uid = (uid_t)regs.ecx;
//        gid_t gid = (gid_t)regs.edx;
//        PyObject* dict = PyObject_GetAttrString( ctx->ret_object, "ownerships" );
//        PyDict_SetItem( dict, PyString_FromString(path), PyTuple_Pack( 2, PyInt_FromLong(uid), PyInt_FromLong(gid)) );
        return 1;
    }
    if(0 & LOG_MODE) {
        struct user_regs_struct regs;
        ptrace(PTRACE_GETREGS, pid, 0, &regs);
//        const char* path = get_str(pid, regs.ebx);
//        mode_t mode = (mode_t)regs.ecx;
//        PyObject* dict = PyObject_GetAttrString( ctx->ret_object, "modes" );
//        PyDict_SetItem( dict, PyString_FromString(path), PyInt_FromLong(mode) );
        return 1;
    }
    if(0 & FAKE_ID) {
        return 2;
    }
	return 0;
}