diff --git a/.github/workflows/locked.yml b/.github/workflows/locked.yml index 59a3f80c47..8604e7f52c 100644 --- a/.github/workflows/locked.yml +++ b/.github/workflows/locked.yml @@ -156,7 +156,7 @@ jobs: ocaml-compiler: ${{ matrix.ocaml-compiler }} - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/metadata.yml b/.github/workflows/metadata.yml index 1092606bc6..6c7360f9e3 100644 --- a/.github/workflows/metadata.yml +++ b/.github/workflows/metadata.yml @@ -39,7 +39,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} diff --git a/.github/workflows/options.yml b/.github/workflows/options.yml index 40652791fa..94c49e4bf6 100644 --- a/.github/workflows/options.yml +++ b/.github/workflows/options.yml @@ -18,7 +18,7 @@ jobs: uses: actions/checkout@v4 - name: Set up Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} diff --git a/conf/svcomp.json b/conf/svcomp.json index 913d43784b..342ac6f298 100644 --- a/conf/svcomp.json +++ b/conf/svcomp.json @@ -70,7 +70,8 @@ "congruence", "octagon", "wideningThresholds", - "loopUnrollHeuristic" + "loopUnrollHeuristic", + "memsafetySpecification" ] } }, diff --git a/src/analyses/base.ml b/src/analyses/base.ml index 908dc88401..6536a9c496 100644 --- a/src/analyses/base.ml +++ b/src/analyses/base.ml @@ -399,6 +399,8 @@ struct Int (if AD.is_bot (AD.meet p1 p2) then ID.of_int ik BI.one else match eq p1 p2 with Some x when x -> ID.of_int ik BI.zero | _ -> bool_top ik) | IndexPI when AD.to_string p2 = ["all_index"] -> addToAddrOp p1 (ID.top_of (Cilfacade.ptrdiff_ikind ())) + | IndexPI | PlusPI -> + addToAddrOp p1 (AD.to_int p2) (* sometimes index is AD for some reason... *) | _ -> VD.top () end (* For other values, we just give up! *) @@ -1231,9 +1233,16 @@ struct if copied then M.warn ~category:(Behavior (Undefined Other)) "The jump buffer %a contains values that were copied here instead of being set by setjmp. This is Undefined Behavior." d_exp e; x - | y -> failwith (GobPretty.sprintf "problem?! is %a %a:\n state is %a" CilType.Exp.pretty e VD.pretty y D.pretty ctx.local) + | Top + | Bot -> + JmpBufDomain.JmpBufSet.top () + | y -> + M.debug ~category:Imprecise "EvalJmpBuf %a is %a, not JmpBuf." CilType.Exp.pretty e VD.pretty y; + JmpBufDomain.JmpBufSet.top () end - | _ -> failwith "problem?!" + | _ -> + M.debug ~category:Imprecise "EvalJmpBuf is not Address"; + JmpBufDomain.JmpBufSet.top () end | Q.EvalInt e -> query_evalint (Analyses.ask_of_ctx ctx) ctx.global ctx.local e diff --git a/src/analyses/commonPriv.ml b/src/analyses/commonPriv.ml index db75455b40..793978980b 100644 --- a/src/analyses/commonPriv.ml +++ b/src/analyses/commonPriv.ml @@ -84,7 +84,7 @@ struct module V = struct (* TODO: Either3? *) - include Printable.Either (Printable.Either (VMutex) (VMutexInits)) (VGlobal) + include Printable.Either (struct include Printable.Either (VMutex) (VMutexInits) let name () = "mutex" end) (VGlobal) let name () = "MutexGlobals" let mutex x: t = `Left (`Left x) let mutex_inits: t = `Left (`Right ()) diff --git a/src/analyses/libraryFunctions.ml b/src/analyses/libraryFunctions.ml index e9d361bd01..0da73b2d38 100644 --- a/src/analyses/libraryFunctions.ml +++ b/src/analyses/libraryFunctions.ml @@ -42,6 +42,7 @@ let c_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("getc", unknown [drop "stream" [r_deep; w_deep]]); ("fgets", unknown [drop "str" [w]; drop "count" []; drop "stream" [r_deep; w_deep]]); ("fopen", unknown [drop "pathname" [r]; drop "mode" [r]]); + ("freopen", unknown [drop "pathname" [r]; drop "mode" [r]; drop "stream" [r_deep; w_deep]]); ("printf", unknown (drop "format" [r] :: VarArgs (drop' [r]))); ("fprintf", unknown (drop "stream" [r_deep; w_deep] :: drop "format" [r] :: VarArgs (drop' [r]))); ("sprintf", unknown (drop "buffer" [w] :: drop "format" [r] :: VarArgs (drop' [r]))); @@ -110,6 +111,7 @@ let c_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("vprintf", unknown [drop "format" [r]; drop "vlist" [r_deep]]); (* TODO: what to do with a va_list type? is r_deep correct? *) ("vfprintf", unknown [drop "stream" [r_deep; w_deep]; drop "format" [r]; drop "vlist" [r_deep]]); (* TODO: what to do with a va_list type? is r_deep correct? *) ("vsprintf", unknown [drop "buffer" [w]; drop "format" [r]; drop "vlist" [r_deep]]); (* TODO: what to do with a va_list type? is r_deep correct? *) + ("asprintf", unknown (drop "strp" [w] :: drop "format" [r] :: VarArgs (drop' [r_deep]))); (* TODO: glibc section? *) ("vasprintf", unknown [drop "strp" [w]; drop "format" [r]; drop "ap" [r_deep]]); (* TODO: what to do with a va_list type? is r_deep correct? *) ("vsnprintf", unknown [drop "str" [w]; drop "size" []; drop "format" [r]; drop "ap" [r_deep]]); (* TODO: what to do with a va_list type? is r_deep correct? *) ("mktime", unknown [drop "tm" [r;w]]); @@ -246,6 +248,7 @@ let posix_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("ftruncate", unknown [drop "fd" []; drop "length" []]); ("mkfifo", unknown [drop "pathname" [r]; drop "mode" []]); ("alarm", unknown [drop "seconds" []]); + ("pread", unknown [drop "fd" []; drop "buf" [w]; drop "count" []; drop "offset" []]); ("pwrite", unknown [drop "fd" []; drop "buf" [r]; drop "count" []; drop "offset" []]); ("hstrerror", unknown [drop "err" []]); ("inet_ntoa", unknown ~attrs:[ThreadUnsafe] [drop "in" []]); @@ -265,6 +268,9 @@ let posix_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("access", unknown [drop "pathname" [r]; drop "mode" []]); ("ttyname", unknown ~attrs:[ThreadUnsafe] [drop "fd" []]); ("shm_open", unknown [drop "name" [r]; drop "oflag" []; drop "mode" []]); + ("shmget", unknown [drop "key" []; drop "size" []; drop "shmflag" []]); + ("shmat", unknown [drop "shmid" []; drop "shmaddr" []; drop "shmflag" []]) (* TODO: shmaddr? *); + ("shmdt", unknown [drop "shmaddr" []]) (* TODO: shmaddr? *); ("sched_get_priority_max", unknown [drop "policy" []]); ("mprotect", unknown [drop "addr" []; drop "len" []; drop "prot" []]); ("ftime", unknown [drop "tp" [w]]); @@ -334,6 +340,7 @@ let posix_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("execl", unknown (drop "path" [r] :: drop "arg" [r] :: VarArgs (drop' [r]))); ("statvfs", unknown [drop "path" [r]; drop "buf" [w]]); ("readlink", unknown [drop "path" [r]; drop "buf" [w]; drop "bufsz" []]); + ("wcwidth", unknown [drop "c" []]); ("wcswidth", unknown [drop "s" [r]; drop "n" []]); ("link", unknown [drop "oldpath" [r]; drop "newpath" [r]]); ("renameat", unknown [drop "olddirfd" []; drop "oldpath" [r]; drop "newdirfd" []; drop "newpath" [r]]); @@ -364,6 +371,9 @@ let posix_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("sigdelset", unknown [drop "set" [r; w]; drop "signum" []]); ("sigismember", unknown [drop "set" [r]; drop "signum" []]); ("sigprocmask", unknown [drop "how" []; drop "set" [r]; drop "oldset" [w]]); + ("sigwait", unknown [drop "set" [r]; drop "sig" [w]]); + ("sigwaitinfo", unknown [drop "set" [r]; drop "info" [w]]); + ("sigtimedwait", unknown [drop "set" [r]; drop "info" [w]; drop "timeout" [r]]); ("fork", unknown []); ("dlopen", unknown [drop "filename" [r]; drop "flag" []]); ("dlerror", unknown ~attrs:[ThreadUnsafe] []); @@ -384,7 +394,15 @@ let posix_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("unlink", unknown [drop "pathname" [r]]); ("popen", unknown [drop "command" [r]; drop "type" [r]]); ("stat", unknown [drop "pathname" [r]; drop "statbuf" [w]]); - ("statfs", unknown [drop "path" [r]; drop "buf" [w]]); + ("fsync", unknown [drop "fd" []]); + ("fdatasync", unknown [drop "fd" []]); + ("getrusage", unknown [drop "who" []; drop "usage" [w]]); + ("alphasort", unknown [drop "a" [r]; drop "b" [r]]); + ("gmtime_r", unknown [drop "timer" [r]; drop "result" [w]]); + ("rand_r", special [drop "seedp" [r; w]] Rand); + ("srandom", unknown [drop "seed" []]); + ("random", special [] Rand); + ("posix_memalign", unknown [drop "memptr" [w]; drop "alignment" []; drop "size" []]); (* TODO: Malloc *) ] (** Pthread functions. *) @@ -393,6 +411,7 @@ let pthread_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("pthread_exit", special [__ "retval" []] @@ fun retval -> ThreadExit { ret_val = retval }); (* Doesn't dereference the void* itself, but just passes to pthread_join. *) ("pthread_join", special [__ "thread" []; __ "retval" [w]] @@ fun thread retval -> ThreadJoin {thread; ret_var = retval}); ("pthread_kill", unknown [drop "thread" []; drop "sig" []]); + ("pthread_equal", unknown [drop "t1" []; drop "t2" []]); ("pthread_cond_init", unknown [drop "cond" [w]; drop "attr" [r]]); ("__pthread_cond_init", unknown [drop "cond" [w]; drop "attr" [r]]); ("pthread_cond_signal", special [__ "cond" []] @@ fun cond -> Signal cond); @@ -414,6 +433,10 @@ let pthread_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("pthread_mutex_unlock", special [__ "mutex" []] @@ fun mutex -> Unlock mutex); ("__pthread_mutex_unlock", special [__ "mutex" []] @@ fun mutex -> Unlock mutex); ("pthread_mutexattr_init", unknown [drop "attr" [w]]); + ("pthread_mutexattr_getpshared", unknown [drop "attr" [r]; drop "pshared" [w]]); + ("pthread_mutexattr_setpshared", unknown [drop "attr" [w]; drop "pshared" []]); + ("pthread_mutexattr_getrobust", unknown [drop "attr" [r]; drop "pshared" [w]]); + ("pthread_mutexattr_setrobust", unknown [drop "attr" [w]; drop "pshared" []]); ("pthread_mutexattr_destroy", unknown [drop "attr" [f]]); ("pthread_rwlock_init", unknown [drop "rwlock" [w]; drop "attr" [r]]); ("pthread_rwlock_destroy", unknown [drop "rwlock" [f]]); @@ -444,6 +467,8 @@ let pthread_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("pthread_key_create", unknown [drop "key" [w]; drop "destructor" [s]]); ("pthread_key_delete", unknown [drop "key" [f]]); ("pthread_cancel", unknown [drop "thread" []]); + ("pthread_testcancel", unknown []); + ("pthread_setcancelstate", unknown [drop "state" []; drop "oldstate" [w]]); ("pthread_setcanceltype", unknown [drop "type" []; drop "oldtype" [w]]); ("pthread_detach", unknown [drop "thread" []]); ("pthread_attr_setschedpolicy", unknown [drop "attr" [r; w]; drop "policy" []]); @@ -516,6 +541,12 @@ let gcc_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("__atomic_clear", unknown [drop "ptr" [w]; drop "memorder" []]); ("__atomic_compare_exchange_n", unknown [drop "ptr" [r; w]; drop "expected" [r; w]; drop "desired" []; drop "weak" []; drop "success_memorder" []; drop "failure_memorder" []]); ("__atomic_compare_exchange", unknown [drop "ptr" [r; w]; drop "expected" [r; w]; drop "desired" [r]; drop "weak" []; drop "success_memorder" []; drop "failure_memorder" []]); + ("__atomic_add_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); + ("__atomic_sub_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); + ("__atomic_and_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); + ("__atomic_xor_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); + ("__atomic_or_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); + ("__atomic_nand_fetch", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); ("__atomic_fetch_add", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); ("__atomic_fetch_sub", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); ("__atomic_fetch_and", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); @@ -524,6 +555,7 @@ let gcc_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("__atomic_fetch_nand", unknown [drop "ptr" [r; w]; drop "val" []; drop "memorder" []]); ("__atomic_test_and_set", unknown [drop "ptr" [r; w]; drop "memorder" []]); ("__atomic_thread_fence", unknown [drop "memorder" []]); + ("__sync_bool_compare_and_swap", unknown [drop "ptr" [r; w]; drop "oldval" []; drop "newval" []]); ("__sync_fetch_and_add", unknown (drop "ptr" [r; w] :: drop "value" [] :: VarArgs (drop' []))); ("__sync_fetch_and_sub", unknown (drop "ptr" [r; w] :: drop "value" [] :: VarArgs (drop' []))); ("__builtin_va_copy", unknown [drop "dest" [w]; drop "src" [r]]); @@ -534,7 +566,8 @@ let gcc_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ let glibc_desc_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("fputs_unlocked", unknown [drop "s" [r]; drop "stream" [w]]); ("futimesat", unknown [drop "dirfd" []; drop "pathname" [r]; drop "times" [r]]); - ("error", unknown ((drop "status" []):: (drop "errnum" []) :: (drop "format" [r]) :: (VarArgs (drop' [r])))); + ("error", unknown ((drop "status" []) :: (drop "errnum" []) :: (drop "format" [r]) :: (VarArgs (drop' [r])))); + ("warn", unknown (drop "format" [r] :: VarArgs (drop' [r]))); ("gettext", unknown [drop "msgid" [r]]); ("euidaccess", unknown [drop "pathname" [r]; drop "mode" []]); ("rpmatch", unknown [drop "response" [r]]); @@ -579,6 +612,7 @@ let glibc_desc_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("atoq", unknown [drop "nptr" [r]]); ("strchrnul", unknown [drop "s" [r]; drop "c" []]); ("getdtablesize", unknown []); + ("daemon", unknown [drop "nochdir" []; drop "noclose" []]); ] let linux_userspace_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ @@ -595,6 +629,8 @@ let linux_userspace_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("__xpg_basename", unknown [drop "path" [r]]); ("ptrace", unknown (drop "request" [] :: VarArgs (drop' [r_deep; w_deep]))); (* man page has 4 arguments, but header has varargs and real-world programs may call with <4 *) ("madvise", unknown [drop "addr" []; drop "length" []; drop "advice" []]); + ("mremap", unknown (drop "old_address" [] :: drop "old_size" [] :: drop "new_size" [] :: drop "flags" [] :: VarArgs (drop "new_address" []))); + ("msync", unknown [drop "addr" []; drop "len" []; drop "flags" []]); ("inotify_init1", unknown [drop "flags" []]); ("inotify_add_watch", unknown [drop "fd" []; drop "pathname" [r]; drop "mask" []]); ("inotify_rm_watch", unknown [drop "fd" []; drop "wd" []]); @@ -604,6 +640,10 @@ let linux_userspace_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("mount", unknown [drop "source" [r]; drop "target" [r]; drop "filesystemtype" [r]; drop "mountflags" []; drop "data" [r]]); ("umount", unknown [drop "target" [r]]); ("umount2", unknown [drop "target" [r]; drop "flags" []]); + ("statfs", unknown [drop "path" [r]; drop "buf" [w]]); + ("fstatfs", unknown [drop "fd" []; drop "buf" [w]]); + ("cfmakeraw", unknown [drop "termios" [r; w]]); + ("process_vm_readv", unknown [drop "pid" []; drop "local_iov" [w_deep]; drop "liovcnt" []; drop "remote_iov" []; drop "riovcnt" []; drop "flags" []]); ] let big_kernel_lock = AddrOf (Cil.var (Cilfacade.create_var (makeGlobalVar "[big kernel lock]" intType))) @@ -991,6 +1031,11 @@ let zlib_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ ("deflateInit2_", unknown [drop "strm" [r_deep; w_deep]; drop "level" []; drop "method" []; drop "windowBits" []; drop "memLevel" []; drop "strategy" []; drop "version" [r]; drop "stream_size" []]); ("deflateEnd", unknown [drop "strm" [f_deep]]); ("zlibVersion", unknown []); + ("zError", unknown [drop "err" []]); + ("gzopen", unknown [drop "path" [r]; drop "mode" [r]]); + ("gzdopen", unknown [drop "fd" []; drop "mode" [r]]); + ("gzread", unknown [drop "file" [r_deep; w_deep]; drop "buf" [w]; drop "len" []]); + ("gzclose", unknown [drop "file" [f_deep]]); ] let liblzma_descs_list: (string * LibraryDesc.t) list = LibraryDsl.[ @@ -1188,7 +1233,6 @@ let invalidate_actions = [ "ioctl", writesAll;(*unsafe*) "fstat__extinline", writesAll;(*unsafe*) "scandir", writes [1;3;4];(*keep [1;3;4]*) - "sigwait", writesAllButFirst 1 readsAll;(*drop 1*) "bindtextdomain", readsAll;(*safe*) "textdomain", readsAll;(*safe*) "dcgettext", readsAll;(*safe*) diff --git a/src/autoTune.ml b/src/autoTune.ml index 9e89a18045..3a2f317d2a 100644 --- a/src/autoTune.ml +++ b/src/autoTune.ml @@ -218,6 +218,7 @@ let focusOnMemSafetySpecification () = enableAnalyses uafAna | ValidDeref -> (* Enable the memOutOfBounds analysis *) let memOobAna = ["memOutOfBounds"] in + set_bool "ana.arrayoob" true; print_endline "Setting \"cil.addNestedScopeAttr\" to true"; set_bool "cil.addNestedScopeAttr" true; print_endline @@ "Specification: ValidDeref -> enabling memOutOfBounds analysis \"" ^ (String.concat ", " memOobAna) ^ "\""; @@ -232,6 +233,7 @@ let focusOnMemSafetySpecification () = print_endline @@ "Specification: ValidMemtrack and ValidMemcleanup -> enabling memLeak analysis \"" ^ (String.concat ", " memLeakAna) ^ "\""; enableAnalyses memLeakAna | MemorySafety -> (* TODO: This is a temporary solution for the memory safety category *) + set_bool "ana.arrayoob" true; (print_endline "Setting \"cil.addNestedScopeAttr\" to true"; set_bool "cil.addNestedScopeAttr" true; if (get_int "ana.malloc.unique_address_count") < 1 then ( diff --git a/src/cdomains/intDomain.ml b/src/cdomains/intDomain.ml index 748df62300..3bc84ae676 100644 --- a/src/cdomains/intDomain.ml +++ b/src/cdomains/intDomain.ml @@ -3274,6 +3274,7 @@ struct let invariant_ikind e ik x = match x with + | x when is_top x -> Invariant.top () | Some (c, m) when m =: Ints_t.zero -> if get_bool "witness.invariant.exact" then let c = Ints_t.to_bigint c in diff --git a/src/common/domains/lattice.ml b/src/common/domains/lattice.ml index 79455aea62..51306d637f 100644 --- a/src/common/domains/lattice.ml +++ b/src/common/domains/lattice.ml @@ -151,10 +151,15 @@ end module HConsed (Base:S) = struct include Printable.HConsed (Base) + + (* We do refine int values on narrow and meet {!IntDomain.IntDomTupleImpl}, which can lead to fixpoint issues if we assume x op x = x *) + (* see https://github.com/goblint/analyzer/issues/1005 *) + let int_refine_active = GobConfig.get_string "ana.int.refinement" <> "never" + let lift_f2 f x y = f (unlift x) (unlift y) - let narrow x y = if x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.narrow x y) + let narrow x y = if (not int_refine_active) && x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.narrow x y) let widen x y = if x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.widen x y) - let meet x y = if x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.meet x y) + let meet x y = if (not int_refine_active) && x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.meet x y) let join x y = if x.BatHashcons.tag == y.BatHashcons.tag then x else lift (lift_f2 Base.join x y) let leq x y = (x.BatHashcons.tag == y.BatHashcons.tag) || lift_f2 Base.leq x y let is_top = lift_f Base.is_top diff --git a/src/common/util/options.schema.json b/src/common/util/options.schema.json index e8510e86f3..ac71f46cc8 100644 --- a/src/common/util/options.schema.json +++ b/src/common/util/options.schema.json @@ -544,7 +544,7 @@ "type": "array", "items": { "type": "string" }, "default": [ - "congruence", "singleThreaded", "specification", "mallocWrappers", "noRecursiveIntervals", "enums", "loopUnrollHeuristic", "arrayDomain", "octagon", "wideningThresholds" + "congruence", "singleThreaded", "specification", "mallocWrappers", "noRecursiveIntervals", "enums", "loopUnrollHeuristic", "arrayDomain", "octagon", "wideningThresholds", "memsafetySpecification" ] } }, diff --git a/src/framework/constraints.ml b/src/framework/constraints.ml index ad35ef2633..963e6e4996 100644 --- a/src/framework/constraints.ml +++ b/src/framework/constraints.ml @@ -1467,6 +1467,7 @@ struct module V = struct include Printable.Either (S.V) (Printable.Either (Printable.Prod (Node) (C)) (Printable.Prod (CilType.Fundec) (C))) + let name () = "longjmp" let s x = `Left x let longjmpto x = `Right (`Left x) let longjmpret x = `Right (`Right x) @@ -1663,7 +1664,8 @@ struct if M.tracing then Messages.tracel "longjmp" "Jumping to %a\n" JmpBufDomain.JmpBufSet.pretty targets; let handle_target target = match target with | JmpBufDomain.BufferEntryOrTop.AllTargets -> - M.warn ~category:Imprecise "Longjmp to potentially invalid target, as contents of buffer %a may be unknown! (imprecision due to heap?)" d_exp env + M.warn ~category:Imprecise "Longjmp to potentially invalid target, as contents of buffer %a may be unknown! (imprecision due to heap?)" d_exp env; + M.msg_final Error ~category:Unsound ~tags:[Category Imprecise; Category Call] "Longjmp to unknown target ignored" | Target (target_node, target_context) -> let target_fundec = Node.find_fundec target_node in if CilType.Fundec.equal target_fundec current_fundec && ControlSpecC.equal target_context (ctx.control_context ()) then ( diff --git a/src/maingoblint.ml b/src/maingoblint.ml index d187fc70f0..2721080752 100644 --- a/src/maingoblint.ml +++ b/src/maingoblint.ml @@ -191,7 +191,7 @@ let handle_options () = check_arguments (); AfterConfig.run (); Sys.set_signal (GobSys.signal_of_string (get_string "dbg.solver-signal")) Signal_ignore; (* Ignore solver-signal before solving (e.g. MyCFG), otherwise exceptions self-signal the default, which crashes instead of printing backtrace. *) - if AutoTune.isActivated "specification" && get_string "ana.specification" <> "" then + if AutoTune.isActivated "memsafetySpecification" && get_string "ana.specification" <> "" then AutoTune.focusOnMemSafetySpecification (); Cilfacade.init_options (); handle_flags () diff --git a/src/witness/svcompSpec.ml b/src/witness/svcompSpec.ml index e51e691154..b2799db2df 100644 --- a/src/witness/svcompSpec.ml +++ b/src/witness/svcompSpec.ml @@ -68,12 +68,12 @@ let of_option () = of_string s let to_string spec = - let module Prop = struct + let module Prop = struct type prop = F | G let string_of_prop = function | F -> "F" | G -> "G" - end + end in let open Prop in let print_output prop spec_str is_neg = diff --git a/tests/regression/03-practical/32-smtprc-tid.c b/tests/regression/03-practical/32-smtprc-tid.c new file mode 100644 index 0000000000..1d4810ee2e --- /dev/null +++ b/tests/regression/03-practical/32-smtprc-tid.c @@ -0,0 +1,38 @@ +#include +#include + +int threads_total = 4; +pthread_t *tids; + +void *cleaner(void *arg) { + while (1) { + for (int i = 0; i < threads_total; i++) { + if (tids[i]) { // RACE! + if (!pthread_join(tids[i], NULL)) // RACE! + tids[i] = 0; // RACE! + } + } + } + return NULL; +} + +void *thread(int i) { // wrong argument type is important + tids[i] = pthread_self(); // RACE! + return NULL; +} + +int main() { + pthread_t tid; + tids = malloc(threads_total * sizeof(pthread_t)); + + for(int i = 0; i < threads_total; i++) + tids[i] = 0; + + pthread_create(&tid, NULL, cleaner, NULL); + + for(int i = 0; i < threads_total; i++) { + pthread_create(&tid, NULL, thread, (int *)i); // cast is important + } + + return 0; +} diff --git a/tests/regression/10-synch/20-race-2_1-container_of.c b/tests/regression/10-synch/20-race-2_1-container_of.c index 6083cf4ca0..04d5facbb7 100644 --- a/tests/regression/10-synch/20-race-2_1-container_of.c +++ b/tests/regression/10-synch/20-race-2_1-container_of.c @@ -1,4 +1,4 @@ -// PARAM: --set ana.activated[+] thread --set ana.path_sens[+] threadflag +// PARAM: --set ana.activated[+] thread --set ana.path_sens[+] threadflag --enable ana.sv-comp.functions #include #include #include diff --git a/tests/regression/38-int-refinements/06-narrow.c b/tests/regression/38-int-refinements/06-narrow.c new file mode 100644 index 0000000000..513e9dde60 --- /dev/null +++ b/tests/regression/38-int-refinements/06-narrow.c @@ -0,0 +1,18 @@ +// PARAM: --set ana.int.refinement fixpoint --enable ana.int.interval +// FIXPOINT +#include + +int g = 0; + +void main() +{ + int i = 0; + while (1) { + i++; + for (int j=0; j < 10; j++) { + if (i > 100) g = 1; + } + if (i>9) i=0; + } + return; +} diff --git a/tests/regression/68-longjmp/56-longjmp-top.c b/tests/regression/68-longjmp/56-longjmp-top.c new file mode 100644 index 0000000000..adb3a47476 --- /dev/null +++ b/tests/regression/68-longjmp/56-longjmp-top.c @@ -0,0 +1,21 @@ +// Extracted from concrat/pigz. +#include +#include +#include + +pthread_key_t buf_key; + +int main() { + jmp_buf buf; + pthread_setspecific(buf_key, &buf); + + if (!setjmp(buf)) { + jmp_buf *buf_ptr; + buf_ptr = pthread_getspecific(buf_key); + longjmp(*buf_ptr, 1); // NO CRASH: problem?! + } + else { + __goblint_check(1); // TODO reachable: https://github.com/goblint/analyzer/pull/1210#discussion_r1350021903 + } + return 0; +}