[PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

STALE5424d

5 messages, 3 authors, 2011-10-19 · open the first message on its own page

[PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

From: Bin Li <hidden>
Date: 2011-10-17 07:35:36

Hi,

The issue is from below link.

https://bugzilla.novell.com/show_bug.cgi?id=719537

The issue is debug at below.

(gdb) bt
#0  0x00007ffff7697945 in raise (sig=<optimized out>)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:64
#1  0x00007ffff7698f21 in abort () at abort.c:92
#2  0x00007ffff76d48ef in __libc_message (do_abort=2,
    fmt=0x7ffff7789541 "*** %s ***: %s terminated\n")
    at ../sysdeps/unix/sysv/linux/libc_fatal.c:186
#3  0x00007ffff7750177 in __fortify_fail (
    msg=0x7ffff77894d8 "buffer overflow detected") at fortify_fail.c:32
#4  0x00007ffff774de10 in __chk_fail () at chk_fail.c:29
#5  0x00007ffff774cf8d in __strncpy_chk (
    s1=0x640c <Address 0x640c out of bounds>,
    s2=0x640c <Address 0x640c out of bounds>, n=6, s1len=18446744073709551615)
    at strncpy_chk.c:34
#6  0x000000000041e9c8 in strncpy (__len=<optimized out>,
    __src=<optimized out>, __dest=<optimized out>)
    at /usr/include/bits/string3.h:123
#7  xfrm_algo_parse (max=<optimized out>, buf=<optimized out>,
    key=<optimized out>, name=<optimized out>, type=<optimized out>,
    alg=<optimized out>) at xfrm_state.c:166

(gdb) l
161                     len = slen;
162                     if (len > 0) {
163                             if (len > max)
164                                     invarg("\"ALGOKEY\" makes buffer
overflow\n", key);
165
166                             strncpy(buf, key, len);
167                     }
168             }
169
170             alg->alg_key_len = len * 8;
(gdb) up
#8  xfrm_state_modify (cmd=<optimized out>, flags=<optimized out>, argc=1,
    argv=0x7fffffffe370) at xfrm_state.c:406
