int sds_priv_drop(SDS_STATE *ss) { struct passwd *pw = NULL; struct group *gr = NULL; if (geteuid() != 0) { warnx("uid != 0. Not dropping privs"); return (1); } SETVAR(ss->proc.user, SDS_USER); SETVAR(ss->proc.group, SDS_GROUP); SETVAR(ss->proc.chroot, SDS_CHROOT); if ( (pw = getpwnam(ss->proc.user)) == NULL) { warnx("user does not exist: %s", ss->proc.user); return (-1); } if ( (gr = getgrnam(ss->proc.group)) == NULL) { warnx("group does not exist: %s", ss->proc.group); return (-1); } if (chroot(ss->proc.chroot) < 0) { warn("%s", ss->proc.chroot); return (-1); } IS_ERR(chdir("/")); LTZERO(setgid(gr->gr_gid)); LTZERO(setuid(pw->pw_uid)); return (0); }
/* Handle/record information received in a transfer vector entry. */ static enum ld_plugin_status parse_tv_tag (struct ld_plugin_tv *tv) { #define SETVAR(x) x = tv->tv_u.x switch (tv->tv_tag) { case LDPT_OPTION: return parse_option (tv->tv_u.tv_string); case LDPT_NULL: case LDPT_GOLD_VERSION: case LDPT_GNU_LD_VERSION: case LDPT_API_VERSION: default: break; case LDPT_OUTPUT_NAME: output_name = tv->tv_u.tv_string; break; case LDPT_LINKER_OUTPUT: linker_output = tv->tv_u.tv_val; break; case LDPT_REGISTER_CLAIM_FILE_HOOK: SETVAR(tv_register_claim_file); break; case LDPT_REGISTER_ALL_SYMBOLS_READ_HOOK: SETVAR(tv_register_all_symbols_read); break; case LDPT_REGISTER_CLEANUP_HOOK: SETVAR(tv_register_cleanup); break; case LDPT_ADD_SYMBOLS: SETVAR(tv_add_symbols); break; case LDPT_GET_SYMBOLS: SETVAR(tv_get_symbols); break; case LDPT_GET_SYMBOLS_V2: tv_get_symbols_v2 = tv->tv_u.tv_get_symbols; break; case LDPT_ADD_INPUT_FILE: SETVAR(tv_add_input_file); break; case LDPT_MESSAGE: SETVAR(tv_message); break; case LDPT_GET_INPUT_FILE: SETVAR(tv_get_input_file); break; case LDPT_RELEASE_INPUT_FILE: SETVAR(tv_release_input_file); break; case LDPT_ADD_INPUT_LIBRARY: SETVAR(tv_add_input_library); break; case LDPT_SET_EXTRA_LIBRARY_PATH: SETVAR(tv_set_extra_library_path); break; } #undef SETVAR return LDPS_OK; }
gint wr_unify_term_aux(glb* g, gint x, gint y, int uniquestrflag) { gptr db; gint encx,ency; gint tmp; // used by VARVAL_F macro gptr xptr,yptr; int xlen,ylen,uselen,ilimit,i; #ifdef DEBUG printf("wr_unify_term_aux called with x %d ",x); wr_print_term(g,x); printf(" and y %d ",y); wr_print_term(g,y); printf("\n"); #endif // first check if immediately same: return 1 if yes if (x==y) return 1; // second, fetch var values for var args if (isvar(x)) x=VARVAL_F(x,(g->varbanks)); if (isvar(y)) y=VARVAL_F(y,(g->varbanks)); // check again if same if (x==y) return 1; // go through the ladder of possibilities // knowing that x and y are different if (!isdatarec(x)) { // x is a primitive if (!isdatarec(y)) { // both x and y are primitive if (isvar(x)) { SETVAR(x,y,g->varbanks,g->varstack,g->tmp_unify_vc); // set occcheck only if y is a var too if (g->tmp_unify_do_occcheck && isvar(y)) (g->tmp_unify_occcheck)=1; return 1; } else if (isvar(y)) { SETVAR(y,x,g->varbanks,g->varstack,g->tmp_unify_vc); // do not set occcheck here: x is a constant! return 1; } else { // x and y are constants if (wr_equal_ptr_primitives(g,x,y,uniquestrflag)) return 1; else return 0; } // x is primitive, but y is not } else if (isvar(x)) { // x is var, y is non-primitive if (g->tmp_unify_occcheck && wr_occurs_in(g,x,y,(gptr)(g->varbanks))) { return 0; } else { SETVAR(x,y,g->varbanks,g->varstack,g->tmp_unify_vc); if (g->tmp_unify_do_occcheck) (g->tmp_unify_occcheck)=1; return 1; } } else { // x is a constant, but y is non-primitive return 0; } // x is not primitive } else if (isvar(y)) { // x is non-primitive, y is var if (g->tmp_unify_occcheck && wr_occurs_in(g,y,x,(gptr)(g->varbanks))) { return 0; } else { SETVAR(y,x,g->varbanks,g->varstack,g->tmp_unify_vc); if (g->tmp_unify_do_occcheck) (g->tmp_unify_occcheck)=1; return 1; } // x is not primitive, y is non-var } else if (!isdatarec(y)) { // x is not primitive, y is constant return 0; } else { // x and y are both complex terms db=g->db; xptr=decode_record(db,x); yptr=decode_record(db,y); xlen=get_record_len(xptr); ylen=get_record_len(yptr); if (g->unify_samelen) { if (xlen!=ylen) return 0; uselen=xlen; } else { if (xlen<=ylen) uselen=xlen; else uselen=ylen; } if (g->unify_maxuseterms) { if (((g->unify_maxuseterms)+(g->unify_firstuseterm))<uselen) uselen=(g->unify_firstuseterm)+(g->unify_maxuseterms); } ilimit=RECORD_HEADER_GINTS+uselen; for(i=RECORD_HEADER_GINTS+(g->unify_firstuseterm); i<ilimit; i++) { encx=*(xptr+i); ency=*(yptr+i); if (encx!=ency && !wr_unify_term_aux(g,encx,ency,uniquestrflag)) return 0; } return 1; } }
gint wr_match_term_aux(glb* g, gint x, gint y, int uniquestrflag) { gptr db; gint xval,encx,ency; gptr xptr,yptr; int xlen,ylen,uselen,ilimit,i; gint eqencx; // used by WR_EQUAL_TERM macro #ifdef DEBUG printf("wr_match_term_aux called with x %d ",x); wr_print_term(g,x); printf(" and y %d ",y); wr_print_term(g,y); printf("\n"); #endif // check x var case immediately if (isvar(x)) { xval=VARVAL_DIRECT(x,(g->varbanks)); if (xval==UNASSIGNED) { // previously unassigned var: assign now and return SETVAR(x,y,g->varbanks,g->varstack,g->tmp_unify_vc); return 1; } else { // xval must now be equal to y, else match fails if (WR_EQUAL_TERM(g,xval,y,uniquestrflag)) return 1; return 0; } } // now x is not var if (!isdatarec(x)) { if (WR_EQUAL_TERM(g,x,y,uniquestrflag)) return 1; } if (!isdatarec(y)) return 0; // x is datarec but y is not // now x and y are different datarecs if (1) { db=g->db; xptr=decode_record(db,x); yptr=decode_record(db,y); xlen=get_record_len(xptr); ylen=get_record_len(yptr); if (g->unify_samelen) { if (xlen!=ylen) return 0; uselen=xlen; } else { if (xlen<=ylen) uselen=xlen; else uselen=ylen; } if (g->unify_maxuseterms) { if (((g->unify_maxuseterms)+(g->unify_firstuseterm))<uselen) uselen=(g->unify_firstuseterm)+(g->unify_maxuseterms); } ilimit=RECORD_HEADER_GINTS+uselen; for(i=RECORD_HEADER_GINTS+(g->unify_firstuseterm); i<ilimit; i++) { encx=*(xptr+i); ency=*(yptr+i); if (!wr_match_term_aux(g,encx,ency,uniquestrflag)) return 0; } return 1; } }