/* Case 2 - unmapped memory is unaddressable+undefined */ static void test2() { char *m = mm(0, pgsz * 5, PROT_READ|PROT_WRITE); VALGRIND_CHECK_READABLE(m, pgsz*5); /* all OK */ munmap(&m[pgsz*2], pgsz); VALGRIND_CHECK_READABLE(&m[pgsz*2], pgsz); /* undefined */ /* XXX need an memcheck/addrcheck request to test addressability */ m[pgsz*2] = 'x'; /* unmapped fault */ }
/* Case 5 - mprotect doesn't affect definedness */ static void test5() { char *m = mm(0, pgsz * 5, PROT_READ|PROT_WRITE); VALGRIND_MAKE_WRITABLE (m, pgsz*5); memset(m, 'x', 10); VALGRIND_CHECK_READABLE(m, 10); /* OK */ VALGRIND_CHECK_READABLE(m+10, 10); /* BAD */ mprotect(m, pgsz*5, PROT_NONE); mprotect(m, pgsz*5, PROT_READ); VALGRIND_CHECK_READABLE(m, 10); /* still OK */ VALGRIND_CHECK_READABLE(m+20, 10); /* BAD */ }
int main ( void ) { int i, sum, m; char* aa = calloc(100,1); sum = 0; VALGRIND_CHECK_READABLE(aa,100); m = VALGRIND_MAKE_WRITABLE( &aa[49], 1 ); VALGRIND_CHECK_WRITABLE(aa,100); printf("m_na: returned value is %d\n", m ); for (i = 0; i < 100; i++) sum += aa[i]; printf("sum is %d\n", sum); m = VALGRIND_DISCARD(m); printf("m_rm: returned value is %d\n", m ); for (i = 0; i < 100; i++) sum += aa[i]; printf("sum is %d\n", sum); return 0; }
/* Case 3 - memory definedness doesn't survive remapping */ static void test3() { char *m = mm(0, pgsz * 5, PROT_READ|PROT_WRITE); VALGRIND_MAKE_WRITABLE(&m[pgsz], pgsz); mm(&m[pgsz], pgsz, PROT_READ); VALGRIND_CHECK_READABLE(&m[pgsz], pgsz); /* OK */ }
/* Case 4 - mprotect doesn't affect addressability */ static void test4() { char *m = mm(0, pgsz * 5, PROT_READ|PROT_WRITE); mprotect(m, pgsz, PROT_WRITE); VALGRIND_CHECK_READABLE(m, pgsz); /* OK */ m[44] = 'y'; /* OK */ mprotect(m, pgsz*5, PROT_NONE); m[55] = 'x'; /* permission fault, but no tool complaint */ }
/* * XDR opaque data * Allows the specification of a fixed size sequence of opaque bytes. * cp points to the opaque object and cnt gives the byte length. */ bool_t xdr_opaque(XDR *xdrs, caddr_t cp, u_int cnt) { u_int rndup; static int crud[BYTES_PER_XDR_UNIT]; /* * if no data we are done */ if (cnt == 0) return (TRUE); /* * round byte count to full xdr units */ rndup = cnt % BYTES_PER_XDR_UNIT; if (rndup > 0) rndup = BYTES_PER_XDR_UNIT - rndup; if (xdrs->x_op == XDR_DECODE) { if (!XDR_GETBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_GETBYTES(xdrs, (caddr_t) (void *)crud, rndup)); } if (xdrs->x_op == XDR_ENCODE) { VALGRIND_CHECK_READABLE((volatile void *)cp, cnt); if (!XDR_PUTBYTES(xdrs, cp, cnt)) { return (FALSE); } if (rndup == 0) return (TRUE); return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); } if (xdrs->x_op == XDR_FREE) { return (TRUE); } return (FALSE); }
enum vocab_ret vocab_decode(struct vocab_vector *vocab, struct vec *v) { unsigned long int tmp; unsigned int bytes = 0, ret; unsigned char byte; VALGRIND_CHECK_WRITABLE(vocab, sizeof(*vocab)); /* if debugging, clear the vocab vector first */ assert((memset(vocab, 0, sizeof(*vocab)), 1)); /* check that memory can be accessed, then mark vocab entry as * uninitialised */ VALGRIND_MAKE_WRITABLE(vocab, sizeof(*vocab)); VALGRIND_CHECK_READABLE(v->pos, VEC_LEN(v)); /* first, get first byte which contains attribute, location and type * indications */ if (v->pos < v->end) { vec_byte_read(v, (char *) &byte, 1); bytes++; vocab->attr = byte & BIT_LMASK(2); byte >>= 2; vocab->location = byte & BIT_LMASK(2); byte >>= 2; vocab->type = byte; if (vocab->attr & VOCAB_ATTRIBUTES_PERLIST) { if ((ret = vec_vbyte_read(v, &tmp))) { vocab->attribute = (unsigned int) tmp; bytes += ret; } else { if (((unsigned int) VEC_LEN(v)) <= vec_vbyte_len(UINT_MAX)) { v->pos -= bytes; return VOCAB_ENOSPC; } else { v->pos -= bytes; return VOCAB_EOVERFLOW; } } } /* get common header entries */ if ((ret = vec_vbyte_read(v, &vocab->size)) && (bytes += ret) && (ret = vec_vbyte_read(v, &vocab->header.doc.docs)) && (bytes += ret) && (ret = vec_vbyte_read(v, &vocab->header.doc.occurs)) && (bytes += ret) && (ret = vec_vbyte_read(v, &vocab->header.doc.last)) && (bytes += ret)) { /* succeeded, do nothing */ } else { if (((unsigned int) VEC_LEN(v)) <= vec_vbyte_len(UINT_MAX)) { v->pos -= bytes; return VOCAB_ENOSPC; } else { v->pos -= bytes; return VOCAB_EOVERFLOW; } } /* get specific header entries */ switch (vocab->type) { case VOCAB_VTYPE_DOC: case VOCAB_VTYPE_DOCWP: /* ok, so i cheated a little and just read the common, uh, not * common ones above (they're not common because future vector * types might not have them)... */ break; case VOCAB_VTYPE_IMPACT: break; default: v->pos -= bytes; return VOCAB_EINVAL; } /* get location */ switch (vocab->location) { case VOCAB_LOCATION_VOCAB: if (((unsigned int) VEC_LEN(v)) >= vocab->size) { /* note that we increment vector over in-vocab vector so that * successive _decode calls will work as planned */ vocab->loc.vocab.vec = v->pos; v->pos += vocab->size; bytes += vocab->size; } else { v->pos -= bytes; return VOCAB_ENOSPC; } break; case VOCAB_LOCATION_FILE: if ((ret = vec_vbyte_read(v, &tmp)) && ((vocab->loc.file.fileno = tmp), (bytes += ret)) && (ret = vec_vbyte_read(v, &vocab->loc.file.offset)) && (bytes += ret) && (ret = vec_vbyte_read(v, &tmp)) && ((vocab->loc.file.capacity = tmp), (bytes += ret))) { /* succeeded, do nothing */ } else { if (((unsigned int) VEC_LEN(v)) <= vec_vbyte_len(UINT_MAX)) { v->pos -= bytes; return VOCAB_ENOSPC; } else { v->pos -= bytes; return VOCAB_EOVERFLOW; } } break; default: v->pos -= bytes; return VOCAB_EINVAL; } return VOCAB_OK; } else {
/* Case 1 - mmaped memory is defined */ static void test1() { char *m = mm(0, pgsz * 5, PROT_READ); VALGRIND_CHECK_READABLE(m, pgsz*5); /* all defined */ }