usb: gadget: f_fs: Prevent panic due to failure of huge size buffer allocation
[platform/kernel/linux-rpi.git] / tools / testing / selftests / kdbus / test-free.c
1 #include <stdio.h>
2 #include <string.h>
3 #include <fcntl.h>
4 #include <stdlib.h>
5 #include <stddef.h>
6 #include <unistd.h>
7 #include <stdint.h>
8 #include <errno.h>
9 #include <assert.h>
10 #include <stdbool.h>
11
12 #include "kdbus-api.h"
13 #include "kdbus-util.h"
14 #include "kdbus-enum.h"
15 #include "kdbus-test.h"
16
17 wur static int sample_ioctl_call(struct kdbus_test_env *env, unsigned *poff, unsigned *psize)
18 {
19         unsigned off, size;
20         struct kdbus_cmd_list cmd_list = {
21                 .flags = KDBUS_LIST_UNIQUE,
22                 .size = sizeof(cmd_list),
23         };
24
25         /* DON'T FREE THIS SLICE OF MEMORY! */
26         ASSERT_ZERO(kdbus_cmd_list(env->conn->fd, &cmd_list));
27
28         #define A(L,R) do { ASSERT_RETURN((typeof(L))(R),==,(R)); *p##L = L = (R); } while (0)
29                 A(off, cmd_list.offset);
30                 ASSERT_RETURN(off,<,POOL_SIZE);
31                 A(size, ((struct kdbus_info *)((uintptr_t)env->conn->buf + off))->size);
32         #undef A
33
34         ASSERT_RETURN(off+size,<,POOL_SIZE);
35         ASSERT_RETURN(off+size,>=,size);
36         ASSERT_RETURN(off+size,>,off);
37         ASSERT_ZERO(size % 8);
38         ASSERT_RETURN(size,>=,sizeof(struct kdbus_info));
39
40         /*print("off(%u) size(%u)\n", *offset, *size);*/
41
42         return TEST_OK;
43 }
44
45 wur static int area_before(unsigned off_left, unsigned size_left, unsigned off_right)
46 {
47         ASSERT_RETURN(off_left+size_left,<=,off_right);
48         return 0;
49 }
50
51 int kdbus_test_free(struct kdbus_test_env *env)
52 {
53         struct kdbus_cmd_free cmd_free = {};
54         unsigned offset[20], size[TABSIZE(offset)];
55         unsigned i;
56
57         /* free an unallocated buffer */
58         cmd_free.size = sizeof(cmd_free);
59         cmd_free.flags = 0;
60         cmd_free.offset = 0;
61         ASSERT_RETURN(-ENXIO,==,kdbus_cmd_free(env->conn->fd, &cmd_free));
62
63         /* free a buffer out of the pool's bounds */
64         cmd_free.size = sizeof(cmd_free);
65         cmd_free.offset = POOL_SIZE + 1;
66         ASSERT_RETURN(-ENXIO,==,kdbus_cmd_free(env->conn->fd, &cmd_free));
67
68         /*
69          * The user application is responsible for freeing the allocated
70          * memory with the KDBUS_CMD_FREE ioctl, so let's test what happens
71          * if we forget about it.
72          *
73          * Assert that memory areas don't overlap.
74          */
75
76         for (i=0; i<TABSIZE(offset); ++i) {
77                 unsigned off, siz;
78                 int j;
79                 ASSERT_ZERO(sample_ioctl_call(env, &off, &siz));
80                 for (j=i-1; j>=0; --j) {
81                         if (offset[j] > off) {
82                                 ASSERT_ZERO(area_before(off,siz,offset[j]));
83                                 offset[j+1] = offset[j];
84                                 size[j+1] = size[j];
85                         } else {
86                                 ASSERT_ZERO(area_before(offset[j],size[j],off));
87                                 break;
88                         }
89                 }
90                 ASSERT_RETURN(j+1,>=,0);
91                 ASSERT_RETURN((unsigned)(j+1),<=,i);
92                 offset[j+1] = off;
93                 size[j+1] = siz;
94         }
95
96         /* attempt to free invalid offsets around the ones above to test the underlying allocator */
97         {
98                 unsigned j, last = offset[TABSIZE(offset)-1] + size[TABSIZE(offset)-1] + 1;
99                 for (i=j=0; i<last; ++i) {
100                         if (i == offset[j]) {
101                                 ++i;
102                                 ++j;
103                         }
104                         cmd_free.size = sizeof(cmd_free);
105                         cmd_free.offset = i;
106                         ASSERT_RETURN(-ENXIO,==,kdbus_cmd_free(env->conn->fd, &cmd_free));
107                 }
108         }
109
110         return TEST_OK;
111 }