/* * netsniff-ng - the packet sniffing beast * By Daniel Borkmann * Copyright 2012 Daniel Borkmann , * Swiss federal institute of technology (ETH Zurich) * Subject to the GPL, version 2. */ /* lex-func-prefix: yy */ %{ #include #include #include #include #include #include "trafgen_parser.tab.h" #include "xmalloc.h" #include "built_in.h" extern void yyerror(const char *); static char *try_convert_shellcode(char *sstr) { bool found_any = false; char *bstr, *ostr = sstr, *hay, *orig = sstr; size_t j = 0, blen, slen = strlen(sstr), tot = 0; const char *needle = "\\x"; sstr++; slen -= 2; if (slen % 4 != 0) return orig; blen = slen / 4; hay = sstr; while ((hay = strstr(hay, needle)) != NULL ) { hay += strlen(needle) + 2; found_any = true; tot++; } if (blen != tot || !found_any) return orig; blen += 2; bstr = xzmalloc(blen); bstr[j++] = '\"'; while (j < blen - 1) bstr[j++] = (uint8_t) strtoul(sstr + 2, &sstr, 16); bstr[j++] = '\"'; xfree(ostr); return bstr; } %} %option align %option nounput %option noyywrap %option noreject %option 8bit %option caseless %option noinput %option nodefault number_oct ([0][0-9]+) number_hex ([0]?[x][a-fA-F0-9]+) number_bin ([0]?[b][0-1]+) number_dec (([0])|([1-9][0-9]*)) number_ascii ([a-zA-Z]) %% "cpu" { return K_CPU; } "fill" { return K_FILL; } "rnd" { return K_RND; } "csum16" { return K_CSUMIP; } "csumip" { return K_CSUMIP; } "csumip4" { return K_CSUMIP; } "csumicmp" { return K_CSUMIP; } "csumicmp4" { return K_CSUMIP; } "csumudp" { return K_CSUMUDP; } "csumtcp" { return K_CSUMTCP; } "drnd" { return K_DRND; } "dinc" { return K_DINC; } "ddec" { return K_DDEC; } "seqinc" { return K_SEQINC; } "seqdec" { return K_SEQDEC; } "const8"|"c8" { return K_CONST8; } "const16"|"c16" { return K_CONST16; } "const32"|"c32" { return K_CONST32; } "const64"|"c64" { return K_CONST64; } [ ]*"-"[ ]* { return '-'; } [ ]*"+"[ ]* { return '+'; } [ ]*"*"[ ]* { return '*'; } [ ]*"/"[ ]* { return '/'; } [ ]*"%"[ ]* { return '%'; } [ ]*"&"[ ]* { return '&'; } [ ]*"|"[ ]* { return '|'; } [ ]*"<"[ ]* { return '<'; } [ ]*">"[ ]* { return '>'; } [ ]*"^"[ ]* { return '^'; } "{" { return '{'; } "}" { return '}'; } "(" { return '('; } ")" { return ')'; } "[" { return '['; } "]" { return ']'; } "," { return ','; } ":" { return ':'; } "\n" { yylineno++; } "\""[^\"]+"\"" { yylval.str = try_convert_shellcode(xstrdup(yytext)); return string; } ([ \t\n]+)? { return K_WHITE; } "/*"([^\*]|\*[^/])*"*/" { return K_COMMENT; } "#"[^\n]* { return K_COMMENT; } {number_hex} { yylval.number = strtoul(yytext + (yytext[0] == 'x' ? 1 : 0), NULL, 16); return number; } {number_dec} { yylval.number = strtol(yytext, NULL, 10); return number; } {number_oct} { yylval.number = strtol(yytext + 1, NULL, 8); return number; } {number_bin} { yylval.number = strtol(yytext + (yytext[0] == 'b' ? 1 : 2), NULL, 2); return number; } {number_ascii} { yylval.number = (uint8_t) (*yytext); return number; } "'\\x"[a-fA-F0-9]{2}"'" { yylval.number = strtol(yytext + 3, NULL, 16); return number; } "'"."'" { yylval.number = (uint8_t) (*(yytext + 1)); return number; } ";"[^\n]* {/* NOP */} . { printf("Unknown character '%s'", yytext); yyerror("lex Unknown character"); } %% 9e0144dc3341'>mip6.h
diff options
context:
space:
mode:
authorDouglas Miller <dougmill@linux.vnet.ibm.com>2017-01-28 06:42:20 -0600
committerTejun Heo <tj@kernel.org>2017-01-28 07:49:42 -0500
commit966d2b04e070bc040319aaebfec09e0144dc3341 (patch)
tree4b96156e3d1dd4dfd6039b7c219c9dc4616da52d /include/net/mip6.h
parent1b1bc42c1692e9b62756323c675a44cb1a1f9dbd (diff)
percpu-refcount: fix reference leak during percpu-atomic transition
percpu_ref_tryget() and percpu_ref_tryget_live() should return "true" IFF they acquire a reference. But the return value from atomic_long_inc_not_zero() is a long and may have high bits set, e.g. PERCPU_COUNT_BIAS, and the return value of the tryget routines is bool so the reference may actually be acquired but the routines return "false" which results in a reference leak since the caller assumes it does not need to do a corresponding percpu_ref_put(). This was seen when performing CPU hotplug during I/O, as hangs in blk_mq_freeze_queue_wait where percpu_ref_kill (blk_mq_freeze_queue_start) raced with percpu_ref_tryget (blk_mq_timeout_work). Sample stack trace: __switch_to+0x2c0/0x450 __schedule+0x2f8/0x970 schedule+0x48/0xc0 blk_mq_freeze_queue_wait+0x94/0x120 blk_mq_queue_reinit_work+0xb8/0x180 blk_mq_queue_reinit_prepare+0x84/0xa0 cpuhp_invoke_callback+0x17c/0x600 cpuhp_up_callbacks+0x58/0x150 _cpu_up+0xf0/0x1c0 do_cpu_up+0x120/0x150 cpu_subsys_online+0x64/0xe0 device_online+0xb4/0x120 online_store+0xb4/0xc0 dev_attr_store+0x68/0xa0 sysfs_kf_write+0x80/0xb0 kernfs_fop_write+0x17c/0x250 __vfs_write+0x6c/0x1e0 vfs_write+0xd0/0x270 SyS_write+0x6c/0x110 system_call+0x38/0xe0 Examination of the queue showed a single reference (no PERCPU_COUNT_BIAS, and __PERCPU_REF_DEAD, __PERCPU_REF_ATOMIC set) and no requests. However, conditions at the time of the race are count of PERCPU_COUNT_BIAS + 0 and __PERCPU_REF_DEAD and __PERCPU_REF_ATOMIC set. The fix is to make the tryget routines use an actual boolean internally instead of the atomic long result truncated to a int. Fixes: e625305b3907 percpu-refcount: make percpu_ref based on longs instead of ints Link: https://bugzilla.kernel.org/show_bug.cgi?id=190751 Signed-off-by: Douglas Miller <dougmill@linux.vnet.ibm.com> Reviewed-by: Jens Axboe <axboe@fb.com> Signed-off-by: Tejun Heo <tj@kernel.org> Fixes: e625305b3907 ("percpu-refcount: make percpu_ref based on longs instead of ints") Cc: stable@vger.kernel.org # v3.18+
Diffstat (limited to 'include/net/mip6.h')