Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-17 Thread Steven Rostedt
On Tue, 16 Aug 2016 17:20:28 -0700
Kees Cook  wrote:


>  EXPORT_SYMBOL(__list_add_valid);
> @@ -46,26 +41,18 @@ bool __list_del_entry_valid(struct list_head *entry)
>   prev = entry->prev;
>   next = entry->next;
>  
> - if (unlikely(next == LIST_POISON1)) {
> - WARN(1, "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
> - entry, LIST_POISON1);
> - return false;
> - }
> - if (unlikely(prev == LIST_POISON2)) {
> - WARN(1, "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
> - entry, LIST_POISON2);
> - return false;
> - }
> - if (unlikely(prev->next != entry)) {
> - WARN(1, "list_del corruption. prev->next should be %p, but was 
> %p\n",
> - entry, prev->next);
> - return false;
> - }
> - if (unlikely(next->prev != entry)) {
> - WARN(1, "list_del corruption. next->prev should be %p, but was 
> %p\n",
> - entry, next->prev);
> - return false;
> - }
> + CHECK_DATA_CORRUPTION(next == LIST_POISON1,
> + "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
> + entry, LIST_POISON1);
> + CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
> + "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
> + entry, LIST_POISON2);
> + CHECK_DATA_CORRUPTION(prev->next != entry,
> + "list_del corruption. prev->next should be %p, but was %p\n",
> + entry, prev->next);
> + CHECK_DATA_CORRUPTION(next->prev != entry,
> + "list_del corruption. next->prev should be %p, but was %p\n",
> + entry, next->prev);

OK, you totally rewrote the WARN() section anyway, thus ignore my
comment on the previous email.

-- Steve

>   return true;
>  
>  }



Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-17 Thread Steven Rostedt
On Tue, 16 Aug 2016 17:20:28 -0700
Kees Cook  wrote:


>  EXPORT_SYMBOL(__list_add_valid);
> @@ -46,26 +41,18 @@ bool __list_del_entry_valid(struct list_head *entry)
>   prev = entry->prev;
>   next = entry->next;
>  
> - if (unlikely(next == LIST_POISON1)) {
> - WARN(1, "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
> - entry, LIST_POISON1);
> - return false;
> - }
> - if (unlikely(prev == LIST_POISON2)) {
> - WARN(1, "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
> - entry, LIST_POISON2);
> - return false;
> - }
> - if (unlikely(prev->next != entry)) {
> - WARN(1, "list_del corruption. prev->next should be %p, but was 
> %p\n",
> - entry, prev->next);
> - return false;
> - }
> - if (unlikely(next->prev != entry)) {
> - WARN(1, "list_del corruption. next->prev should be %p, but was 
> %p\n",
> - entry, next->prev);
> - return false;
> - }
> + CHECK_DATA_CORRUPTION(next == LIST_POISON1,
> + "list_del corruption, %p->next is LIST_POISON1 (%p)\n",
> + entry, LIST_POISON1);
> + CHECK_DATA_CORRUPTION(prev == LIST_POISON2,
> + "list_del corruption, %p->prev is LIST_POISON2 (%p)\n",
> + entry, LIST_POISON2);
> + CHECK_DATA_CORRUPTION(prev->next != entry,
> + "list_del corruption. prev->next should be %p, but was %p\n",
> + entry, prev->next);
> + CHECK_DATA_CORRUPTION(next->prev != entry,
> + "list_del corruption. next->prev should be %p, but was %p\n",
> + entry, next->prev);

OK, you totally rewrote the WARN() section anyway, thus ignore my
comment on the previous email.

-- Steve

>   return true;
>  
>  }



Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-16 Thread Kees Cook
On Tue, Aug 16, 2016 at 5:26 PM, Joe Perches  wrote:
> On Tue, 2016-08-16 at 17:20 -0700, Kees Cook wrote:
>> The kernel checks for cases of data structure corruption under some
>> CONFIGs (e.g. CONFIG_DEBUG_LIST). When corruption is detected, some
>> systems may want to BUG() immediately instead of letting the system run
>> with known corruption.  Usually these kinds of manipulation primitives can
>> be used by security flaws to gain arbitrary memory write control. This
>> provides a new config CONFIG_BUG_ON_DATA_CORRUPTION and a corresponding
>> macro CHECK_DATA_CORRUPTION for handling these situations. Notably, even
>> if not BUGing, the kernel should not continue processing the corrupted
>> structure.
> []
>> diff --git a/include/linux/bug.h b/include/linux/bug.h
> []
>> @@ -118,4 +118,21 @@ static inline enum bug_trap_type report_bug(unsigned 
>> long bug_addr,
>>  }
>>
>>  #endif   /* CONFIG_GENERIC_BUG */
>> +
>> +/*
>> + * Since detected data corruption should stop operation on the affected
>> + * structures, this returns false if the corruption condition is found.
>> + */
>> +#define CHECK_DATA_CORRUPTION(condition, format...)   \
>
> My preference would be to use (condition, fmt, ...)
>
>> + do { \
>> + if (unlikely(condition)) {   \
>> + if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
>> + printk(KERN_ERR format); \
>
> and
> pr_err(fmt, ##__VA_ARGS__);
>
> so that any use would also get any local pr_fmt applied as well.
>
>> + BUG();   \
>> + } else   \
>> + WARN(1, format); \
>> + return false;\
>> + }\
>> + } while (0)
>> +
>>  #endif   /* _LINUX_BUG_H */
>

Ah yes, excellent point. I'll convert this for my v3. Thanks!

