https://github.com/torvalds/linux
Revision 573b3aa6940661dc50c383213d428c27df78be7c authored by Yonghong Song on 30 July 2018, 15:49:03 UTC, committed by Daniel Borkmann on 30 July 2018, 22:37:09 UTC
I hit the following problem when I tried to use bpftool
to dump a percpu array.

  $ sudo ./bpftool map show
  61: percpu_array  name stub  flags 0x0
          key 4B  value 4B  max_entries 1  memlock 4096B
  ...
  $ sudo ./bpftool map dump id 61
  bpftool: malloc.c:2406: sysmalloc: Assertion
  `(old_top == initial_top (av) && old_size == 0) || \
   ((unsigned long) (old_size) >= MINSIZE && \
   prev_inuse (old_top) && \
   ((unsigned long) old_end & (pagesize - 1)) == 0)'
  failed.
  Aborted

Further debugging revealed that this is due to
miscommunication between bpftool and kernel.
For example, for the above percpu_array with value size of 4B.
The map info returned to user space has value size of 4B.

In bpftool, the values array for lookup is allocated like:
   info->value_size * get_possible_cpus() = 4 * get_possible_cpus()
In kernel (kernel/bpf/syscall.c), the values array size is
rounded up to multiple of 8.
   round_up(map->value_size, 8) * num_possible_cpus()
   = 8 * num_possible_cpus()
So when kernel copies the values to user buffer, the kernel will
overwrite beyond user buffer boundary.

This patch fixed the issue by allocating and stepping through
percpu map value array properly in bpftool.

Fixes: 71bb428fe2c19 ("tools: bpf: add bpftool")
Signed-off-by: Yonghong Song <yhs@fb.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
1 parent 61f4b23
Raw File
Tip revision: 573b3aa6940661dc50c383213d428c27df78be7c authored by Yonghong Song on 30 July 2018, 15:49:03 UTC
tools/bpftool: fix a percpu_array map dump problem
Tip revision: 573b3aa
scsi_bsg_iscsi.h
/*
 *  iSCSI Transport BSG Interface
 *
 *  Copyright (C) 2009   James Smart, Emulex Corporation
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef SCSI_BSG_ISCSI_H
#define SCSI_BSG_ISCSI_H

/*
 * This file intended to be included by both kernel and user space
 */

#include <scsi/scsi.h>

/*
 * iSCSI Transport SGIO v4 BSG Message Support
 */

/* Default BSG request timeout (in seconds) */
#define ISCSI_DEFAULT_BSG_TIMEOUT      (10 * HZ)


/*
 * Request Message Codes supported by the iSCSI Transport
 */

/* define the class masks for the message codes */
#define ISCSI_BSG_CLS_MASK     0xF0000000      /* find object class */
#define ISCSI_BSG_HST_MASK     0x80000000      /* iscsi host class */

/* iscsi host Message Codes */
#define ISCSI_BSG_HST_VENDOR           (ISCSI_BSG_HST_MASK | 0x000000FF)


/*
 * iSCSI Host Messages
 */

/* ISCSI_BSG_HST_VENDOR : */

/* Request:
 * Note: When specifying vendor_id, be sure to read the Vendor Type and ID
 *   formatting requirements specified in scsi_netlink.h
 */
struct iscsi_bsg_host_vendor {
	/*
	 * Identifies the vendor that the message is formatted for. This
	 * should be the recipient of the message.
	 */
	uint64_t vendor_id;

	/* start of vendor command area */
	uint32_t vendor_cmd[0];
};

/* Response:
 */
struct iscsi_bsg_host_vendor_reply {
	/* start of vendor response area */
	uint32_t vendor_rsp[0];
};


/* request (CDB) structure of the sg_io_v4 */
struct iscsi_bsg_request {
	uint32_t msgcode;
	union {
		struct iscsi_bsg_host_vendor    h_vendor;
	} rqst_data;
} __attribute__((packed));


/* response (request sense data) structure of the sg_io_v4 */
struct iscsi_bsg_reply {
	/*
	 * The completion result. Result exists in two forms:
	 * if negative, it is an -Exxx system errno value. There will
	 * be no further reply information supplied.
	 * else, it's the 4-byte scsi error result, with driver, host,
	 * msg and status fields. The per-msgcode reply structure
	 * will contain valid data.
	 */
	uint32_t result;

	/* If there was reply_payload, how much was recevied ? */
	uint32_t reply_payload_rcv_len;

	union {
		struct iscsi_bsg_host_vendor_reply      vendor_reply;
	} reply_data;
};


#endif /* SCSI_BSG_ISCSI_H */
back to top