406                                     xfrm_algo_parse((void *)&alg, type,
name, key,

the compiler passes zero to __builtin___strncpy_chk as the buffer size.
xfrm_algo_parse is inlined into xfrm_state_modify.


Thanks!

Sincerely Yours,

Bin Li

http://zh.opensuse.org

Re: [PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

From: Stephen Hemminger <hidden>
Date: 2011-10-17 15:23:10

On Mon, 17 Oct 2011 15:35:35 +0800
Bin Li [off-list ref] wrote:
(gdb) l
161                     len = slen;
162                     if (len > 0) {
163                             if (len > max)
164                                     invarg("\"ALGOKEY\" makes buffer
overflow\n", key);
165
166                             strncpy(buf, key, len);
167                     }
168             }
169
170             alg->alg_key_len = len * 8;
(gdb) up
#8  xfrm_state_modify (cmd=<optimized out>, flags=<optimized out>, argc=1,
    argv=0x7fffffffe370) at xfrm_state.c:406
406                                     xfrm_algo_parse((void *)&alg, type,
name, key,

the compiler passes zero to __builtin___strncpy_chk as the buffer size.
xfrm_algo_parse is inlined into xfrm_state_modify.
I don't understand, looks like a compiler bug. Call strncpy with
0 length should not be possible since the check was  3 lines
before for len > 0.

Re: [PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

From: Bin Li <hidden>
Date: 2011-10-19 09:15:27

Stephen,

 You can reproduce this issue in 2.6.37 like below. And the previous
gdb log is after the install the debuginfo package in SUSE.

# ip -6 xfrm state add src 3ffe:501:ffff:ff03:21a:64ff:fe12:e4c1 dst
3ffe:501:ffff:ff05:200:ff:fe00:c1c1 proto ah spi 0x1000 mode transport
auth md5 "TAHITEST89ABCDEF"

*** buffer overflow detected ***: ip terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x40)[0xb76d0070]
/lib/libc.so.6(+0xe8e27)[0xb76cde27]
/lib/libc.so.6(+0xe8317)[0xb76cd317]
ip[0x806d6c4]
ip(do_xfrm_state+0x120)[0x806dc70]
ip(do_xfrm+0x81)[0x806ad51]
ip[0x804c355]
ip(main+0x476)[0x804caa6]
/lib/libc.so.6(__libc_start_main+0xfe)[0xb75fbc2e]
ip[0x804c261]
======= Memory map: ========
08048000-08087000 r-xp 00000000 08:01 4465       /sbin/ip
08087000-08088000 r--p 0003e000 08:01 4465       /sbin/ip
08088000-0808a000 rw-p 0003f000 08:01 4465       /sbin/ip
0808a000-080ad000 rw-p 00000000 00:00 0          [heap]
b75c6000-b75e2000 r-xp 00000000 08:01 131084     /lib/libgcc_s.so.1
b75e2000-b75e3000 r--p 0001b000 08:01 131084     /lib/libgcc_s.so.1
b75e3000-b75e4000 rw-p 0001c000 08:01 131084     /lib/libgcc_s.so.1
b75e4000-b75e5000 rw-p 00000000 00:00 0
b75e5000-b774b000 r-xp 00000000 08:01 131375     /lib/libc-2.11.3.so
b774b000-b774c000 ---p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774c000-b774e000 r--p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774e000-b774f000 rw-p 00168000 08:01 131375     /lib/libc-2.11.3.so
b774f000-b7752000 rw-p 00000000 00:00 0
b7752000-b7755000 r-xp 00000000 08:01 131428     /lib/libdl-2.11.3.so
b7755000-b7756000 r--p 00002000 08:01 131428     /lib/libdl-2.11.3.so
b7756000-b7757000 rw-p 00003000 08:01 131428     /lib/libdl-2.11.3.so
b7774000-b7775000 rw-p 00000000 00:00 0
b7775000-b7794000 r-xp 00000000 08:01 154467     /lib/ld-2.11.3.so
b7794000-b7795000 r--p 0001e000 08:01 154467     /lib/ld-2.11.3.so
b7795000-b7796000 rw-p 0001f000 08:01 154467     /lib/ld-2.11.3.so
bfa02000-bfa23000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Aborted

And If without -D_FORTIFY_SOURCE=2 in gcc, it works fine, so It's a
bug in iproute2 which is not conforming to -D_FORTIFY_SOURCE=2
restrictions.

Thanks!

On Mon, Oct 17, 2011 at 11:23 PM, Stephen Hemminger
[off-list ref] wrote:
On Mon, 17 Oct 2011 15:35:35 +0800
Bin Li [off-list ref] wrote:
quoted
(gdb) l
161                     len = slen;
162                     if (len > 0) {
163                             if (len > max)
164                                     invarg("\"ALGOKEY\" makes buffer
overflow\n", key);
165
166                             strncpy(buf, key, len);
167                     }
168             }
169
170             alg->alg_key_len = len * 8;
(gdb) up
#8  xfrm_state_modify (cmd=<optimized out>, flags=<optimized out>, argc=1,
    argv=0x7fffffffe370) at xfrm_state.c:406
406                                     xfrm_algo_parse((void *)&alg, type,
name, key,

the compiler passes zero to __builtin___strncpy_chk as the buffer size.
xfrm_algo_parse is inlined into xfrm_state_modify.
I don't understand, looks like a compiler bug. Call strncpy with
0 length should not be possible since the check was  3 lines
before for len > 0.

Re: [PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

From: Eric Dumazet <hidden>
Date: 2011-10-19 11:30:56

Le mercredi 19 octobre 2011 à 17:15 +0800, Bin Li a écrit :
Stephen,

 You can reproduce this issue in 2.6.37 like below. And the previous
gdb log is after the install the debuginfo package in SUSE.

# ip -6 xfrm state add src 3ffe:501:ffff:ff03:21a:64ff:fe12:e4c1 dst
3ffe:501:ffff:ff05:200:ff:fe00:c1c1 proto ah spi 0x1000 mode transport
auth md5 "TAHITEST89ABCDEF"

*** buffer overflow detected ***: ip terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x40)[0xb76d0070]
/lib/libc.so.6(+0xe8e27)[0xb76cde27]
/lib/libc.so.6(+0xe8317)[0xb76cd317]
ip[0x806d6c4]
ip(do_xfrm_state+0x120)[0x806dc70]
ip(do_xfrm+0x81)[0x806ad51]
ip[0x804c355]
ip(main+0x476)[0x804caa6]
/lib/libc.so.6(__libc_start_main+0xfe)[0xb75fbc2e]
ip[0x804c261]
======= Memory map: ========
08048000-08087000 r-xp 00000000 08:01 4465       /sbin/ip
08087000-08088000 r--p 0003e000 08:01 4465       /sbin/ip
08088000-0808a000 rw-p 0003f000 08:01 4465       /sbin/ip
0808a000-080ad000 rw-p 00000000 00:00 0          [heap]
b75c6000-b75e2000 r-xp 00000000 08:01 131084     /lib/libgcc_s.so.1
b75e2000-b75e3000 r--p 0001b000 08:01 131084     /lib/libgcc_s.so.1
b75e3000-b75e4000 rw-p 0001c000 08:01 131084     /lib/libgcc_s.so.1
b75e4000-b75e5000 rw-p 00000000 00:00 0
b75e5000-b774b000 r-xp 00000000 08:01 131375     /lib/libc-2.11.3.so
b774b000-b774c000 ---p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774c000-b774e000 r--p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774e000-b774f000 rw-p 00168000 08:01 131375     /lib/libc-2.11.3.so
b774f000-b7752000 rw-p 00000000 00:00 0
b7752000-b7755000 r-xp 00000000 08:01 131428     /lib/libdl-2.11.3.so
b7755000-b7756000 r--p 00002000 08:01 131428     /lib/libdl-2.11.3.so
b7756000-b7757000 rw-p 00003000 08:01 131428     /lib/libdl-2.11.3.so
b7774000-b7775000 rw-p 00000000 00:00 0
b7775000-b7794000 r-xp 00000000 08:01 154467     /lib/ld-2.11.3.so
b7794000-b7795000 r--p 0001e000 08:01 154467     /lib/ld-2.11.3.so
b7795000-b7796000 rw-p 0001f000 08:01 154467     /lib/ld-2.11.3.so
bfa02000-bfa23000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Aborted

And If without -D_FORTIFY_SOURCE=2 in gcc, it works fine, so It's a
bug in iproute2 which is not conforming to -D_FORTIFY_SOURCE=2
restrictions.
FORTIFY assumes we cant copy a string on alg.u.alg.alg_key !

This completely precludes 0-sized arrays

struct xfrm_algo {
        char            alg_name[64];
        unsigned int    alg_key_len;    /* in bits */
        char            alg_key[0];
};

struct {
      union {
          struct xfrm_algo alg;
          struct xfrm_algo_aead aead;
          struct xfrm_algo_auth auth;
      } u;
      char buf[XFRM_ALGO_KEY_BUF_SIZE];
} alg = {};

I would say its a FORTIFY bug. This kind of construct is perfectly
valid.

Re: [PATCH] iproute2: Conforming to -D_FORTIFY_SOURCE=2 restrictions

From: Stephen Hemminger <hidden>
Date: 2011-10-19 16:50:55

On Wed, 19 Oct 2011 13:30:51 +0200
Eric Dumazet [off-list ref] wrote:
Le mercredi 19 octobre 2011 à 17:15 +0800, Bin Li a écrit :
quoted
Stephen,

 You can reproduce this issue in 2.6.37 like below. And the previous
gdb log is after the install the debuginfo package in SUSE.

# ip -6 xfrm state add src 3ffe:501:ffff:ff03:21a:64ff:fe12:e4c1 dst
3ffe:501:ffff:ff05:200:ff:fe00:c1c1 proto ah spi 0x1000 mode transport
auth md5 "TAHITEST89ABCDEF"

*** buffer overflow detected ***: ip terminated
======= Backtrace: =========
/lib/libc.so.6(__fortify_fail+0x40)[0xb76d0070]
/lib/libc.so.6(+0xe8e27)[0xb76cde27]
/lib/libc.so.6(+0xe8317)[0xb76cd317]
ip[0x806d6c4]
ip(do_xfrm_state+0x120)[0x806dc70]
ip(do_xfrm+0x81)[0x806ad51]
ip[0x804c355]
ip(main+0x476)[0x804caa6]
/lib/libc.so.6(__libc_start_main+0xfe)[0xb75fbc2e]
ip[0x804c261]
======= Memory map: ========
08048000-08087000 r-xp 00000000 08:01 4465       /sbin/ip
08087000-08088000 r--p 0003e000 08:01 4465       /sbin/ip
08088000-0808a000 rw-p 0003f000 08:01 4465       /sbin/ip
0808a000-080ad000 rw-p 00000000 00:00 0          [heap]
b75c6000-b75e2000 r-xp 00000000 08:01 131084     /lib/libgcc_s.so.1
b75e2000-b75e3000 r--p 0001b000 08:01 131084     /lib/libgcc_s.so.1
b75e3000-b75e4000 rw-p 0001c000 08:01 131084     /lib/libgcc_s.so.1
b75e4000-b75e5000 rw-p 00000000 00:00 0
b75e5000-b774b000 r-xp 00000000 08:01 131375     /lib/libc-2.11.3.so
b774b000-b774c000 ---p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774c000-b774e000 r--p 00166000 08:01 131375     /lib/libc-2.11.3.so
b774e000-b774f000 rw-p 00168000 08:01 131375     /lib/libc-2.11.3.so
b774f000-b7752000 rw-p 00000000 00:00 0
b7752000-b7755000 r-xp 00000000 08:01 131428     /lib/libdl-2.11.3.so
b7755000-b7756000 r--p 00002000 08:01 131428     /lib/libdl-2.11.3.so
b7756000-b7757000 rw-p 00003000 08:01 131428     /lib/libdl-2.11.3.so
b7774000-b7775000 rw-p 00000000 00:00 0
b7775000-b7794000 r-xp 00000000 08:01 154467     /lib/ld-2.11.3.so
b7794000-b7795000 r--p 0001e000 08:01 154467     /lib/ld-2.11.3.so
b7795000-b7796000 rw-p 0001f000 08:01 154467     /lib/ld-2.11.3.so
bfa02000-bfa23000 rw-p 00000000 00:00 0          [stack]
ffffe000-fffff000 r-xp 00000000 00:00 0          [vdso]
Aborted

And If without -D_FORTIFY_SOURCE=2 in gcc, it works fine, so It's a
bug in iproute2 which is not conforming to -D_FORTIFY_SOURCE=2
restrictions.
FORTIFY assumes we cant copy a string on alg.u.alg.alg_key !

This completely precludes 0-sized arrays

struct xfrm_algo {
        char            alg_name[64];
        unsigned int    alg_key_len;    /* in bits */
        char            alg_key[0];
};

struct {
      union {
          struct xfrm_algo alg;
          struct xfrm_algo_aead aead;
          struct xfrm_algo_auth auth;
      } u;
      char buf[XFRM_ALGO_KEY_BUF_SIZE];
} alg = {};

I would say its a FORTIFY bug. This kind of construct is perfectly
valid.
Maybe it will handle flexible style arrays.
See also:
   http://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

At this time, I won't accept the patch that uses alloca() just to deal
with this FORTIFY bug.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help