From: Zhihong Peng <zhihongx.p...@intel.com>

`AddressSanitizer
<https://github.com/google/sanitizers/wiki/AddressSanitizer>` (ASan)
is a widely-used debugging tool to detect memory access errors.
It helps detect issues like use-after-free, various kinds of buffer
overruns in C/C++ programs, and other similar errors, as well as
printing out detailed debug information whenever an error is detected.

DPDK ASan functionality is currently only supported Linux x86_64.
Support other platforms, need to define ASAN_SHADOW_OFFSET value
according to google ASan document, and configure meson
(config/meson.build).

Here is an example of heap-buffer-overflow bug:
        ......
        char *p = rte_zmalloc(NULL, 7, 0);
        p[7] = 'a';
        ......

Here is an example of use-after-free bug:
        ......
        char *p = rte_zmalloc(NULL, 7, 0);
        rte_free(p);
        *p = 'a';
        ......

We can enable ASan by adding below compilation options:
-Dbuildtype=debug -Db_lundef=false -Db_sanitize=address
"-Dbuildtype=debug": This is a non-essential option. When this option
is added, if a memory error occurs, ASan can clearly show where the
code is wrong.
"-Db_lundef=false": When use clang to compile DPDK, this option must
be added.

Signed-off-by: Xueqin Lin <xueqin....@intel.com>
Signed-off-by: Zhihong Peng <zhihongx.p...@intel.com>
---
v7: 1) Split doc and code into two.
    2) Modify asan.rst doc
v8: No change.
v9: 1) Add the check of libasan library.
    2) Add release notes.
---
 config/meson.build                     | 10 +++
 devtools/words-case.txt                |  1 +
 doc/guides/prog_guide/asan.rst         | 97 ++++++++++++++++++++++++++
 doc/guides/prog_guide/index.rst        |  1 +
 doc/guides/rel_notes/release_21_11.rst |  9 +++
 5 files changed, 118 insertions(+)
 create mode 100644 doc/guides/prog_guide/asan.rst

diff --git a/config/meson.build b/config/meson.build
index 4cdf589e20..5170b79fed 100644
--- a/config/meson.build
+++ b/config/meson.build
@@ -411,6 +411,16 @@ if get_option('b_lto')
     endif
 endif
 
