Miscellaneous fixes (#1914)

* Fix multiple memory access errors

Fixes a buffer overflow in get_pid_exe(), a use-after-free error in
bcc_usdt_get_probe_argctype() and a possible NULL pointer dereference
in find_debug_via_debuglink().

* Fix multiple ressource leaks

Leaked file descriptors in bpf_attach_uprobe() and verify_checksum().
Memory leaks in  Parser::func_add() and bcc_procutils_language().

* fixup! Fix multiple ressource leaks
diff --git a/src/cc/bcc_elf.c b/src/cc/bcc_elf.c
index e848912..c425db6 100644
--- a/src/cc/bcc_elf.c
+++ b/src/cc/bcc_elf.c
@@ -377,8 +377,10 @@
   if (fd < 0)
     return 0;
 
-  if (fstat(fd, &st) < 0)
+  if (fstat(fd, &st) < 0) {
+    close(fd);
     return 0;
+  }
 
   buf = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (!buf) {
@@ -433,7 +435,7 @@
 
 DONE:
   free(bindir);
-  if (check_crc && !verify_checksum(res, crc))
+  if (res && check_crc && !verify_checksum(res, crc))
     return NULL;
   return res;
 }
diff --git a/src/cc/bcc_proc.c b/src/cc/bcc_proc.c
index 14ee18e..6fe11a0 100644
--- a/src/cc/bcc_proc.c
+++ b/src/cc/bcc_proc.c
@@ -446,8 +446,10 @@
       while (isspace(mapname[0])) mapname++;
       for (i = 0; i < nb_languages; i++) {
         snprintf(pathname, sizeof(pathname), "/lib%s", languages[i]);
-        if (strstr(mapname, pathname))
+        if (strstr(mapname, pathname)) {
+          fclose(procfile);
           return languages[i];
+	}
         if ((str = strstr(mapname, "libc")) &&
             (str[4] == '-' || str[4] == '.'))
           libc = true;
diff --git a/src/cc/common.cc b/src/cc/common.cc
index 1cfe91a..c8370a3 100644
--- a/src/cc/common.cc
+++ b/src/cc/common.cc
@@ -57,6 +57,8 @@
   res = readlink(exe_link.c_str(), exe_path, sizeof(exe_path));
   if (res == -1)
     return "";
+  if (res >= sizeof(exe_path))
+    res = sizeof(exe_path) - 1;
   exe_path[res] = '\0';
   return std::string(exe_path);
 }
diff --git a/src/cc/frontends/b/parser.cc b/src/cc/frontends/b/parser.cc
index 9e61346..8a5e149 100644
--- a/src/cc/frontends/b/parser.cc
+++ b/src/cc/frontends/b/parser.cc
@@ -199,8 +199,10 @@
   auto cur_scope = scopes_->current_var();
   scopes_->set_current(scope);
   for (auto it = formals->begin(); it != formals->end(); ++it)
-    if (!variable_add(nullptr, it->get()))
+    if (!variable_add(nullptr, it->get())) {
+      delete decl;
       return nullptr;
+    }
   scopes_->set_current(cur_scope);
   decl->scope_ = scope;
   scopes_->top_func()->add(id->name_, decl);
diff --git a/src/cc/libbpf.c b/src/cc/libbpf.c
index c23030e..acfbc5e 100644
--- a/src/cc/libbpf.c
+++ b/src/cc/libbpf.c
@@ -925,6 +925,7 @@
 
   if (setns(fd, CLONE_NEWNS))
     perror("setns");
+  close(fd);
 }
 
 int bpf_attach_uprobe(int progfd, enum bpf_probe_attach_type attach_type,
diff --git a/src/cc/usdt/usdt.cc b/src/cc/usdt/usdt.cc
index 2992593..2010520 100644
--- a/src/cc/usdt/usdt.cc
+++ b/src/cc/usdt/usdt.cc
@@ -478,8 +478,9 @@
   void *ctx, const char* probe_name, const int arg_index
 ) {
   USDT::Probe *p = static_cast<USDT::Context *>(ctx)->get(probe_name);
-  std::string res = p ? p->get_arg_ctype(arg_index) : "";
-  return res.c_str();
+  if (p)
+    return p->get_arg_ctype(arg_index).c_str();
+  return "";
 }
 
 void bcc_usdt_foreach(void *usdt, bcc_usdt_cb callback) {