> You didn't get his point... The key point is that sizeof() result type > is size_t, slightly modify you code, try the result. >> int main(void) >> { >> unsigned int arg = 0xffffffff; >> unsigned int foo; >> printf("%lu\n", arg + sizeof(foo)); >> if (sizeof(foo) - 1 != arg + sizeof(foo)) { >> printf("not over flow.\n"); >> return -1; >> } >> printf("arg over flow.\n"); >> >> return 0; >> } sizeof() is size_t(unsigned int), get.size is also unsigned int, arg + sizeof(foo) can overflow as sizeof(foo) - 1 [root@localhost test]# ./test 3 arg over flow. my fault is *len is check with: if (*len < sizeof(get)) { duprintf("get_entries: %u < %zu\n", *len, sizeof(get)); return -EINVAL; } so, *len must >= sizeof(get), then: if (*len != sizeof(struct ipt_get_entries) + get.size) { duprintf("get_entries: %u != %zu\n", *len, sizeof(get) + get.size); return -EINVAL; } if sizeof(struct ipt_get_entries) + get.size oveflow, it must < sizeof(struct ipt_get_entries), It not make any problem, just return. get.size overflow can't make any problem, thx Feng and Jan for helping me. On Tue, Mar 23, 2010 at 12:49 PM, Xiaotian Feng <xtfeng@xxxxxxxxx> wrote: > On Tue, Mar 23, 2010 at 11:48 AM, wzt wzt <wzt.wzt@xxxxxxxxx> wrote: >> 1、 suppose *len = 35, sizeof(struct ipt_get_entries) = 36 >> 2、 set get.size = 0xffffffff from user space >> 3、 sizeof(struct ipt_get_entries) + get.size = 36 + 0xffffffff = 35; >> 4、 if (*len != sizeof(struct ipt_get_entries) + get.size) was bypassed. >> >> you can test with c code: >> >> #include <stdio.h> >> >> int main(void) >> { >> unsigned int arg = 0xffffffff; >> >> printf("%u\n", arg + 36); >> if (35 != arg + 36) { >> printf("not over flow.\n"); >> return -1; >> } >> printf("arg over flow.\n"); >> >> return 0; >> } >> > > You didn't get his point... The key point is that sizeof() result type > is size_t, slightly modify you code, try the result. >> int main(void) >> { >> unsigned int arg = 0xffffffff; >> unsigned int foo; >> printf("%lu\n", arg + sizeof(foo)); >> if (sizeof(foo) - 1 != arg + sizeof(foo)) { >> printf("not over flow.\n"); >> return -1; >> } >> printf("arg over flow.\n"); >> >> return 0; >> } > >> On Tue, Mar 23, 2010 at 11:04 AM, Jan Engelhardt <jengelh@xxxxxxxxxx> wrote: >>> >>> On Tuesday 2010-03-23 03:37, wzt wzt wrote: >>>>> And, for the addition overflow, can it be caught by >>>>> >>>>> "if (*len != sizeof(struct ipt_get_entries) + get.size)" ??? >>>> >>>>sizeof(struct ipt_get_entries) + get.size can be overflow as *len, >>>>get.size is control by user space with copy_from_user(). >>> >>> The != should catch it. >>> >>> For 64-bit environments: >>> * + invoked with size_t, unsigned int >>> => right side promoted to size_t, result type is size_t >>> * != invoked with int and size_t >>> => left-side promoted to ssize_t (probably; but something as large as size_t) >>> * get.size is 32-bit bounded, as is *len, >>> so no overflow to worry about at all unless you make >>> sizeof(X) hilariously big close to 2^64 which is rather unlikely. >>> >>> For 32-bit environments: >>> * Let *len be a number of choice (e.g. 36) >>> * Find a sizeof(X)+get.size that equals 36 mod 2^32. >>> * Since sizeof(X) is const, get.size must be 0 mod 2^32. >>> * So get.size must be a multiple of 2^32 to fool the system. >>> * Since get.size itself is only a 32-bit quantity, you cannot >>> represent any value larger than 4294967295. >>> >>> >>> What Was What Was Wanted. >>> >> > -- To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html