/* * Test that proc_dointvec will not try to use a NULL .data field even when the * length is non-zero.
*/ staticvoid sysctl_test_api_dointvec_null_tbl_data(struct kunit *test)
{ struct ctl_table null_data_table = {
.procname = "foo", /* * Here we are testing that proc_dointvec behaves correctly when * we give it a NULL .data field. Normally this would point to a * piece of memory where the value would be stored.
*/
.data = NULL,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE_HUNDRED,
}; /* * proc_dointvec expects a buffer in user space, so we allocate one. We * also need to cast it to __user so sparse doesn't get mad.
*/ void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
GFP_USER);
size_t len;
loff_t pos;
/* * We don't care what the starting length is since proc_dointvec should * not try to read because .data is NULL.
*/
len = 1234;
KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&null_data_table,
KUNIT_PROC_READ, buffer, &len,
&pos));
KUNIT_EXPECT_EQ(test, 0, len);
/* * See above.
*/
len = 1234;
KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&null_data_table,
KUNIT_PROC_WRITE, buffer, &len,
&pos));
KUNIT_EXPECT_EQ(test, 0, len);
}
/* * Similar to the previous test, we create a struct ctrl_table that has a .data * field that proc_dointvec cannot do anything with; however, this time it is * because we tell proc_dointvec that the size is 0.
*/ staticvoid sysctl_test_api_dointvec_table_maxlen_unset(struct kunit *test)
{ int data = 0; struct ctl_table data_maxlen_unset_table = {
.procname = "foo",
.data = &data, /* * So .data is no longer NULL, but we tell proc_dointvec its * length is 0, so it still shouldn't try to use it.
*/
.maxlen = 0,
.mode = 0644,
.proc_handler = proc_dointvec,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE_HUNDRED,
}; void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
GFP_USER);
size_t len;
loff_t pos;
/* * As before, we don't care what buffer length is because proc_dointvec * cannot do anything because its internal .data buffer has zero length.
*/
len = 1234;
KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&data_maxlen_unset_table,
KUNIT_PROC_READ, buffer, &len,
&pos));
KUNIT_EXPECT_EQ(test, 0, len);
/* * See previous comment.
*/
len = 1234;
KUNIT_EXPECT_EQ(test, 0, proc_dointvec(&data_maxlen_unset_table,
KUNIT_PROC_WRITE, buffer, &len,
&pos));
KUNIT_EXPECT_EQ(test, 0, len);
}
/* * Here we provide a valid struct ctl_table, but we try to read and write from * it using a buffer of zero length, so it should still fail in a similar way as * before.
*/ staticvoid sysctl_test_api_dointvec_table_len_is_zero(struct kunit *test)
{ int data = 0; /* Good table. */ struct ctl_table table = {
.procname = "foo",
.data = &data,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE_HUNDRED,
}; void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
GFP_USER); /* * However, now our read/write buffer has zero length.
*/
size_t len = 0;
loff_t pos;
/* * Test that proc_dointvec refuses to read when the file position is non-zero.
*/ staticvoid sysctl_test_api_dointvec_table_read_but_position_set( struct kunit *test)
{ int data = 0; /* Good table. */ struct ctl_table table = {
.procname = "foo",
.data = &data,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE_HUNDRED,
}; void __user *buffer = (void __user *)kunit_kzalloc(test, sizeof(int),
GFP_USER); /* * We don't care about our buffer length because we start off with a * non-zero file position.
*/
size_t len = 1234; /* * proc_dointvec should refuse to read into the buffer since the file * pos is non-zero.
*/
loff_t pos = 1;
/* * Test that writing a value smaller than the minimum possible value is not * allowed.
*/ staticvoid sysctl_test_api_dointvec_write_single_less_int_min( struct kunit *test)
{ int data = 0; struct ctl_table table = {
.procname = "foo",
.data = &data,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
.extra1 = SYSCTL_ZERO,
.extra2 = SYSCTL_ONE_HUNDRED,
};
size_t max_len = 32, len = max_len;
loff_t pos = 0; char *buffer = kunit_kzalloc(test, max_len, GFP_USER); char __user *user_buffer = (char __user *)buffer; unsignedlong abs_of_less_than_min = (unsignedlong)INT_MAX
- (INT_MAX + INT_MIN) + 1;
/* * We use this rigmarole to create a string that contains a value one * less than the minimum accepted value.
*/
KUNIT_ASSERT_LT(test,
(size_t)snprintf(buffer, max_len, "-%lu",
abs_of_less_than_min),
max_len);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.