+if get_option('b_sanitize') == 'address'
+    if cc.get_id() == 'gcc'
+        asan_dep = cc.find_library('asan', required: true)
+        if (not cc.links('int main(int argc, char *argv[]) { return 0; }',
+                    dependencies: asan_dep))
+            error('broken dependency, "libasan"')
+        endif
+    endif
+endif
+
 if get_option('default_library') == 'both'
     error( '''
  Unsupported value "both" for "default_library" option.
diff --git a/devtools/words-case.txt b/devtools/words-case.txt
index 0bbad48626..ada6910fa0 100644
--- a/devtools/words-case.txt
+++ b/devtools/words-case.txt
@@ -5,6 +5,7 @@ API
 Arm
 armv7
 armv8
+ASan
 BAR
 CRC
 DCB
diff --git a/doc/guides/prog_guide/asan.rst b/doc/guides/prog_guide/asan.rst
new file mode 100644
index 0000000000..627675ef46
--- /dev/null
+++ b/doc/guides/prog_guide/asan.rst
@@ -0,0 +1,97 @@
+.. Copyright (c) <2021>, Intel Corporation
+   All rights reserved.
+
+Memory error detect standard tool - AddressSanitizer(ASan)
+==========================================================
+
+`AddressSanitizer
+<https://github.com/google/sanitizers/wiki/AddressSanitizer>` (ASan)
+is a widely-used debugging tool to detect memory access errors.
+It helps detect issues like use-after-free, various kinds of buffer
+overruns in C/C++ programs, and other similar errors, as well as
+printing out detailed debug information whenever an error is detected.
+
+AddressSanitizer is a part of LLVM (3.1+) and GCC (4.8+).
+
+DPDK ASan functionality is currently only supported Linux x86_64.
+Support other platforms, need to define ASAN_SHADOW_OFFSET value
+according to google ASan document, and configure meson
+(config/meson.build).
+
+Example heap-buffer-overflow error
+----------------------------------
+
+Following error was reported when ASan was enabled::
+
+    Applied 9 bytes of memory, but accessed the 10th byte of memory,
+    so heap-buffer-overflow appeared.
+
+Below code results in this error::
+
+    Add code to helloworld:
+    char *p = rte_zmalloc(NULL, 9, 0);
+    if (!p) {
+        printf("rte_zmalloc error.");
+        return -1;
+    }
+    p[9] = 'a';
+
+The error log::
+
+    ==369953==ERROR: AddressSanitizer: heap-buffer-overflow on address 
0x7fb17f465809 at pc 0x5652e6707b84 bp 0x7ffea70eea20 sp 0x7ffea70eea10 WRITE 
of size 1 at 0x7fb17f465809 thread T0
+    #0 0x5652e6707b83 in main ../examples/helloworld/main.c:47
+    #1 0x7fb94953c0b2 in __libc_start_main 
(/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
+    #2 0x5652e67079bd in _start 
(/home/pzh/asan_test/x86_64-native-linuxapp-gcc/examples/dpdk-helloworld+0x8329bd)
+
+    Address 0x7fb17f465809 is a wild pointer.
+    SUMMARY: AddressSanitizer: heap-buffer-overflow 
../examples/helloworld/main.c:47 in main
+
+Example use-after-free error
+----------------------------
+
+Following error was reported when ASan was enabled::
+
+    Applied for 9 bytes of memory, and accessed the first byte after
+    released, so heap-use-after-free appeared.
+
+Below code results in this error::
+
+    Add code to helloworld:
+    char *p = rte_zmalloc(NULL, 9, 0);
+    if (!p) {
+        printf("rte_zmalloc error.");
+        return -1;
+    }
+    rte_free(p);
+    *p = 'a';
+
+The error log::
+
+    ==417048==ERROR: AddressSanitizer: heap-use-after-free on address 
0x7fc83f465800 at pc 0x564308a39b89 bp 0x7ffc8c85bf50 sp 0x7ffc8c85bf40 WRITE 
of size 1 at 0x7fc83f465800 thread T0
+    #0 0x564308a39b88 in main ../examples/helloworld/main.c:48
+    #1 0x7fd0079c60b2 in __libc_start_main 
(/lib/x86_64-linux-gnu/libc.so.6+0x270b2)
+    #2 0x564308a399bd in _start 
(/home/pzh/asan_test/x86_64-native-linuxapp-gcc/examples/dpdk-helloworld+0x8329bd)
+
+    Address 0x7fc83f465800 is a wild pointer.
+    SUMMARY: AddressSanitizer: heap-use-after-free 
../examples/helloworld/main.c:48 in main
+
+Usage
+-----
+
+meson build
+^^^^^^^^^^^
+
+To enable ASan in meson build system, use following meson build command:
+
+Example usage::
+
+ meson build -Dbuildtype=debug -Db_lundef=false -Db_sanitize=address
+ ninja -C build
+
+.. Note::
+
+  a) Some of the features of ASan (for example, 'Display memory application 
location, currently
+     displayed as a wild pointer') are not currently supported by DPDK's 
implementation.
+  b) DPDK test has been completed in ubuntu18.04/ubuntu20.04/redhat8.3. To 
compile with gcc in
+     centos, libasan needs to be installed separately.
+  c) If the program uses cmdline, when a memory bug occurs, need to execute 
the "stty echo" command.
diff --git a/doc/guides/prog_guide/index.rst b/doc/guides/prog_guide/index.rst
index 2dce507f46..df8a4b93e1 100644
--- a/doc/guides/prog_guide/index.rst
+++ b/doc/guides/prog_guide/index.rst
@@ -71,3 +71,4 @@ Programmer's Guide
     lto
     profile_app
     glossary
+    asan
diff --git a/doc/guides/rel_notes/release_21_11.rst 
b/doc/guides/rel_notes/release_21_11.rst
index 5036641842..58c6377148 100644
--- a/doc/guides/rel_notes/release_21_11.rst
+++ b/doc/guides/rel_notes/release_21_11.rst
@@ -141,6 +141,15 @@ New Features
   * Added tests to validate packets hard expiry.
   * Added tests to verify tunnel header verification in IPsec inbound.
 
+* **Enable ASan for memory detector on DPDK.**
+
+  `AddressSanitizer
+  <https://github.com/google/sanitizers/wiki/AddressSanitizer>` (ASan)
+  is a widely-used debugging tool to detect memory access errors.
+  It helps detect issues like use-after-free, various kinds of buffer
+  overruns in C/C++ programs, and other similar errors, as well as
+  printing out detailed debug information whenever an error is detected.
+
 
 Removed Items
 -------------
-- 
2.25.1

Reply via email to