Commit ffbc9376 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'flex-array-conversions-5.8-rc2' of...

Merge tag 'flex-array-conversions-5.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux

Pull flexible-array member conversions from Gustavo A. R. Silva:
 "Replace zero-length arrays with flexible-array members.

  Notice that all of these patches have been baking in linux-next for
  two development cycles now.

  There is a regular need in the kernel to provide a way to declare
  having a dynamically sized set of trailing elements in a structure.
  Kernel code should always use “flexible array members”[1] for these
  cases. The older style of one-element or zero-length arrays should no
  longer be used[2].

  C99 introduced “flexible array members”, which lacks a numeric size
  for the array declaration entirely:

        struct something {
                size_t count;
                struct foo items[];
        };

  This is the way the kernel expects dynamically sized trailing elements
  to be declared. It allows the compiler to generate errors when the
  flexible array does not occur last in the structure, which helps to
  prevent some kind of undefined behavior[3] bugs from being
  inadvertently introduced to the codebase.

  It also allows the compiler to correctly analyze array sizes (via
  sizeof(), CONFIG_FORTIFY_SOURCE, and CONFIG_UBSAN_BOUNDS). For
  instance, there is no mechanism that warns us that the following
  application of the sizeof() operator to a zero-length array always
  results in zero:

        struct something {
                size_t count;
                struct foo items[0];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
        instance->count = count;

        size = sizeof(instance->items) * instance->count;
        memcpy(instance->items, source, size);

  At the last line of code above, size turns out to be zero, when one
  might have thought it represents the total size in bytes of the
  dynamic memory recently allocated for the trailing array items. Here
  are a couple examples of this issue[4][5].

  Instead, flexible array members have incomplete type, and so the
  sizeof() operator may not be applied[6], so any misuse of such
  operators will be immediately noticed at build time.

  The cleanest and least error-prone way to implement this is through
  the use of a flexible array member:

        struct something {
                size_t count;
                struct foo items[];
        };

        struct something *instance;

        instance = kmalloc(struct_size(instance, items, count), GFP_KERNEL);
        instance->count = count;

        size = sizeof(instance->items[0]) * instance->count;
        memcpy(instance->items, source, size);

  instead"

[1] https://en.wikipedia.org/wiki/Flexible_array_member
[2] https://github.com/KSPP/linux/issues/21
[3] commit 76497732 ("cxgb3/l2t: Fix undefined behaviour")
[4] commit f2cd32a4 ("rndis_wlan: Remove logically dead code")
[5] commit ab91c2a8 ("tpm: eventlog: Replace zero-length array with flexible-array member")
[6] https://gcc.gnu.org/onlinedocs/gcc/Zero-Length.html

* tag 'flex-array-conversions-5.8-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gustavoars/linux: (41 commits)
  w1: Replace zero-length array with flexible-array
  tracing/probe: Replace zero-length array with flexible-array
  soc: ti: Replace zero-length array with flexible-array
  tifm: Replace zero-length array with flexible-array
  dmaengine: tegra-apb: Replace zero-length array with flexible-array
  stm class: Replace zero-length array with flexible-array
  Squashfs: Replace zero-length array with flexible-array
  ASoC: SOF: Replace zero-length array with flexible-array
  ima: Replace zero-length array with flexible-array
  sctp: Replace zero-length array with flexible-array
  phy: samsung: Replace zero-length array with flexible-array
  RxRPC: Replace zero-length array with flexible-array
  rapidio: Replace zero-length array with flexible-array
  media: pwc: Replace zero-length array with flexible-array
  firmware: pcdp: Replace zero-length array with flexible-array
  oprofile: Replace zero-length array with flexible-array
  block: Replace zero-length array with flexible-array
  tools/testing/nvdimm: Replace zero-length array with flexible-array
  libata: Replace zero-length array with flexible-array
  kprobes: Replace zero-length array with flexible-array
  ...
parents ff58155c 76fafbff
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -42,7 +42,7 @@ enum unw_register_index {

struct unw_info_block {
	u64 header;
	u64 desc[0];		/* unwind descriptors */
	u64 desc[];		/* unwind descriptors */
	/* personality routine and language-specific data follow behind descriptors */
};

+1 −1
Original line number Diff line number Diff line
@@ -93,7 +93,7 @@ struct frag { /* VBLK Fragment handling */
	u8		num;		/* Total number of records */
	u8		rec;		/* This is record number n */
	u8		map;		/* Which portions are in use */
	u8		data[0];
	u8		data[];
};

/* In memory LDM database structures. */
+1 −1
Original line number Diff line number Diff line
@@ -120,7 +120,7 @@ static const u32 tegra_ahb_gizmo[] = {
struct tegra_ahb {
	void __iomem	*regs;
	struct device	*dev;
	u32		ctx[0];
	u32		ctx[];
};

static inline u32 gizmo_readl(struct tegra_ahb *ahb, u32 offset)
+1 −1
Original line number Diff line number Diff line
@@ -620,7 +620,7 @@ struct fifo_buffer {
	unsigned int head_index;
	unsigned int size;
	int total; /* sum of all values */
	int values[0];
	int values[];
};
extern struct fifo_buffer *fifo_alloc(unsigned int fifo_size);

+4 −4
Original line number Diff line number Diff line
@@ -271,7 +271,7 @@ struct p_rs_param {
	u32 resync_rate;

	      /* Since protocol version 88 and higher. */
	char verify_alg[0];
	char verify_alg[];
} __packed;

struct p_rs_param_89 {
@@ -305,7 +305,7 @@ struct p_protocol {
	u32 two_primaries;

	/* Since protocol version 87 and higher. */
	char integrity_alg[0];
	char integrity_alg[];

} __packed;

@@ -360,7 +360,7 @@ struct p_sizes {
	u16	    dds_flags; /* use enum dds_flags here. */

	/* optional queue_limits if (agreed_features & DRBD_FF_WSAME) */
	struct o_qlim qlim[0];
	struct o_qlim qlim[];
} __packed;

struct p_state {
@@ -409,7 +409,7 @@ struct p_compressed_bm {
	 */
	u8 encoding;

	u8 code[0];
	u8 code[];
} __packed;

struct p_delay_probe93 {
Loading