-Kees

-- 
Kees Cook
Nexus Security


Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-16 Thread Kees Cook
On Tue, Aug 16, 2016 at 5:26 PM, Joe Perches  wrote:
> On Tue, 2016-08-16 at 17:20 -0700, Kees Cook wrote:
>> The kernel checks for cases of data structure corruption under some
>> CONFIGs (e.g. CONFIG_DEBUG_LIST). When corruption is detected, some
>> systems may want to BUG() immediately instead of letting the system run
>> with known corruption.  Usually these kinds of manipulation primitives can
>> be used by security flaws to gain arbitrary memory write control. This
>> provides a new config CONFIG_BUG_ON_DATA_CORRUPTION and a corresponding
>> macro CHECK_DATA_CORRUPTION for handling these situations. Notably, even
>> if not BUGing, the kernel should not continue processing the corrupted
>> structure.
> []
>> diff --git a/include/linux/bug.h b/include/linux/bug.h
> []
>> @@ -118,4 +118,21 @@ static inline enum bug_trap_type report_bug(unsigned 
>> long bug_addr,
>>  }
>>
>>  #endif   /* CONFIG_GENERIC_BUG */
>> +
>> +/*
>> + * Since detected data corruption should stop operation on the affected
>> + * structures, this returns false if the corruption condition is found.
>> + */
>> +#define CHECK_DATA_CORRUPTION(condition, format...)   \
>
> My preference would be to use (condition, fmt, ...)
>
>> + do { \
>> + if (unlikely(condition)) {   \
>> + if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
>> + printk(KERN_ERR format); \
>
> and
> pr_err(fmt, ##__VA_ARGS__);
>
> so that any use would also get any local pr_fmt applied as well.
>
>> + BUG();   \
>> + } else   \
>> + WARN(1, format); \
>> + return false;\
>> + }\
>> + } while (0)
>> +
>>  #endif   /* _LINUX_BUG_H */
>

Ah yes, excellent point. I'll convert this for my v3. Thanks!

-Kees

-- 
Kees Cook
Nexus Security


Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-16 Thread Joe Perches
On Tue, 2016-08-16 at 17:20 -0700, Kees Cook wrote:
> The kernel checks for cases of data structure corruption under some
> CONFIGs (e.g. CONFIG_DEBUG_LIST). When corruption is detected, some
> systems may want to BUG() immediately instead of letting the system run
> with known corruption.  Usually these kinds of manipulation primitives can
> be used by security flaws to gain arbitrary memory write control. This
> provides a new config CONFIG_BUG_ON_DATA_CORRUPTION and a corresponding
> macro CHECK_DATA_CORRUPTION for handling these situations. Notably, even
> if not BUGing, the kernel should not continue processing the corrupted
> structure.
[]
> diff --git a/include/linux/bug.h b/include/linux/bug.h
[]
> @@ -118,4 +118,21 @@ static inline enum bug_trap_type report_bug(unsigned 
> long bug_addr,
>  }
>  
>  #endif   /* CONFIG_GENERIC_BUG */
> +
> +/*
> + * Since detected data corruption should stop operation on the affected
> + * structures, this returns false if the corruption condition is found.
> + */
> +#define CHECK_DATA_CORRUPTION(condition, format...)   \

My preference would be to use (condition, fmt, ...)

> + do { \
> + if (unlikely(condition)) {   \
> + if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
> + printk(KERN_ERR format); \

and
pr_err(fmt, ##__VA_ARGS__);

so that any use would also get any local pr_fmt applied as well.

> + BUG();   \
> + } else   \
> + WARN(1, format); \
> + return false;    \
> + }    \
> + } while (0)
> +
>  #endif   /* _LINUX_BUG_H */



Re: [PATCH v2 4/5] bug: Provide toggle for BUG on data corruption

2016-08-16 Thread Joe Perches
On Tue, 2016-08-16 at 17:20 -0700, Kees Cook wrote:
> The kernel checks for cases of data structure corruption under some
> CONFIGs (e.g. CONFIG_DEBUG_LIST). When corruption is detected, some
> systems may want to BUG() immediately instead of letting the system run
> with known corruption.  Usually these kinds of manipulation primitives can
> be used by security flaws to gain arbitrary memory write control. This
> provides a new config CONFIG_BUG_ON_DATA_CORRUPTION and a corresponding
> macro CHECK_DATA_CORRUPTION for handling these situations. Notably, even
> if not BUGing, the kernel should not continue processing the corrupted
> structure.
[]
> diff --git a/include/linux/bug.h b/include/linux/bug.h
[]
> @@ -118,4 +118,21 @@ static inline enum bug_trap_type report_bug(unsigned 
> long bug_addr,
>  }
>  
>  #endif   /* CONFIG_GENERIC_BUG */
> +
> +/*
> + * Since detected data corruption should stop operation on the affected
> + * structures, this returns false if the corruption condition is found.
> + */
> +#define CHECK_DATA_CORRUPTION(condition, format...)   \

My preference would be to use (condition, fmt, ...)

> + do { \
> + if (unlikely(condition)) {   \
> + if (IS_ENABLED(CONFIG_BUG_ON_DATA_CORRUPTION)) { \
> + printk(KERN_ERR format); \

and
pr_err(fmt, ##__VA_ARGS__);

so that any use would also get any local pr_fmt applied as well.

> + BUG();   \
> + } else   \
> + WARN(1, format); \
> + return false;    \
> + }    \
> + } while (0)
> +
>  #endif   /* _LINUX_BUG_H */