Esempio n. 1
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;
}
Esempio n. 2
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;
	const char *name;

	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, 0, 0);
		path = get_str(pid, arg);
		if (flags & OPEN_MODE) {
			flags = ptrace(PTRACE_PEEKUSER, pid, 4, 0);
			if (!(flags & O_WRONLY || flags & 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, 4, 0);
		path = get_str(pid, arg);
		ret = path_arg_writable(ctx, pid, path, name, flags & DONT_FOLLOW);
		if (ret) return ret;
	}

	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;
}