Ejemplo n.º 1
0
void setBindConnectReturnValue(struct tcb* tcp) {
    int sockfd = tcp->u_arg[0];
    char *pidkey = db_read_pid_key(currdb, tcp->pid);
    char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
    ull_t sockid = db_getConnectCounterInc(currdb, pidkey);
    int u_rval = db_getSockResult(netdb, prov_pid, sockid); // get the result of a connect call
    //~ vbp(3, "here\n");

    // return recorded result
    struct user_regs_struct regs;
    long pid = tcp->pid;
    EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
    SET_RETURN_CODE(&regs, u_rval);
    vbp(3, "return %d\n", u_rval);
    if (u_rval < 0) {
        // set errno? TODO
    } else {
        db_setSockConnectId(currdb, pidkey, sockfd, sockid);	// map this sock number to given sock in tcp
        // TODO: keep the addrbuf.pad memory as well
    }
    EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);

    // init variables for this socket
    db_setupSockConnectCounter(currdb, pidkey, sockfd, sockid);

    free(prov_pid);
    free(pidkey);
}
Ejemplo n.º 2
0
void CDEnet_end_getsockname(struct tcb* tcp) {
    static int count = 1;
    vbp(0, "%ld\n", tcp->u_rval);
    if (CDE_provenance_mode) {
        print_getsockname_prov(tcp);
    }
    if (CDE_nw_mode) {
        long pid = tcp->pid;
        //~ char *pidkey = db_read_real_pid_key(currdb, pid);
        //~ ull_t listenid = db_getListenId(currdb, pidkey, tcp->u_arg[0]);
        //~ ull_t acceptid = db_getAcceptCounterInc(currdb, pidkey, listenid);
        //~ char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
        //~ int u_rval; // get the result of a accept call
        //~ char *addr = NULL;

        struct user_regs_struct regs;
        EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
        SET_RETURN_CODE(&regs, 0);
        EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);

        socklen_t addrlen = sizeof(struct sockaddr);
        struct sockaddr sa;
        struct sockaddr_in *sain = (struct sockaddr_in*) &(sa.sa_data);
        struct in_addr *inaddr = &(sain->sin_addr);

        inet_pton(AF_INET, "0.0.0.0", &(inaddr->s_addr));
        sain->sin_family = AF_INET;
        sain->sin_port = htons(2000+(count++)); // RANDOM
        sa.sa_family = AF_INET;

        memcpy_to_child(pid, (char*) tcp->u_arg[1], (char*) &sa, addrlen);
        memcpy_to_child(pid, (char*) tcp->u_arg[2], (char*) &addrlen, sizeof(addrlen)); // TODO: big/little endian
    }
}
Ejemplo n.º 3
0
void CDEnet_end_send(struct tcb* tcp) {
    int sockfd = tcp->u_arg[0];
    if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) {
        vb(2);
        if (socket_data_handle(tcp, SOCK_SEND) < 0) {
            // TODO
        }
    }
    if (CDE_nw_mode && db_isCapturedSock(currdb, sockfd)) {
        vb(2);
        if (CDE_verbose_mode >= 3) {
            char buff[KEYLEN];
            size_t buflength = tcp->u_arg[2];
            if (umoven(tcp, tcp->u_arg[1], buflength, buff) < 0) {
                return;
            }
            buff[tcp->u_arg[2]] = '\0';
            vbp(3, "action %d [%ld] checksum %u ",
                SOCK_SEND, tcp->u_arg[2], checksum(buff, buflength));
            if (CDE_verbose_mode >= 3) printbuf(buff, buflength);
        }
        long pid = tcp->pid;
        char *pidkey, *sockid;
        db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid);
        if (pidkey == NULL || sockid == NULL) {
            vbp(0, "error");
            return;
        }
        ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_SEND);
        char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
        ull_t u_rval;
        db_getSendRecvResult(netdb, SOCK_SEND, prov_pid, sockid, sendid, &u_rval, NULL); // get recorded result
        struct user_regs_struct regs;
        EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
        SET_RETURN_CODE(&regs, u_rval);
        if (u_rval < 0) {
            // set errno? TODO
        }
        EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);

        free(prov_pid);
        free(sockid);
        free(pidkey);
    }
}
Ejemplo n.º 4
0
void CDEnet_end_recv(struct tcb* tcp) {
    int sockfd = tcp->u_arg[0];
    if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) {
        vb(2);
        socket_data_handle(tcp, SOCK_RECV);
    }
    if (CDE_nw_mode && db_isCapturedSock(currdb, sockfd)) {
        vb(2);
        long pid = tcp->pid;
        char *pidkey, *sockid;
        db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid);
        if (pidkey == NULL || sockid == NULL) {
            vbp(0, "error");
            return;
        }
        ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_RECV);
        char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
        ull_t u_rval;
        char *buff = db_getSendRecvResult(netdb, SOCK_RECV, prov_pid, sockid, sendid, &u_rval, NULL); // get recorded result
        if (buff == NULL && u_rval>0) {
            vbp(2, "buff == NULL && u_rval (%lld) > 0", u_rval);
            u_rval = 0;
        }
        struct user_regs_struct regs;
        EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
        SET_RETURN_CODE(&regs, u_rval);
        EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);
        if (u_rval <= 0) {
            // set errno? TODO
        } else { // successed call, copy to buffer as well
            //~ printf("mem: %zd %d\n %s", u_rval, u_rval > 0, buff);
            memcpy_to_child(pid, (char*) tcp->u_arg[1], buff, u_rval);
        }

        if (buff != NULL) free(buff);
        free(prov_pid);
        free(sockid);
        free(pidkey);
    }
}
Ejemplo n.º 5
0
// int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
//     on connection or binding succeeds, zero is returned; on error, -1 is returned.
void CDEnet_begin_bindconnect(struct tcb* tcp, int isConnect) {
    vb(1);
    if (CDE_nw_mode) {
        char addrbuf[KEYLEN];
        if (umoven(tcp, tcp->u_arg[1], tcp->u_arg[2], addrbuf) < 0) return;
        if (isConnect) {
            int port = getPort((void*)addrbuf);
            vbp(3, "Port %d\n", port);
            if (port == 53 || port == 22) return;
        }

        db_setCapturedSock(currdb, tcp->u_arg[0]);
        denySyscall(tcp->pid);
    }
}
Ejemplo n.º 6
0
void get_ip_info(long pid, int sockfd, char *buf) {
    struct stat fdstat;
    char path[KEYLEN];
    sprintf(path, "/proc/%ld/fd/%d", pid, sockfd);
    if (stat(path, &fdstat) >= 0) {
        char cmd[KEYLEN], sip[9], sport[5], dip[9], dport[5];
        ino_t inode;
        sprintf(cmd, "cat /proc/net/tcp | grep %ld | head -n 1", fdstat.st_ino);
        FILE *fd = popen(cmd, "r");
        if (fd != NULL) {
            fscanf(fd, "%*d: %8s:%4s %8s:%4s %*2s %*8s:%*8s %*2s:%*8s %*8s %*d %*d %ld",
                   sip, sport, dip, dport, &inode);
            if (inode == fdstat.st_ino) {
                sprintf(buf, "%s.%s.%s.%s", sip, sport, dip, dport);
                vbp(3, "%ld %d %s:%s %s:%s %ld %ld\n", pid, sockfd, sip, sport, dip, dport, inode, fdstat.st_ino);
            }
            pclose(fd);
        }
    }
}
Ejemplo n.º 7
0
void CDEnet_end_bindconnect(struct tcb* tcp, int isConnect) {
    int sockfd = tcp->u_arg[0];
    long addr = tcp->u_arg[1];
    int addrlen = tcp->u_arg[2];
    union sockaddr_t addrbuf;

    vb(2);

    if (addr == 0) return;

    if (addrlen < 2 || addrlen > sizeof(addrbuf)) addrlen = sizeof(addrbuf);

    if (umoven(tcp, addr, addrlen, addrbuf.pad) < 0) return;
    addrbuf.pad[sizeof(addrbuf.pad) - 1] = '\0';

    //~ printf("sock %d, family %d inet %d\n", sockfd, addrbuf.sa.sa_family, AF_INET);
    //~ if (CDE_provenance_mode && addrbuf.sa.sa_family == AF_INET) {
    if (CDE_provenance_mode) {
        int port = getPort((void*)addrbuf.pad);
        char buf[KEYLEN];
        bzero(buf, sizeof(buf));
        vbp(3, "Port %d return %ld\n", port, tcp->u_rval);
        if (port == 53 || port == 22) return;
        if (isConnect) {
            if (addrbuf.sa.sa_family == AF_INET) {
                get_ip_info(tcp->pid, sockfd, buf);
            } else if (addrbuf.sa.sa_family == AF_LOCAL) {
                sprintf(buf, "..%s", addrbuf.sau.sun_path);
            }
        }
        print_connect_prov(tcp, sockfd, addrbuf.pad, tcp->u_arg[2], tcp->u_rval, buf);
    }
    if (CDE_nw_mode) { // return my own network socket connect result from netdb
        if (isConnect) if (!isCurrCapturedSock(sockfd)) return;
        setBindConnectReturnValue(tcp);
    }
}
Ejemplo n.º 8
0
Collision::Collision(PObject* obj1, PObject* obj2)
{
	trueCollision = false;
	
	objects = new PObject*[2];
	objects[0] = obj1;
	objects[1] = obj2;
	
	/*
	 * the following was written before the Vect2D class was written
	 * (and that's why it's so messy)
	 */
	Vect2D norm;
	Point p1,p2;
	
	const Point* obj1vertices = objects[0]->getVertices();
	const Point* obj2vertices = objects[1]->getVertices();
	int numPoints=0;
	float sumx=0;
	float sumy=0;
	float parametric;
	float parametric2;
	float denominator;
	
	float vec1x;
	float vec1y;
	float vec1deltax;//between this point and the next one in the shape (going counterclockwise)
	float vec1deltay;
	
	float vec2x;
	float vec2y;
	float vec2deltax;
	float vec2deltay;
	
	float deltax, deltay; //between the two points on different shapes
	
	/*
	 * x1+k*t = x2+c*k
	 * y1+b*t = y2+d*k
	 */
	
	for (int i = 0; i < objects[0]->getNumVertices(); i++)
	{
		vec1x = obj1vertices[i].x;//x1
		vec1y = obj1vertices[i].y;//y1
		
		vec1deltax = obj1vertices[(i + 1) % objects[0]->getNumVertices()].x - vec1x;//a
		vec1deltay = obj1vertices[(i + 1) % objects[0]->getNumVertices()].y - vec1y;//b
		
		for (int j = 0; j < objects[1]->getNumVertices(); j++)
		{
			vec2x = obj2vertices[j].x;//x2
			vec2y = obj2vertices[j].y;//y2
			
			vec2deltax = obj2vertices[(j + 1) % objects[1]->getNumVertices()].x - vec2x;//c
			vec2deltay = obj2vertices[(j + 1) % objects[1]->getNumVertices()].y - vec2y;//d
			
			denominator = (vec1deltax * vec2deltay) - (vec2deltax * vec1deltay);//ad-bc
			if (denominator != 0)
			{
				deltax = vec1x-vec2x;//x1-x2
				deltay = vec1y-vec2y;//y1-y2
				
				parametric = ((vec2deltax * (deltay)) - vec2deltay * (deltax)) / (denominator);//t
				parametric2 = ((vec1deltax * (deltay)) - vec1deltay * (deltax)) / (denominator);//k

				if (parametric <= 1 && parametric >= 0 && parametric2 <= 1 && parametric2 >= 0)
				{
					numPoints++;
					sumx += vec1x + (parametric * vec1deltax);//x = x1+a*t
					sumy += vec1y + (parametric * vec1deltay);//y = y1+b*t
					//uses the normal vector of the first collision
					if (!trueCollision){
						/* old way of finding
						//figure out which one collided on the corner
						if (abs(parametric2-.5) < abs(parametric-.5)){
							//vector1's point of collision was closer to the corner
							norm.set(vec2deltay,-vec2deltax);
						}
						else
						{
							norm.set(vec2deltax,-vec2deltay);
						}*/
						//VERY crude approximation for normal vector at collision point
						norm.set(objects[1]->get_centerx()-objects[0]->get_centerx(), objects[1]->get_centery()-objects[0]->get_centery());
						norm.normalize();
					}
					trueCollision = true;
				}
			}
		}
	}
	if (trueCollision)
	{
		intersection.x = sumx/numPoints;
		intersection.y = sumy/numPoints;
		//calculate impulse here
		float e = objects[0]->get_elasticity()*objects[1]->get_elasticity();
		Vect2D r1(intersection.x-objects[0]->get_centerx(), intersection.y-objects[0]->get_centery());
		Vect2D r2(intersection.x-objects[1]->get_centerx(), intersection.y-objects[1]->get_centery());
		//vap = vcenter + w x r1 where w is angular velocity vector that points into screen
		//vap = velocity of point of collision on each object
		Vect2D vap(objects[0]->get_vx()-objects[0]->get_dtheta()*r1.y, objects[0]->get_vy()+objects[0]->get_dtheta()*r1.x);
		Vect2D vbp(objects[1]->get_vx()-objects[1]->get_dtheta()*r2.y, objects[1]->get_vy()+objects[1]->get_dtheta()*r2.x);
		Vect2D& vabp = vap-vbp;
		float ran = r1.cross(norm);
		float rbn = r2.cross(norm);
		//source: http://www.myphysicslab.com/collision.html
		float j= (-(1+e)*vabp.dot(norm))/(1/objects[0]->get_mass() + 1/objects[1]->get_mass() + ran*ran/objects[0]->get_momentInertia() + rbn*rbn/objects[1]->get_momentInertia());
		
		impulse.set(norm);
		impulse.scale(j);
	}
}
Ejemplo n.º 9
0
void CDEnet_end_recvmsg(struct tcb* tcp) {
    int sockfd = tcp->u_arg[0];
    struct msghdr mh;
    struct iovec *msg_iov = NULL;
    char memop_ok = 1;
    if (CDE_provenance_mode && CDE_network_content_mode && isProvCapturedSock(sockfd)) {
        int len = tcp->u_rval;
        //~ char *msg_name = NULL, *msg_control = NULL;
        char *storage = NULL;

        vb(2);

        if (umoven(tcp, tcp->u_arg[1], sizeof(struct msghdr), (char*) &mh) < 0) return;
        if (len > 0) {
            storage = malloc(len);
            memop_ok &= storage != NULL;
        }
        //~ if (memop_ok && mh.msg_namelen > 0) {
        //~ msg_name = malloc(mh.msg_namelen);
        //~ memop_ok &= msg_name != NULL;
        //~ if (memop_ok)
        //~ memop_ok &= umoven(tcp, (long) mh.msg_name, mh.msg_namelen, msg_name) >= 0;
        //~ }
        if (memop_ok && mh.msg_iovlen > 0) {
            int memlen = mh.msg_iovlen * sizeof(struct iovec);
            msg_iov = malloc(memlen);
            memop_ok &= msg_iov != NULL;
            if (memop_ok)
                memop_ok &= umoven(tcp, (long) mh.msg_iov, memlen , (void*) msg_iov) >= 0;
        }
        //~ if (memop_ok && mh.msg_controllen > 0) {
        //~ msg_control = malloc(mh.msg_controllen);
        //~ memop_ok &= msg_control != NULL;
        //~ if (memop_ok)
        //~ memop_ok &= umoven(tcp, (long) mh.msg_control, mh.msg_controllen, msg_control) >= 0;
        //~ }
        if (memop_ok) {
            char *it = storage;
            long int read_len, i;
            for (i=0; i<mh.msg_iovlen && memop_ok; i++) {
                read_len = len + storage - it < msg_iov[i].iov_len ?
                           len + storage - it : msg_iov[i].iov_len;
                memop_ok &= umoven(tcp, (long) msg_iov[i].iov_base, read_len, it) >= 0;
                if (memop_ok)
                    it = it + read_len;
            }
            if (memop_ok) {
                print_sock_action(tcp, sockfd, storage, 0, tcp->u_arg[2], len, SOCK_RECVMSG, &mh);
                vbp(2, "recorded\n");
            }
        }
        freeifnn(storage);
        //~ freeifnn(msg_control);
        freeifnn(msg_iov);
        //~ freeifnn(msg_name);
    }
    if (CDE_nw_mode && isCurrCapturedSock(sockfd)) {
        vb(2);
        long pid = tcp->pid;
        char *pidkey, *sockid;
        db_get_pid_sock(currdb, pid, sockfd, &pidkey, &sockid);
        if (pidkey == NULL || sockid == NULL) {
            vbp(0, "error");
            return;
        }
        ull_t sendid = db_getPkgCounterInc(currdb, pidkey, sockid, SOCK_RECV);
        char* prov_pid = getMappedPid(pidkey);	// convert this pid to corresponding prov_pid
        ull_t u_rval;
        struct msghdr ret_mh;
        char *buff = db_getSendRecvResult(netdb, SOCK_RECVMSG, prov_pid, sockid, sendid, &u_rval, &ret_mh); // get recorded result
        struct user_regs_struct regs;

        if (buff == NULL) {
            vbp(0, "recvmsg not captured!\n");
            //~ while (1) sleep(1);
            EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
            SET_RETURN_CODE(&regs, -1);
            EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);

        } else {

            EXITIF(ptrace(PTRACE_GETREGS, pid, NULL, &regs)<0);
            SET_RETURN_CODE(&regs, u_rval);
            EXITIF(ptrace(PTRACE_SETREGS, pid, NULL, &regs)<0);
            if (u_rval <= 0) {
                // set errno? TODO
            } else { // successed call, copy to buffer as well

                // get the calling mh structure
                memop_ok &= umoven(tcp, tcp->u_arg[1], sizeof(struct msghdr), (char*) &mh) >= 0;
                if (memop_ok && mh.msg_iovlen > 0) {
                    int memlen = mh.msg_iovlen * sizeof(struct iovec);
                    msg_iov = malloc(memlen);
                    memop_ok &= msg_iov != NULL;
                    if (memop_ok)
                        memop_ok &= umoven(tcp, (long) mh.msg_iov, memlen , (void*) msg_iov) >= 0;
                }

                // and copy stuff back to that mh
                if (memop_ok) {
                    // data
                    char *it = buff;
                    long int read_len, i;
                    for (i=0; i<mh.msg_iovlen && memop_ok; i++) {
                        read_len = u_rval + buff - it < msg_iov[i].iov_len ?
                                   u_rval + buff - it : msg_iov[i].iov_len;
                        memcpy_to_child(pid, msg_iov[i].iov_base, it, read_len);
                        it = it + read_len;
                    }
                    // others
                    mh.msg_flags = ret_mh.msg_flags;
                    memcpy_to_child(pid, (char*) tcp->u_arg[1], (char*) &mh, sizeof(mh));
                }
                freeifnn(msg_iov);
            }
        }

        freeifnn(buff);
        free(prov_pid);
        free(sockid);
        free(pidkey);
    }
}
Ejemplo n.º 10
0
// get the corresponding pidkey from traced execution
// some graph algorithm is needed here
// @input current pidkey
// @return pidkey from netdb
// TODO
char* getMappedPid(char* pidkey) {
    // TODO: need a cache for this operation as well
    char key[KEYLEN], *p;
    const char *read;
    size_t read_len;
    ull_t childid;
    int n=0, i;
    ull_t idlist[100]; // enough?

    p = pidkey;
    while (p != NULL) {
        sprintf(key, "prv.pid.%s.childid", p);
        vbp(3, "%s\n", key);
        db_read_ull(currdb, key, &childid);
        idlist[n++] = childid;

        sprintf(key, "prv.pid.%s.parent", p);
        if (p != pidkey && p != NULL) free(p);
        p = db_readc(currdb, key);
    }
    vbp(2, "%s -> [%d] [", pidkey, n);
    if (CDE_verbose_mode >= 2) {
        for (i=0; i<n; i++) {
            fprintf(stderr, "%llu, ", idlist[i]);
        }
        fprintf(stderr, "]\n");
    }

    if (PIDKEY != NULL) {
        p = strdup(PIDKEY);
        n -= 2;
    } else {
        p = db_readc(netdb, "meta.root");
        sprintf(key, "prv.pid.%s.exec.", p);
        //~ sprintf(key, "prv.pid.%s.actualexec.", p);
        free(p);
        leveldb_iterator_t *it = leveldb_create_iterator(netdb->db, netdb->roptions);
        leveldb_iter_seek(it, key, strlen(key));

        read = leveldb_iter_value(it, &read_len);
        p = malloc(read_len + 1);
        memcpy(p, read, read_len);
        p[read_len] = '\0';
        n-=2; // skip the first root -> child that I just did
    }
    while (n>0) {
        sprintf(key, "prv.pid.%s.child.%llu", p, idlist[n-1]);
        n--;
        free(p);
        p = db_readc(netdb, key);
        vbp(3, "%s\n", key);
    }
    vbp(2, "return %s\n", p);
    return p;

    //~ char *value;
    //~ const char *read;
    //~ size_t read_len;
    //~
    //~ sprintf(key, "prv.pid.%s.parent.", netdb_root);
    //~ leveldb_iterator_t *it = leveldb_create_iterator(netdb->db, netdb->roptions);
    //~ leveldb_iter_seek(it, key, strlen(key));
    //~
    //~ read = leveldb_iter_value(it, &read_len);
    //~ value = malloc(read_len + 1);
    //~ memcpy(value, read, read_len);
    //~ value[read_len] = '\0';
    //~ return value;
}