static int mk_attr_descrs(NODE *list, ATTR_DESCR attr_descrs[]) { int i; int type, len; NODE *attr; int errval; // for each element of the list... for(i = 0; list != NULL && i < MAXATTRS; ++i, list = list->u.LIST.next) { attr = list->u.LIST.self; // interpret the format string errval = parse_format_string(attr->u.ATTRTYPE.type, &type, &len); if (errval != E_OK) return errval; // add it to the list attr_descrs[i].attrName = attr->u.ATTRTYPE.attrname; attr_descrs[i].attrType = type; attr_descrs[i].attrLen = len; } // if the list is too long, then error if (i == MAXATTRS) return E_TOOMANYATTRS; return i; }
/* * mk_attr_infos: converts a list of attribute descriptors (attribute names, * types, and lengths) to an array of AttrInfo's so it can be sent to * Create. * * Returns: * length of the list on success ( >= 0 ) * error code otherwise */ static int mk_attr_infos(NODE *list, int max, AttrInfo attrInfos[]) { int i; int len; AttrType type; NODE *attr; RC errval; /* for each element of the list... */ for(i = 0; list != NULL; ++i, list = list -> u.LIST.next) { /* if the list is too long, then error */ if(i == max) return E_TOOMANY; attr = list -> u.LIST.curr; /* Make sure the attribute name isn't too long */ if(strlen(attr -> u.ATTRTYPE.attrname) > MAXNAME) return E_TOOLONG; /* interpret the format string */ errval = parse_format_string(attr -> u.ATTRTYPE.type, &type, &len); if(errval != E_OK) return errval; /* add it to the list */ attrInfos[i].attrName = attr -> u.ATTRTYPE.attrname; attrInfos[i].attrType = type; attrInfos[i].attrLength = len; } return i; }
static int init(struct sr_input *in, GHashTable *options) { struct context *inc; int num_channels; char channelname[8]; const char *format; int fmt_index; num_channels = g_variant_get_int32(g_hash_table_lookup(options, "numchannels")); if (num_channels < 1) { sr_err("Invalid value for numchannels: must be at least 1."); return SR_ERR_ARG; } format = g_variant_get_string(g_hash_table_lookup(options, "format"), NULL); if ((fmt_index = parse_format_string(format)) == -1) { GString *formats = g_string_sized_new(200); for (unsigned int i = 0; i < ARRAY_SIZE(sample_formats); i++) g_string_append_printf(formats, "%s ", sample_formats[i].fmt_name); sr_err("Invalid format '%s': must be one of: %s.", format, formats->str); g_string_free(formats, TRUE); return SR_ERR_ARG; } in->sdi = g_malloc0(sizeof(struct sr_dev_inst)); in->priv = inc = g_malloc0(sizeof(struct context)); for (int i = 0; i < num_channels; i++) { snprintf(channelname, 8, "CH%d", i + 1); sr_channel_new(in->sdi, i, SR_CHANNEL_ANALOG, TRUE, channelname); } inc->samplerate = g_variant_get_uint64(g_hash_table_lookup(options, "samplerate")); inc->samplesize = sample_formats[fmt_index].encoding.unitsize * num_channels; init_context(inc, &sample_formats[fmt_index], in->sdi->channels); return SR_OK; }
static void ax_printf (CORE_ADDR fn, CORE_ADDR chan, const char *format, int nargs, ULONGEST *args) { const char *f = format; struct format_piece *fpieces; int i, fp; char *current_substring; int nargs_wanted; ax_debug ("Printf of \"%s\" with %d args", format, nargs); fpieces = parse_format_string (&f); nargs_wanted = 0; for (fp = 0; fpieces[fp].string != NULL; fp++) if (fpieces[fp].argclass != literal_piece) ++nargs_wanted; if (nargs != nargs_wanted) error (_("Wrong number of arguments for specified format-string")); i = 0; for (fp = 0; fpieces[fp].string != NULL; fp++) { current_substring = fpieces[fp].string; ax_debug ("current substring is '%s', class is %d", current_substring, fpieces[fp].argclass); switch (fpieces[fp].argclass) { case string_arg: { gdb_byte *str; CORE_ADDR tem; int j; tem = args[i]; /* This is a %s argument. Find the length of the string. */ for (j = 0;; j++) { gdb_byte c; read_inferior_memory (tem + j, &c, 1); if (c == 0) break; } /* Copy the string contents into a string inside GDB. */ str = (gdb_byte *) alloca (j + 1); if (j != 0) read_inferior_memory (tem, str, j); str[j] = 0; printf (current_substring, (char *) str); } break; case long_long_arg: #if defined (CC_HAS_LONG_LONG) && defined (PRINTF_HAS_LONG_LONG) { long long val = args[i]; printf (current_substring, val); break; } #else error (_("long long not supported in agent printf")); #endif case int_arg: { int val = args[i]; printf (current_substring, val); break; } case long_arg: { long val = args[i]; printf (current_substring, val); break; } case literal_piece: /* Print a portion of the format string that has no directives. Note that this will not include any ordinary %-specs, but it might include "%%". That is why we use printf_filtered and not puts_filtered here. Also, we pass a dummy argument because some platforms have modified GCC to include -Wformat-security by default, which will warn here if there is no argument. */ printf (current_substring, 0); break; default: error (_("Format directive in '%s' not supported in agent printf"), current_substring); } /* Maybe advance to the next argument. */ if (fpieces[fp].argclass != literal_piece) ++i; } free_format_pieces (fpieces); fflush (stdout); }
int main(int argc, char **argv) { int opt; extern char *optarg; extern int optind; int loop_status; signal(SIGHUP, &handle_signal); signal(SIGINT, &handle_signal); /* Process command line arguments */ while ((opt = getopt(argc, argv, "b:df:Fhpqi:l:m:n:o:P:r:st:u:S:")) != -1) { switch (opt) { case 'b': use_dumpfile = optarg; break; case 'd': daemon_mode = 1; use_syslog = 1; break; case 'f': format_str = optarg; break; case 'F': force_flush = 1; break; case 'h': display_usage(); break; case 'i': interface = optarg; break; case 'l': rate_threshold = atoi(optarg); break; case 'm': methods_str = optarg; break; case 'n': parse_count = atoi(optarg); break; case 'o': use_outfile = optarg; break; case 'p': set_promisc = 0; break; case 'P': pid_filename = optarg; break; case 'q': quiet_mode = 1; break; case 'r': use_infile = optarg; break; case 's': rate_stats = 1; break; case 't': rate_interval = atoi(optarg); break; case 'u': new_user = optarg; break; case 'S': eth_skip_bits = atoi(optarg); break; default: display_usage(); } } display_banner(); if (daemon_mode && !use_outfile) LOG_DIE("Daemon mode requires an output file"); if (parse_count < 0) LOG_DIE("Invalid -n value, must be 0 or greater"); if (rate_interval < 1) LOG_DIE("Invalid -t value, must be 1 or greater"); if (rate_threshold < 1) LOG_DIE("Invalid -l value, must be 1 or greater"); if (argv[optind] && *(argv[optind])) { capfilter = argv[optind]; } else { capfilter = default_capfilter; } if (!format_str) format_str = default_format; if (rate_stats) format_str = rate_format; parse_format_string(format_str); if (!methods_str) methods_str = default_methods; parse_methods_string(methods_str); if (force_flush) { if (setvbuf(stdout, NULL, _IONBF, 0) != 0) LOG_WARN("Cannot disable buffering on stdout"); } if (!pid_filename) pid_filename = PID_FILENAME; pcap_hnd = prepare_capture(interface, set_promisc, use_infile, capfilter); open_outfiles(); if (daemon_mode) runas_daemon(); if (new_user) change_user(new_user); if ((buf = malloc(BUFSIZ + 1)) == NULL) LOG_DIE("Cannot allocate memory for packet data buffer"); if (rate_stats) init_rate_stats(rate_interval, use_infile, rate_threshold); start_time = time(0); loop_status = pcap_loop(pcap_hnd, -1, &parse_http_packet, NULL); if (loop_status == -1) { LOG_DIE("Problem reading packets from interface: %s", pcap_geterr(pcap_hnd)); } else if (loop_status == -2) { PRINT("Loop halted, shutting down..."); } print_stats(); cleanup(); return loop_status == -1 ? EXIT_FAILURE : EXIT_SUCCESS; }
int main(int argc, char **argv) { int opt; extern char *optarg; extern int optind; int loop_status; signal(SIGINT, &handle_signal); /* Process command line arguments */ while ((opt = getopt(argc, argv, "b:df:hpqi:m:n:o:r:u:")) != -1) { switch (opt) { case 'b': use_dumpfile = optarg; break; case 'd': daemon_mode = 1; use_syslog = 1; break; case 'f': format_str = optarg; break; case 'h': display_usage(); break; case 'i': interface = optarg; break; case 'm': methods_str = optarg; break; case 'n': parse_count = atoi(optarg); break; case 'o': use_outfile = optarg; break; case 'p': set_promisc = 0; break; case 'q': quiet_mode = 1; break; case 'r': use_infile = optarg; break; case 'u': new_user = optarg; break; default: display_usage(); } } display_banner(); if (daemon_mode && !use_outfile) LOG_DIE("Daemon mode requires an output file"); if (parse_count < 0) LOG_DIE("Invalid -n value, must be 0 or greater"); if (argv[optind] && *(argv[optind])) { capfilter = argv[optind]; } else { capfilter = default_capfilter; } if (!format_str) format_str = default_format; parse_format_string(format_str); if (!methods_str) methods_str = default_methods; parse_methods_string(methods_str); pcap_hnd = prepare_capture(interface, set_promisc, use_infile, capfilter); open_outfiles(); if (daemon_mode) runas_daemon(); if (new_user) change_user(new_user); if ((buf = malloc(BUFSIZ + 1)) == NULL) LOG_DIE("Cannot allocate memory for packet data buffer"); start_time = time(0); loop_status = pcap_loop(pcap_hnd, -1, &parse_http_packet, NULL); if (loop_status == -1) { LOG_DIE("Problem reading packets from interface: %s", pcap_geterr(pcap_hnd)); } else if (loop_status == -2) { PRINT("Loop halted, shutting down..."); } cleanup(); return loop_status == -1 ? EXIT_FAILURE : EXIT_SUCCESS; }
void string_instrumentationt::do_format_string_write( goto_programt &dest, goto_programt::const_targett target, const code_function_callt::argumentst &arguments, unsigned format_string_inx, unsigned argument_start_inx, const std::string &function_name) { const exprt &format_arg = arguments[format_string_inx]; if(format_arg.id()=="address_of" && format_arg.op0().id()=="index" && format_arg.op0().op0().id()==ID_string_constant) // constant format { format_token_listt token_list; parse_format_string(format_arg.op0().op0(), token_list); unsigned args=0; for(format_token_listt::const_iterator it=token_list.begin(); it!=token_list.end(); it++) { if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!= it->flags.end()) continue; // asterisk means `ignore this' switch(it->type) { case format_tokent::STRING: { const exprt &argument=arguments[argument_start_inx+args]; const typet &arg_type=ns.follow(argument.type()); goto_programt::targett assertion=dest.add_instruction(); assertion->location=target->location; assertion->location.set("property", "string"); std::string comment("format string buffer overflow in "); comment += function_name; assertion->location.set("comment", comment); if(it->field_width!=0) { exprt fwidth = from_integer(it->field_width, uint_type()); exprt fw_1("+", uint_type()); exprt one = gen_one(uint_type()); fw_1.move_to_operands(fwidth); fw_1.move_to_operands(one); // +1 for 0-char exprt fw_lt_bs; if(arg_type.id()=="pointer") fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(argument)); else { index_exprt index; index.array()=argument; index.index()=gen_zero(uint_type()); address_of_exprt aof(index); fw_lt_bs=binary_relation_exprt(fw_1, "<=", buffer_size(aof)); } assertion->make_assertion(fw_lt_bs); } else { // this is a possible overflow. assertion->make_assertion(false_exprt()); } // now kill the contents invalidate_buffer(dest, target, argument, arg_type, it->field_width); args++; break; } case format_tokent::TEXT: case format_tokent::UNKNOWN: { // nothing break; } default: // everything else { const exprt &argument=arguments[argument_start_inx+args]; const typet &arg_type=ns.follow(argument.type()); goto_programt::targett assignment=dest.add_instruction(ASSIGN); assignment->location=target->location; exprt lhs("dereference", arg_type.subtype()); lhs.copy_to_operands(argument); exprt rhs=side_effect_expr_nondett(lhs.type()); rhs.location()=target->location; assignment->code=code_assignt(lhs, rhs); args++; break; } } } } else // non-const format string { for(unsigned i=argument_start_inx; i<arguments.size(); i++) { const typet &arg_type=ns.follow(arguments[i].type()); // Note: is_string_type() is a `good guess' here. Actually // any of the pointers could point into an array. But it // would suck if we had to invalidate all variables. // Luckily this case isn't needed too often. if(is_string_type(arg_type)) { goto_programt::targett assertion=dest.add_instruction(); assertion->location=target->location; assertion->location.set("property", "string"); std::string comment("format string buffer overflow in "); comment += function_name; assertion->location.set("comment", comment); // as we don't know any field width for the %s that // should be here during runtime, we just report a // possibly false positive assertion->make_assertion(false_exprt()); invalidate_buffer(dest, target, arguments[i], arg_type, 0); } else { goto_programt::targett assignment = dest.add_instruction(ASSIGN); assignment->location=target->location; exprt lhs("dereference", arg_type.subtype()); lhs.copy_to_operands(arguments[i]); exprt rhs=side_effect_expr_nondett(lhs.type()); rhs.location()=target->location; assignment->code=code_assignt(lhs, rhs); } } } }
void string_instrumentationt::do_format_string_read( goto_programt &dest, goto_programt::const_targett target, const code_function_callt::argumentst &arguments, unsigned format_string_inx, unsigned argument_start_inx, const std::string &function_name) { const exprt &format_arg = arguments[format_string_inx]; if(format_arg.id()=="address_of" && format_arg.op0().id()=="index" && format_arg.op0().op0().id()==ID_string_constant) { format_token_listt token_list; parse_format_string(format_arg.op0().op0(), token_list); unsigned args=0; for(format_token_listt::const_iterator it=token_list.begin(); it!=token_list.end(); it++) { if(it->type==format_tokent::STRING) { const exprt &arg = arguments[argument_start_inx+args]; const typet &arg_type = ns.follow(arg.type()); if(arg.id()!=ID_string_constant) // we don't need to check constants { goto_programt::targett assertion=dest.add_instruction(); assertion->location=target->location; assertion->location.set("property", "string"); std::string comment("zero-termination of string argument of "); comment += function_name; assertion->location.set("comment", comment); exprt temp(arg); if(arg_type.id()!="pointer") { index_exprt index; index.array()=temp; index.index()=gen_zero(uint_type()); index.type()=arg_type.subtype(); temp=address_of_exprt(index); } assertion->make_assertion(is_zero_string(temp)); } } if(it->type!=format_tokent::TEXT && it->type!=format_tokent::UNKNOWN) args++; if(find(it->flags.begin(), it->flags.end(), format_tokent::ASTERISK)!= it->flags.end()) args++; // just eat the additional argument } } else // non-const format string { goto_programt::targett format_ass=dest.add_instruction(); format_ass->make_assertion(is_zero_string(arguments[1])); format_ass->location=target->location; format_ass->location.set("property", "string"); std::string comment("zero-termination of format string of "); comment += function_name; format_ass->location.set("comment", comment); for(unsigned i=2; i<arguments.size(); i++) { const exprt &arg = arguments[i]; const typet &arg_type=ns.follow(arguments[i].type()); if(arguments[i].id()!=ID_string_constant && is_string_type(arg_type)) { goto_programt::targett assertion=dest.add_instruction(); assertion->location=target->location; assertion->location.set("property", "string"); std::string comment("zero-termination of string argument of "); comment += function_name; assertion->location.set("comment", comment); exprt temp(arg); if(arg_type.id()!="pointer") { index_exprt index; index.array()=temp; index.index()=gen_zero(uint_type()); index.type()=arg_type.subtype(); temp=address_of_exprt(index); } assertion->make_assertion(is_zero_string(temp)); } } } }
void goto_convertt::do_scanf( const exprt &lhs, const exprt &function, const exprt::operandst &arguments, goto_programt &dest) { const irep_idt &f_id=function.get(ID_identifier); if(f_id==CPROVER_PREFIX "scanf") { if(arguments.size()<1) { err_location(function); error() << "scanf takes at least one argument" << eom; throw 0; } irep_idt format_string; if(!get_string_constant(arguments[0], format_string)) { // use our model format_token_listt token_list=parse_format_string(id2string(format_string)); std::size_t argument_number=1; for(const auto & t : token_list) { typet type=get_type(t); if(type.is_not_nil()) { if(argument_number<arguments.size()) { exprt ptr= typecast_exprt(arguments[argument_number], pointer_type(type)); argument_number++; // make it nondet for now exprt lhs=dereference_exprt(ptr, type); exprt rhs=side_effect_expr_nondett(type); code_assignt assign(lhs, rhs); assign.add_source_location()=function.source_location(); copy(assign, ASSIGN, dest); } } } } else { // we'll just do nothing code_function_callt function_call; function_call.lhs()=lhs; function_call.function()=function; function_call.arguments()=arguments; function_call.add_source_location()=function.source_location(); copy(function_call, FUNCTION_CALL, dest); } } else assert(false); }
const char *fmt_str = cp -> argv [ 0 ] . data . ascii; /* local formatting storage */ PrintFmt fmt [ LOCAL_FMT_COUNT ]; /* data block for parse */ ParseData pd; pd . fmt_size = cp -> argv [ 0 ] . count; pd . fmt = fmt; /* packaged va_list */ vargs . dp = dp; vargs . idx = 0; /* parse the format string */ rc = parse_format_string ( fmt_str, & pd, & vargs ); if ( rc == 0 ) { /* the object size: literal data bytes + space for PrintFmt + space for PrintArg */ size_t obj_extra = pd . lit_size + pd . fmt_idx * sizeof ( PrintFmt ) + pd . arg_idx * sizeof ( PrintArg ) + pd . str_idx * sizeof ( String ); obj = malloc ( sizeof * obj + 1 + obj_extra ); if ( obj == NULL ) rc = RC ( rcXF, rcFunction, rcConstructing, rcMemory, rcExhausted ); else {