Skip to content

Commit 85f4c95

Browse files
GustavoARSilvagregkh
authored andcommitted
tty: n_hdlc: Use flexible-array member and struct_size() helper
Old code in the kernel uses 1-byte and 0-byte arrays to indicate the presence of a "variable length array": struct something { int length; u8 data[1]; }; struct something *instance; instance = kmalloc(sizeof(*instance) + size, GFP_KERNEL); instance->length = size; memcpy(instance->data, source, size); There is also 0-byte arrays. Both cases pose confusion for things like sizeof(), CONFIG_FORTIFY_SOURCE, etc.[1] Instead, the preferred mechanism to declare variable-length types such as the one above is a flexible array member[2] which need to be the last member of a structure and empty-sized: struct something { int stuff; u8 data[]; }; Also, by making use of the mechanism above, we will get a compiler warning in case the flexible array does not occur last in the structure, which will help us prevent some kind of undefined behavior bugs from being inadvertenly introduced[3] to the codebase from now on. Lastly, make use of the struct_size() helper to safely calculate the allocation size for instances of struct n_hdlc_buf and avoid any potential type mistakes[4][5]. [1] KSPP#21 [2] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html [3] commit 7649773 ("cxgb3/l2t: Fix undefined behaviour") [4] https://lore.kernel.org/lkml/[email protected]/ [5] commit 553d66c ("iommu/vt-d: Use struct_size() helper") Signed-off-by: Gustavo A. R. Silva <[email protected]> Reviewed-by: Jiri Slaby <[email protected]> Link: https://lore.kernel.org/r/20200121172138.GA3162@embeddedor Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 1ddeb5a commit 85f4c95

File tree

1 file changed

+5
-6
lines changed

1 file changed

+5
-6
lines changed

drivers/tty/n_hdlc.c

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,9 @@
115115
struct n_hdlc_buf {
116116
struct list_head list_item;
117117
int count;
118-
char buf[1];
118+
char buf[];
119119
};
120120

121-
#define N_HDLC_BUF_SIZE (sizeof(struct n_hdlc_buf) + maxframe)
122-
123121
struct n_hdlc_buf_list {
124122
struct list_head list;
125123
int count;
@@ -524,7 +522,8 @@ static void n_hdlc_tty_receive(struct tty_struct *tty, const __u8 *data,
524522
/* no buffers in free list, attempt to allocate another rx buffer */
525523
/* unless the maximum count has been reached */
526524
if (n_hdlc->rx_buf_list.count < MAX_RX_BUF_COUNT)
527-
buf = kmalloc(N_HDLC_BUF_SIZE, GFP_ATOMIC);
525+
buf = kmalloc(struct_size(buf, buf, maxframe),
526+
GFP_ATOMIC);
528527
}
529528

530529
if (!buf) {
@@ -853,7 +852,7 @@ static struct n_hdlc *n_hdlc_alloc(void)
853852

854853
/* allocate free rx buffer list */
855854
for(i=0;i<DEFAULT_RX_BUF_COUNT;i++) {
856-
buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
855+
buf = kmalloc(struct_size(buf, buf, maxframe), GFP_KERNEL);
857856
if (buf)
858857
n_hdlc_buf_put(&n_hdlc->rx_free_buf_list,buf);
859858
else if (debuglevel >= DEBUG_LEVEL_INFO)
@@ -862,7 +861,7 @@ static struct n_hdlc *n_hdlc_alloc(void)
862861

863862
/* allocate free tx buffer list */
864863
for(i=0;i<DEFAULT_TX_BUF_COUNT;i++) {
865-
buf = kmalloc(N_HDLC_BUF_SIZE, GFP_KERNEL);
864+
buf = kmalloc(struct_size(buf, buf, maxframe), GFP_KERNEL);
866865
if (buf)
867866
n_hdlc_buf_put(&n_hdlc->tx_free_buf_list,buf);
868867
else if (debuglevel >= DEBUG_LEVEL_INFO)

0 commit comments

Comments
 (0)