Ejemplo n.º 1
0
int timer_create_portable(clockid_t clockid, struct sigevent *portable_evp,
                          timer_t *timerid)
{
    struct sigevent native_sigevent, *evp = portable_evp;

    if (!invalid_pointer(portable_evp) &&
        (evp->sigev_notify == SIGEV_SIGNAL ||
         evp->sigev_notify == SIGEV_THREAD_ID)) {

        native_sigevent = *portable_evp;
        evp = &native_sigevent;
        evp->sigev_signo = signum_pton(evp->sigev_signo);
    }
    return timer_create(clockid, evp, timerid);
}
Ejemplo n.º 2
0
static void __init
test_pointer(void)
{
	plain();
	null_pointer();
	invalid_pointer();
	symbol_ptr();
	kernel_ptr();
	struct_resource();
	addr();
	escaped_str();
	hex_string();
	mac();
	ip();
	uuid();
	dentry();
	struct_va_format();
	struct_rtc_time();
	struct_clk();
	bitmap();
	netdev_features();
	flags();
}
Ejemplo n.º 3
0
void goto_checkt::pointer_validity_check(
  const dereference_exprt &expr,
  const guardt &guard)
{
  if(!enable_pointer_check)
    return;

  const exprt &pointer=expr.op0();
  const typet &pointer_type=to_pointer_type(ns.follow(pointer.type()));

  assert(base_type_eq(pointer_type.subtype(), expr.type(), ns));

  local_bitvector_analysist::flagst flags=
    local_bitvector_analysis->get(t, pointer);

  const typet &dereference_type=pointer_type.subtype();

  // For Java, we only need to check for null
  if(mode==ID_java)
  {
    if(flags.is_unknown() || flags.is_null())
    {
      notequal_exprt not_eq_null(pointer, gen_zero(pointer.type()));

      add_guarded_claim(
        not_eq_null,
        "reference is null",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);
    }
  }
  else
  {
    if(flags.is_unknown() || flags.is_null())
    {
      add_guarded_claim(
        not_exprt(null_pointer(pointer)),
        "dereference failure: pointer NULL",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);
    }

    if(flags.is_unknown())
      add_guarded_claim(
        not_exprt(invalid_pointer(pointer)),
        "dereference failure: pointer invalid",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);

    if(flags.is_uninitialized())
      add_guarded_claim(
        not_exprt(invalid_pointer(pointer)),
        "dereference failure: pointer uninitialized",
        "pointer dereference",
        expr.find_source_location(),
        expr,
        guard);

    if(mode != ID_java)
    {
      if(flags.is_unknown() || flags.is_dynamic_heap())
        add_guarded_claim(
          not_exprt(deallocated(pointer, ns)),
          "dereference failure: deallocated dynamic object",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);

      if(flags.is_unknown() || flags.is_dynamic_local())
        add_guarded_claim(
          not_exprt(dead_object(pointer, ns)),
          "dereference failure: dead object",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
    }

    if(enable_bounds_check)
    {
      if(flags.is_unknown() || flags.is_dynamic_heap())
      {
        exprt dynamic_bounds=
          or_exprt(dynamic_object_lower_bound(pointer),
                   dynamic_object_upper_bound(pointer, dereference_type, ns));

        add_guarded_claim(
          implies_exprt(malloc_object(pointer, ns), not_exprt(dynamic_bounds)),
          "dereference failure: dynamic object bounds",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
      }
    }

    if(enable_bounds_check)
    {
      if(flags.is_unknown() ||
         flags.is_dynamic_local() ||
         flags.is_static_lifetime())
      {
        exprt object_bounds=
          or_exprt(object_lower_bound(pointer),
                   object_upper_bound(pointer, dereference_type, ns));

        add_guarded_claim(
          or_exprt(dynamic_object(pointer), not_exprt(object_bounds)),
          "dereference failure: object bounds",
          "pointer dereference",
          expr.find_source_location(),
          expr,
          guard);
      }
    }
  }
}
Ejemplo n.º 4
0
/*
 * For 32 bit flocks we are converting a portable/ARM struct flock to a MIPS struct flock:
 *
 * MIPS:                        ARM:
 *     struct flock {           struct flock_portable {
 *       short l_type;            short l_type;
 *
 *       short l_whence;          short l_whence;
 *       off_t l_start;           loff_t l_start;
 *       off_t l_len;             loff_t l_len;
 *       long l_sysid;
 *
 *       __kernel_pid_t l_pid;    pid_t l_pid;
 *       long pad[4];
 *     };                       }
 *
 * which have identically sized structure members:
 *
 * For a 64 bit flocks we only have to deal with
 * a four byte padding in the ARM/Portable structure:
 *
 *    MIPS:                     ARM:
 *        struct flock64 {      struct flock64_portable {
 *        short l_type;           short l_type;
 *        short l_whence;         short l_whence;
 *                                unsigned char __padding[4];   <----  NOTE
 *        loff_t l_start;         loff_t l_start;
 *        loff_t l_len;           loff_t l_len;
 *        pid_t l_pid;            pid_t l_pid;
 *      }                       }
 */
int WRAP(fcntl)(int fd, int portable_cmd, ...)
{
    int flags;
    va_list ap;
    void *arg;
    int mips_cmd;
    int result = 0;
    struct flock flock;                                 /* Native MIPS structure */
    struct flock64 flock64;                             /* Native MIPS structure */
    char *portable_cmd_name = map_portable_cmd_to_name(portable_cmd);
    struct flock_portable *flock_portable = NULL;
    struct flock64_portable *flock64_portable = NULL;

    ALOGV(" ");
    ALOGV("%s(fd:%d, portable_cmd:%d:'%s', ...) {",  __func__,
              fd,    portable_cmd,
                     portable_cmd_name);


    va_start(ap, portable_cmd);
    arg = va_arg(ap, void *);
    va_end(ap);

    mips_cmd = fcntl_cmd_pton(portable_cmd);
    switch(mips_cmd) {
    case F_GETLK:
    case F_SETLK:
    case F_SETLKW:
        flock_portable = (struct flock_portable *) arg;

        if (invalid_pointer(flock_portable)) {
            ALOGE("%s: flock_portable:%p == {NULL||-1}", __func__, flock_portable);
            errno = EFAULT;
            result = -1;
            goto done;
        }

        /*
         * Lock type and Whence are the same for all ARCHs
         *      (F_RDLCK:0,   F_WRLCK:1,  F_UNLCK:2)
         *      (SEEK_SET:0, SEEK_CUR:1, SEEK_END:2)
         */
        flock.l_type = flock_portable->l_type;
        flock.l_whence = flock_portable->l_whence;
        flock.l_start = (off_t) flock_portable->l_start;
        flock.l_len =  (off_t) flock_portable->l_len;
        flock.l_sysid = 0L;
        flock.l_pid = flock_portable->l_pid;    /* Perhaps 0 would be better */

        result = __fcntl64(fd, mips_cmd, (void *) &flock);

        flock_portable->l_type = flock.l_type;
        flock_portable->l_whence = flock.l_whence;
        flock_portable->l_start = flock.l_start;
        flock_portable->l_len = flock.l_len;
        flock_portable->l_pid = flock.l_pid;
        break;

    case F_GETLK64:
    case F_SETLK64:
    case F_SETLKW64:
        flock64_portable = (struct flock64_portable *) arg;

        if (invalid_pointer(flock_portable)) {
            ALOGE("%s: flock_portable:%p == {NULL||-1}", __func__, flock_portable);
            errno = EFAULT;
            result = -1;
            goto done;
        }

        /*
         * Lock type and Whence are the same for all ARCHs
         *      (F_RDLCK:0,   F_WRLCK:1,  F_UNLCK:2)
         *      (SEEK_SET:0, SEEK_CUR:1, SEEK_END:2)
         */
        flock64.l_type = flock64_portable->l_type;
        flock64.l_whence = flock64_portable->l_whence;
        flock64.l_start = (off_t) flock64_portable->l_start;
        flock64.l_len =  (off_t) flock64_portable->l_len;
        flock64.l_pid = flock64_portable->l_pid;        /* Perhaps 0 would be better */

        result = __fcntl64(fd, mips_cmd, (void *) &flock);

        flock64_portable->l_type = flock64.l_type;
        flock64_portable->l_whence = flock64.l_whence;
        flock64_portable->l_start = flock64.l_start;
        flock64_portable->l_len = flock64.l_len;
        flock64_portable->l_pid = flock64.l_pid;
        break;

    case F_SETFL:
        flags = fcntl_flags_pton((int)arg);
        result = __fcntl64(fd, mips_cmd, (void *)flags);
        break;

    case F_GETFL:
        result = __fcntl64(fd, mips_cmd, arg);
        if (result != -1)
            result = fcntl_flags_ntop(result);
        break;

    case F_DUPFD:
    case F_GETFD:
    case F_SETFD:
    case F_SETOWN:
    case F_GETOWN:
    case F_SETSIG:
    case F_GETSIG:
    case F_SETLEASE:
    case F_GETLEASE:
    case F_NOTIFY:
        ALOGV("%s: Calling __fcntl64(fd:%d, mips_cmd:0x%x, arg:%p);", __func__,
                                     fd,    mips_cmd,      arg);

        result = __fcntl64(fd, mips_cmd, arg);

        if (result < 0) {
            ALOGV("%s: result = %d = __fcntl64(fd:%d, mips_cmd:0x%x, arg:%p);", __func__,
                       result,                 fd,    mips_cmd,      arg);
        } else {
            if (mips_cmd == F_SETFD) {
                /*
                 * File descriptor flag bits got set or cleared.
                 */
                flags = (int)arg;
                if (flags & FD_CLOEXEC) {
                    filefd_CLOEXEC_enabled(fd);
                } else {
                    filefd_CLOEXEC_disabled(fd);
                }
            }
        }
        break;

    default:
        /*
         * This is likely a rare situation, abort() would hang fcntl13 LTP test.
         */
        ALOGE("%s: mips_cmd:%d doesn't appear to be supported;", __func__,
                   mips_cmd);

        ALOGV("%s: Assume it doesn't need to be mapped!", __func__);

        result = __fcntl64(fd, mips_cmd, arg);
    }

done:
    ALOGV("%s: return(result:%d); }", __func__, result);
    return result;
}
Ejemplo n.º 5
0
/// \par parameters: expression dest, to be dereferenced under given guard,
/// and given mode
/// \return returns pointer after dereferencing
exprt value_set_dereferencet::dereference(
  const exprt &pointer,
  const guardt &guard,
  const modet mode)
{
  if(pointer.type().id()!=ID_pointer)
    throw "dereference expected pointer type, but got "+
          pointer.type().pretty();

  // we may get ifs due to recursive calls
  if(pointer.id()==ID_if)
  {
    const if_exprt &if_expr=to_if_expr(pointer);
    // push down the if
    guardt true_guard=guard;
    guardt false_guard=guard;

    true_guard.add(if_expr.cond());
    false_guard.add(not_exprt(if_expr.cond()));

    exprt true_case=dereference(if_expr.true_case(), true_guard, mode);
    exprt false_case=dereference(if_expr.false_case(), false_guard, mode);

    return if_exprt(if_expr.cond(), true_case, false_case);
  }

  // type of the object
  const typet &type=pointer.type().subtype();

  #if 0
  std::cout << "DEREF: " << from_expr(ns, "", pointer) << '\n';
  #endif

  // collect objects the pointer may point to
  value_setst::valuest points_to_set;

  dereference_callback.get_value_set(pointer, points_to_set);

  #if 0
  for(value_setst::valuest::const_iterator
      it=points_to_set.begin();
      it!=points_to_set.end();
      it++)
    std::cout << "P: " << from_expr(ns, "", *it) << '\n';
  #endif

  // get the values of these

  std::list<valuet> values;

  for(value_setst::valuest::const_iterator
      it=points_to_set.begin();
      it!=points_to_set.end();
      it++)
  {
    valuet value=build_reference_to(*it, mode, pointer, guard);

    #if 0
    std::cout << "V: " << from_expr(ns, "", value.pointer_guard) << " --> ";
    std::cout << from_expr(ns, "", value.value) << '\n';
    #endif

    values.push_back(value);
  }

  // can this fail?
  bool may_fail;

  if(values.empty())
  {
    invalid_pointer(pointer, guard);
    may_fail=true;
  }
  else
  {
    may_fail=false;
    for(std::list<valuet>::const_iterator
        it=values.begin();
        it!=values.end();
        it++)
      if(it->value.is_nil())
        may_fail=true;
  }

  if(may_fail)
  {
    // first see if we have a "failed object" for this pointer

    const symbolt *failed_symbol;
    exprt failure_value;

    if(dereference_callback.has_failed_symbol(
         pointer, failed_symbol))
    {
      // yes!
      failure_value=failed_symbol->symbol_expr();
      failure_value.set(ID_C_invalid_object, true);
    }
    else
    {
      // else: produce new symbol

      symbolt symbol;
      symbol.name="symex::invalid_object"+std::to_string(invalid_counter++);
      symbol.base_name="invalid_object";
      symbol.type=type;

      // make it a lvalue, so we can assign to it
      symbol.is_lvalue=true;

      get_new_name(symbol, ns);

      failure_value=symbol.symbol_expr();
      failure_value.set(ID_C_invalid_object, true);

      new_symbol_table.move(symbol);
    }

    valuet value;
    value.value=failure_value;
    value.pointer_guard=true_exprt();
    values.push_front(value);
  }

  // now build big case split, but we only do "good" objects

  exprt value=nil_exprt();

  for(std::list<valuet>::const_iterator
      it=values.begin();
      it!=values.end();
      it++)
  {
    if(it->value.is_not_nil())
    {
      if(value.is_nil()) // first?
        value=it->value;
      else
        value=if_exprt(it->pointer_guard, it->value, value);
    }
  }

  #if 0
  std::cout << "R: " << from_expr(ns, "", value) << "\n\n";
  #endif

  return value;
}
Ejemplo n.º 6
0
value_set_dereferencet::valuet value_set_dereferencet::build_reference_to(
  const exprt &what,
  const modet mode,
  const exprt &pointer_expr,
  const guardt &guard)
{
  const typet &dereference_type=
    ns.follow(pointer_expr.type()).subtype();

  if(what.id()==ID_unknown ||
     what.id()==ID_invalid)
  {
    invalid_pointer(pointer_expr, guard);
    return valuet();
  }

  if(what.id()!=ID_object_descriptor)
    throw "unknown points-to: "+what.id_string();

  const object_descriptor_exprt &o=to_object_descriptor_expr(what);

  const exprt &root_object=o.root_object();
  const exprt &object=o.object();

  #if 0
  std::cout << "O: " << from_expr(ns, "", root_object) << '\n';
  #endif

  valuet result;

  if(root_object.id()=="NULL-object")
  {
    if(options.get_bool_option("pointer-check"))
    {
      guardt tmp_guard(guard);

      if(o.offset().is_zero())
      {
        tmp_guard.add(null_pointer(pointer_expr));

        dereference_callback.dereference_failure(
          "pointer dereference",
          "NULL pointer", tmp_guard);
      }
      else
      {
        tmp_guard.add(null_object(pointer_expr));

        dereference_callback.dereference_failure(
          "pointer dereference",
          "NULL plus offset pointer", tmp_guard);
      }
    }
  }
  else if(root_object.id()==ID_dynamic_object)
  {
    // const dynamic_object_exprt &dynamic_object=
    //  to_dynamic_object_expr(root_object);

    // the object produced by malloc
    exprt malloc_object=
      ns.lookup(CPROVER_PREFIX "malloc_object").symbol_expr();

    exprt is_malloc_object=same_object(pointer_expr, malloc_object);

    // constraint that it actually is a dynamic object
    exprt dynamic_object_expr(ID_dynamic_object, bool_typet());
    dynamic_object_expr.copy_to_operands(pointer_expr);

    // this is also our guard
    result.pointer_guard=dynamic_object_expr;

    // can't remove here, turn into *p
    result.value=dereference_exprt(pointer_expr, dereference_type);

    if(options.get_bool_option("pointer-check"))
    {
      // if(!dynamic_object.valid().is_true())
      {
        // check if it is still alive
        guardt tmp_guard(guard);
        tmp_guard.add(deallocated(pointer_expr, ns));
        dereference_callback.dereference_failure(
          "pointer dereference",
          "dynamic object deallocated",
          tmp_guard);
      }

      if(options.get_bool_option("bounds-check"))
      {
        if(!o.offset().is_zero())
        {
          // check lower bound
          guardt tmp_guard(guard);
          tmp_guard.add(is_malloc_object);
          tmp_guard.add(
            dynamic_object_lower_bound(
              pointer_expr,
              ns,
              nil_exprt()));
          dereference_callback.dereference_failure(
            "pointer dereference",
            "dynamic object lower bound", tmp_guard);
        }

        {
          // check upper bound

          // we check SAME_OBJECT(__CPROVER_malloc_object, p) &&
          //          POINTER_OFFSET(p)+size>__CPROVER_malloc_size

          guardt tmp_guard(guard);
          tmp_guard.add(is_malloc_object);
          tmp_guard.add(
            dynamic_object_upper_bound(
              pointer_expr,
              dereference_type,
              ns,
              size_of_expr(dereference_type, ns)));
          dereference_callback.dereference_failure(
            "pointer dereference",
            "dynamic object upper bound", tmp_guard);
        }
      }
    }
  }
  else if(root_object.id()==ID_integer_address)
  {
    // This is stuff like *((char *)5).
    // This is turned into an access to __CPROVER_memory[...].

    if(language_mode==ID_java)
    {
      result.value=nil_exprt();
      return result;
    }

    const symbolt &memory_symbol=ns.lookup(CPROVER_PREFIX "memory");
    exprt symbol_expr=symbol_exprt(memory_symbol.name, memory_symbol.type);

    if(base_type_eq(
         ns.follow(memory_symbol.type).subtype(),
         dereference_type, ns))
    {
      // Types match already, what a coincidence!
      // We can use an index expression.

      exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr));
      index_expr.type()=ns.follow(memory_symbol.type).subtype();
      result.value=index_expr;
    }
    else if(dereference_type_compare(
              ns.follow(memory_symbol.type).subtype(),
              dereference_type))
    {
      exprt index_expr=index_exprt(symbol_expr, pointer_offset(pointer_expr));
      index_expr.type()=ns.follow(memory_symbol.type).subtype();
      result.value=typecast_exprt(index_expr, dereference_type);
    }
    else
    {
      // We need to use byte_extract.
      // Won't do this without a commitment to an endianness.

      if(config.ansi_c.endianness==configt::ansi_ct::endiannesst::NO_ENDIANNESS)
      {
      }
      else
      {
        exprt byte_extract(byte_extract_id(), dereference_type);
        byte_extract.copy_to_operands(
          symbol_expr, pointer_offset(pointer_expr));
        result.value=byte_extract;
      }
    }
  }
  else
  {
    // something generic -- really has to be a symbol
    address_of_exprt object_pointer(object);

    if(o.offset().is_zero())
    {
      equal_exprt equality(pointer_expr, object_pointer);

      if(ns.follow(equality.lhs().type())!=ns.follow(equality.rhs().type()))
        equality.lhs().make_typecast(equality.rhs().type());

      result.pointer_guard=equality;
    }
    else
    {
      result.pointer_guard=same_object(pointer_expr, object_pointer);
    }

    guardt tmp_guard(guard);
    tmp_guard.add(result.pointer_guard);

    valid_check(object, tmp_guard, mode);

    const typet &object_type=ns.follow(object.type());
    const exprt &root_object=o.root_object();
    const typet &root_object_type=ns.follow(root_object.type());

    exprt root_object_subexpression=root_object;

    if(dereference_type_compare(object_type, dereference_type) &&
       o.offset().is_zero())
    {
      // The simplest case: types match, and offset is zero!
      // This is great, we are almost done.

      result.value=object;

      if(object_type!=ns.follow(dereference_type))
        result.value.make_typecast(dereference_type);
    }
    else if(root_object_type.id()==ID_array &&
            dereference_type_compare(
              root_object_type.subtype(),
              dereference_type))
    {
      // We have an array with a subtype that matches
      // the dereferencing type.
      // We will require well-alignedness!

      exprt offset;

      // this should work as the object is essentially the root object
      if(o.offset().is_constant())
        offset=o.offset();
      else
        offset=pointer_offset(pointer_expr);

      exprt adjusted_offset;

      // are we doing a byte?
      mp_integer element_size=
        dereference_type.id()==ID_empty?
        pointer_offset_size(char_type(), ns):
        pointer_offset_size(dereference_type, ns);

      if(element_size==1)
      {
        // no need to adjust offset
        adjusted_offset=offset;
      }
      else if(element_size<=0)
      {
        throw "unknown or invalid type size of:\n"+dereference_type.pretty();
      }
      else
      {
        exprt element_size_expr=
          from_integer(element_size, offset.type());

        adjusted_offset=binary_exprt(
          offset, ID_div, element_size_expr, offset.type());

        // TODO: need to assert well-alignedness
      }

      index_exprt index_expr=
        index_exprt(root_object, adjusted_offset, root_object_type.subtype());

      bounds_check(index_expr, tmp_guard);

      result.value=index_expr;

      if(ns.follow(result.value.type())!=ns.follow(dereference_type))
        result.value.make_typecast(dereference_type);
    }
    else if(get_subexpression_at_offset(
        root_object_subexpression,
        o.offset(),
        dereference_type,
        ns))
    {
      // Successfully found a member, array index, or combination thereof
      // that matches the desired type and offset:
      result.value=root_object_subexpression;
    }
    else
    {
      // we extract something from the root object
      result.value=o.root_object();

      // this is relative to the root object
      const exprt offset=pointer_offset(pointer_expr);

      if(memory_model(result.value, dereference_type, tmp_guard, offset))
      {
        // ok, done
      }
      else
      {
        if(options.get_bool_option("pointer-check"))
        {
          std::string msg="memory model not applicable (got `";
          msg+=from_type(ns, "", result.value.type());
          msg+="', expected `";
          msg+=from_type(ns, "", dereference_type);
          msg+="')";

          dereference_callback.dereference_failure(
            "pointer dereference",
            msg, tmp_guard);
        }

        return valuet(); // give up, no way that this is ok
      }
    }
  }

  return result;
}