aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--block/blk-core.c18
-rw-r--r--block/bsg.c3
-rw-r--r--block/scsi_ioctl.c6
-rw-r--r--drivers/block/pktcdvd.c2
-rw-r--r--drivers/cdrom/cdrom.c2
-rw-r--r--drivers/crypto/msm/ota_crypto.c4
-rw-r--r--drivers/crypto/msm/qcedev.c15
-rw-r--r--drivers/crypto/msm/qcrypto.c4
-rw-r--r--drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c6
-rw-r--r--drivers/media/platform/msm/vidc/msm_vidc_common.c2
-rw-r--r--drivers/media/platform/msm/vidc/venus_hfi.c6
-rw-r--r--drivers/misc/qseecom.c4
-rw-r--r--drivers/scsi/device_handler/scsi_dh_alua.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_emc.c2
-rw-r--r--drivers/scsi/device_handler/scsi_dh_hp_sw.c4
-rw-r--r--drivers/scsi/device_handler/scsi_dh_rdac.c2
-rw-r--r--drivers/scsi/osd/osd_initiator.c4
-rw-r--r--drivers/scsi/osst.c2
-rw-r--r--drivers/scsi/scsi_error.c3
-rw-r--r--drivers/scsi/scsi_lib.c2
-rw-r--r--drivers/scsi/sg.c51
-rw-r--r--drivers/scsi/st.c2
-rw-r--r--drivers/slimbus/slim-msm-ngd.c5
-rw-r--r--drivers/slimbus/slim-msm.h1
-rw-r--r--drivers/spmi/spmi-dbgfs.c37
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c20
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c49
-rw-r--r--drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c33
-rw-r--r--drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c4
-rw-r--r--drivers/target/target_core_pscsi.c3
-rw-r--r--drivers/usb/serial/cypress_m8.c11
-rw-r--r--fs/9p/acl.c40
-rw-r--r--fs/btrfs/acl.c4
-rw-r--r--fs/ecryptfs/file.c9
-rw-r--r--fs/ecryptfs/main.c7
-rw-r--r--fs/exec.c5
-rw-r--r--fs/ext2/acl.c12
-rw-r--r--fs/ext3/acl.c12
-rw-r--r--fs/ext4/acl.c12
-rw-r--r--fs/f2fs/acl.c4
-rw-r--r--fs/generic_acl.c8
-rw-r--r--fs/gfs2/acl.c11
-rw-r--r--fs/jffs2/acl.c9
-rw-r--r--fs/jfs/xattr.c6
-rw-r--r--fs/namei.c10
-rw-r--r--fs/ocfs2/acl.c18
-rw-r--r--fs/posix_acl.c29
-rw-r--r--fs/proc/array.c10
-rw-r--r--fs/readdir.c20
-rw-r--r--fs/reiserfs/xattr_acl.c8
-rw-r--r--fs/sdcardfs/main.c7
-rw-r--r--fs/xfs/xfs_acl.c13
-rw-r--r--include/linux/blkdev.h1
-rw-r--r--include/linux/dcache.h7
-rw-r--r--include/linux/fs.h11
-rw-r--r--include/linux/perf_event.h6
-rw-r--r--include/linux/posix_acl.h1
-rw-r--r--include/linux/sched.h8
-rw-r--r--include/scsi/sg.h91
-rw-r--r--kernel/events/core.c15
-rw-r--r--kernel/exit.c5
-rw-r--r--kernel/fork.c2
-rw-r--r--kernel/sched/core.c32
-rw-r--r--mm/mempolicy.c20
-rw-r--r--mm/migrate.c48
-rw-r--r--net/ceph/crypto.c87
-rw-r--r--net/ceph/crypto.h2
-rw-r--r--net/l2tp/l2tp_ip.c2
-rw-r--r--net/packet/af_packet.c30
-rw-r--r--security/keys/gc.c2
-rw-r--r--security/keys/keyctl.c20
-rw-r--r--security/keys/process_keys.c44
-rw-r--r--sound/soc/codecs/wcd9320.c8
-rw-r--r--sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c2
74 files changed, 664 insertions, 343 deletions
diff --git a/block/blk-core.c b/block/blk-core.c
index f417c5c6729..01e928ee4db 100644
--- a/block/blk-core.c
+++ b/block/blk-core.c
@@ -1047,6 +1047,8 @@ struct request *blk_make_request(struct request_queue *q, struct bio *bio,
if (unlikely(!rq))
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(rq);
+
for_each_bio(bio) {
struct bio *bounce_bio = bio;
int ret;
@@ -1064,6 +1066,22 @@ struct request *blk_make_request(struct request_queue *q, struct bio *bio,
EXPORT_SYMBOL(blk_make_request);
/**
+ * blk_rq_set_block_pc - initialize a requeest to type BLOCK_PC
+ * @rq: request to be initialized
+ *
+ */
+void blk_rq_set_block_pc(struct request *rq)
+{
+ rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ rq->__data_len = 0;
+ rq->__sector = (sector_t) -1;
+ rq->bio = rq->biotail = NULL;
+ memset(rq->__cmd, 0, sizeof(rq->__cmd));
+ rq->cmd = rq->__cmd;
+}
+EXPORT_SYMBOL(blk_rq_set_block_pc);
+
+/**
* blk_requeue_request - put a request back on queue
* @q: request queue where request should be inserted
* @rq: request to be inserted
diff --git a/block/bsg.c b/block/bsg.c
index b1c1d542aa2..8c750d542c7 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -196,7 +196,6 @@ static int blk_fill_sgv4_hdr_rq(struct request_queue *q, struct request *rq,
* fill in request structure
*/
rq->cmd_len = hdr->request_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
@@ -273,6 +272,8 @@ bsg_map_hdr(struct bsg_device *bd, struct sg_io_v4 *hdr, fmode_t has_write_perm,
rq = blk_get_request(q, rw, GFP_KERNEL);
if (!rq)
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(rq);
+
ret = blk_fill_sgv4_hdr_rq(q, rq, hdr, bd, has_write_perm);
if (ret)
goto out;
diff --git a/block/scsi_ioctl.c b/block/scsi_ioctl.c
index f1c00c9aec1..74123963164 100644
--- a/block/scsi_ioctl.c
+++ b/block/scsi_ioctl.c
@@ -232,7 +232,6 @@ static int blk_fill_sghdr_rq(struct request_queue *q, struct request *rq,
* fill in request structure
*/
rq->cmd_len = hdr->cmd_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = msecs_to_jiffies(hdr->timeout);
if (!rq->timeout)
@@ -313,6 +312,7 @@ static int sg_io(struct request_queue *q, struct gendisk *bd_disk,
rq = blk_get_request(q, writing ? WRITE : READ, GFP_KERNEL);
if (!rq)
return -ENOMEM;
+ blk_rq_set_block_pc(rq);
if (blk_fill_sghdr_rq(q, rq, hdr, mode)) {
blk_put_request(rq);
@@ -511,7 +511,7 @@ int sg_scsi_ioctl(struct request_queue *q, struct gendisk *disk, fmode_t mode,
memset(sense, 0, sizeof(sense));
rq->sense = sense;
rq->sense_len = 0;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(rq);
blk_execute_rq(q, disk, rq, 0);
@@ -543,7 +543,7 @@ static int __blk_send_generic(struct request_queue *q, struct gendisk *bd_disk,
int err;
rq = blk_get_request(q, WRITE, __GFP_WAIT);
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(rq);
rq->timeout = BLK_DEFAULT_SG_TIMEOUT;
rq->cmd[0] = cmd;
rq->cmd[4] = data;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index ba66e4445f4..39ffe9c106e 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -742,6 +742,7 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
rq = blk_get_request(q, (cgc->data_direction == CGC_DATA_WRITE) ?
WRITE : READ, __GFP_WAIT);
+ blk_rq_set_block_pc(rq);
if (cgc->buflen) {
if (blk_rq_map_kern(q, rq, cgc->buffer, cgc->buflen, __GFP_WAIT))
@@ -752,7 +753,6 @@ static int pkt_generic_packet(struct pktcdvd_device *pd, struct packet_command *
memcpy(rq->cmd, cgc->cmd, CDROM_PACKET_SIZE);
rq->timeout = 60*HZ;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
if (cgc->quiet)
rq->cmd_flags |= REQ_QUIET;
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 8a3aff724d9..1ca0772c713 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -2165,6 +2165,7 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
ret = -ENOMEM;
break;
}
+ blk_rq_set_block_pc(rq);
ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
if (ret) {
@@ -2184,7 +2185,6 @@ static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
rq->cmd[9] = 0xf8;
rq->cmd_len = 12;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->timeout = 60 * HZ;
bio = rq->bio;
diff --git a/drivers/crypto/msm/ota_crypto.c b/drivers/crypto/msm/ota_crypto.c
index 6ecf5b2b4cc..60525358f89 100644
--- a/drivers/crypto/msm/ota_crypto.c
+++ b/drivers/crypto/msm/ota_crypto.c
@@ -744,8 +744,8 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
int len;
len = _disp_stats();
-
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
return rc;
diff --git a/drivers/crypto/msm/qcedev.c b/drivers/crypto/msm/qcedev.c
index 0cbefe7671d..43b3d0ad5d3 100644
--- a/drivers/crypto/msm/qcedev.c
+++ b/drivers/crypto/msm/qcedev.c
@@ -1549,6 +1549,15 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
pr_err("%s: Invalid byte offset\n", __func__);
goto error;
}
+ total = req->byteoffset;
+ for (i = 0; i < req->entries; i++) {
+ if (total > U32_MAX - req->vbuf.src[i].len) {
+ pr_err("%s:Integer overflow on total src len\n",
+ __func__);
+ goto error;
+ }
+ total += req->vbuf.src[i].len;
+ }
}
if (req->data_len < req->byteoffset) {
@@ -1584,7 +1593,7 @@ static int qcedev_check_cipher_params(struct qcedev_cipher_op_req *req,
}
}
/* Check for sum of all dst length is equal to data_len */
- for (i = 0; i < req->entries; i++) {
+ for (i = 0, total = 0; i < req->entries; i++) {
if (req->vbuf.dst[i].len >= U32_MAX - total) {
pr_err("%s: Integer overflow on total req dst vbuf length\n",
__func__);
@@ -2164,9 +2173,9 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
len = _disp_stats(qcedev);
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
-
return rc;
}
diff --git a/drivers/crypto/msm/qcrypto.c b/drivers/crypto/msm/qcrypto.c
index bbf4ef693ed..8d1c7e27e3b 100644
--- a/drivers/crypto/msm/qcrypto.c
+++ b/drivers/crypto/msm/qcrypto.c
@@ -4918,9 +4918,9 @@ static ssize_t _debug_stats_read(struct file *file, char __user *buf,
len = _disp_stats(qcrypto);
- rc = simple_read_from_buffer((void __user *) buf, len,
+ if (len <= count)
+ rc = simple_read_from_buffer((void __user *) buf, len,
ppos, (void *) _debug_read_buf, len);
-
return rc;
}
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
index 7d369fff360..78a629328b5 100644
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.c
@@ -251,6 +251,12 @@ int msm_camera_config_vreg(struct device *dev, struct camera_vreg_t *cam_vreg,
pr_err("%s:%d vreg sequence invalid\n", __func__, __LINE__);
return -EINVAL;
}
+
+ if (cam_vreg == NULL) {
+ pr_err("%s:%d cam_vreg sequence invalid\n", __func__, __LINE__);
+ return -EINVAL;
+ }
+
if (!num_vreg_seq)
num_vreg_seq = num_vreg;
diff --git a/drivers/media/platform/msm/vidc/msm_vidc_common.c b/drivers/media/platform/msm/vidc/msm_vidc_common.c
index 2fcb6fbd343..86e889951e4 100644
--- a/drivers/media/platform/msm/vidc/msm_vidc_common.c
+++ b/drivers/media/platform/msm/vidc/msm_vidc_common.c
@@ -1368,7 +1368,7 @@ static void handle_fbd(enum command_response cmd, void *data)
if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
dprintk(VIDC_DBG,
- "extradata: userptr = %p; bytesused = %d; length = %d\n",
+ "extradata: userptr = %pK; bytesused = %d; length = %d\n",
(u8 *)vb->v4l2_planes[extra_idx].m.userptr,
vb->v4l2_planes[extra_idx].bytesused,
vb->v4l2_planes[extra_idx].length);
diff --git a/drivers/media/platform/msm/vidc/venus_hfi.c b/drivers/media/platform/msm/vidc/venus_hfi.c
index e03d5609747..faadacb7e93 100644
--- a/drivers/media/platform/msm/vidc/venus_hfi.c
+++ b/drivers/media/platform/msm/vidc/venus_hfi.c
@@ -668,7 +668,7 @@ static int venus_hfi_unvote_bus(void *dev,
struct venus_hfi_device *device = dev;
if (!device) {
- dprintk(VIDC_ERR, "%s invalid device handle %p",
+ dprintk(VIDC_ERR, "%s invalid device handle %pK",
__func__, device);
return -EINVAL;
}
@@ -765,7 +765,7 @@ static int venus_hfi_scale_bus(void *dev, int load,
int bus_vector = 0;
if (!device) {
- dprintk(VIDC_ERR, "%s invalid device handle %p",
+ dprintk(VIDC_ERR, "%s invalid device handle %pK",
__func__, device);
return -EINVAL;
}
@@ -2513,7 +2513,7 @@ static int venus_hfi_session_clean(void *session)
}
sess_close = session;
device = sess_close->device;
- dprintk(VIDC_DBG, "deleted the session: 0x%p",
+ dprintk(VIDC_DBG, "deleted the session: 0x%pK",
sess_close);
mutex_lock(&device->session_lock);
list_del(&sess_close->list);
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
index 3ecdda9dd58..74d22a7754e 100644
--- a/drivers/misc/qseecom.c
+++ b/drivers/misc/qseecom.c
@@ -1246,7 +1246,7 @@ int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
void *req_buf = NULL;
if ((req_ptr == NULL) || (send_svc_ireq_ptr == NULL)) {
- pr_err("Error with pointer: req_ptr = %p, send_svc_ptr = %p\n",
+ pr_err("Error with pointer: req_ptr = %pK, send_svc_ptr = %pK\n",
req_ptr, send_svc_ireq_ptr);
return -EINVAL;
}
@@ -2471,7 +2471,7 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
if (ret)
return ret;
- pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%p\n",
+ pr_debug("sending cmd_req->rsp size: %u, ptr: 0x%pK\n",
req.resp_len, req.resp_buf);
return ret;
}
diff --git a/drivers/scsi/device_handler/scsi_dh_alua.c b/drivers/scsi/device_handler/scsi_dh_alua.c
index 3a8ba3e433d..e8124e9255f 100644
--- a/drivers/scsi/device_handler/scsi_dh_alua.c
+++ b/drivers/scsi/device_handler/scsi_dh_alua.c
@@ -111,6 +111,7 @@ static struct request *get_alua_req(struct scsi_device *sdev,
"%s: blk_get_request failed\n", __func__);
return NULL;
}
+ blk_rq_set_block_pc(rq);
if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
@@ -119,7 +120,6 @@ static struct request *get_alua_req(struct scsi_device *sdev,
return NULL;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->retries = ALUA_FAILOVER_RETRIES;
diff --git a/drivers/scsi/device_handler/scsi_dh_emc.c b/drivers/scsi/device_handler/scsi_dh_emc.c
index e1c8be06de9..6f07f7fe3aa 100644
--- a/drivers/scsi/device_handler/scsi_dh_emc.c
+++ b/drivers/scsi/device_handler/scsi_dh_emc.c
@@ -280,6 +280,7 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
return NULL;
}
+ blk_rq_set_block_pc(rq);
rq->cmd_len = COMMAND_SIZE(cmd);
rq->cmd[0] = cmd;
@@ -304,7 +305,6 @@ static struct request *get_req(struct scsi_device *sdev, int cmd,
break;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->timeout = CLARIION_TIMEOUT;
diff --git a/drivers/scsi/device_handler/scsi_dh_hp_sw.c b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
index 084062bb8ee..e9d9fea9e27 100644
--- a/drivers/scsi/device_handler/scsi_dh_hp_sw.c
+++ b/drivers/scsi/device_handler/scsi_dh_hp_sw.c
@@ -120,7 +120,7 @@ retry:
if (!req)
return SCSI_DH_RES_TEMP_UNAVAIL;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(TEST_UNIT_READY);
@@ -250,7 +250,7 @@ static int hp_sw_start_stop(struct hp_sw_dh_data *h)
if (!req)
return SCSI_DH_RES_TEMP_UNAVAIL;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
req->cmd_len = COMMAND_SIZE(START_STOP);
diff --git a/drivers/scsi/device_handler/scsi_dh_rdac.c b/drivers/scsi/device_handler/scsi_dh_rdac.c
index 20c4557f5ab..0439652c2d4 100644
--- a/drivers/scsi/device_handler/scsi_dh_rdac.c
+++ b/drivers/scsi/device_handler/scsi_dh_rdac.c
@@ -279,6 +279,7 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
"get_rdac_req: blk_get_request failed.\n");
return NULL;
}
+ blk_rq_set_block_pc(rq);
if (buflen && blk_rq_map_kern(q, rq, buffer, buflen, GFP_NOIO)) {
blk_put_request(rq);
@@ -287,7 +288,6 @@ static struct request *get_rdac_req(struct scsi_device *sdev,
return NULL;
}
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
rq->cmd_flags |= REQ_FAILFAST_DEV | REQ_FAILFAST_TRANSPORT |
REQ_FAILFAST_DRIVER;
rq->retries = RDAC_RETRIES;
diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c
index c06b8e5aa2c..9ad3ac77fd9 100644
--- a/drivers/scsi/osd/osd_initiator.c
+++ b/drivers/scsi/osd/osd_initiator.c
@@ -1566,6 +1566,7 @@ static struct request *_make_request(struct request_queue *q, bool has_write,
if (unlikely(!req))
return ERR_PTR(-ENOMEM);
+ blk_rq_set_block_pc(req);
return req;
}
}
@@ -1586,7 +1587,6 @@ static int _init_blk_request(struct osd_request *or,
}
or->request = req;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= REQ_QUIET;
req->timeout = or->timeout;
@@ -1604,7 +1604,7 @@ static int _init_blk_request(struct osd_request *or,
ret = PTR_ERR(req);
goto out;
}
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
or->in.req = or->request->next_rq = req;
}
} else if (has_in)
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c
index 21883a2d632..0727ea7cc38 100644
--- a/drivers/scsi/osst.c
+++ b/drivers/scsi/osst.c
@@ -365,7 +365,7 @@ static int osst_execute(struct osst_request *SRpnt, const unsigned char *cmd,
if (!req)
return DRIVER_ERROR << 24;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_QUIET;
SRpnt->bio = NULL;
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
index 185971c2b41..65955f7c22f 100644
--- a/drivers/scsi/scsi_error.c
+++ b/drivers/scsi/scsi_error.c
@@ -1643,6 +1643,8 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
*/
req = blk_get_request(sdev->request_queue, READ, GFP_KERNEL);
+ blk_rq_set_block_pc(req);
+
req->cmd[0] = ALLOW_MEDIUM_REMOVAL;
req->cmd[1] = 0;
req->cmd[2] = 0;
@@ -1652,7 +1654,6 @@ static void scsi_eh_lock_door(struct scsi_device *sdev)
req->cmd_len = COMMAND_SIZE(req->cmd[0]);
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= REQ_QUIET;
req->timeout = 10 * HZ;
req->retries = 5;
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 6f1bf55db91..302b6a815e4 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -217,6 +217,7 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
req = blk_get_request(sdev->request_queue, write, __GFP_WAIT);
if (!req)
return ret;
+ blk_rq_set_block_pc(req);
if (bufflen && blk_rq_map_kern(sdev->request_queue, req,
buffer, bufflen, __GFP_WAIT))
@@ -228,7 +229,6 @@ int scsi_execute(struct scsi_device *sdev, const unsigned char *cmd,
req->sense_len = 0;
req->retries = retries;
req->timeout = timeout;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->cmd_flags |= flags | REQ_QUIET | REQ_PREEMPT;
/*
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index 72e2478cb45..1224e762353 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -7,9 +7,7 @@
* Original driver (sg.c):
* Copyright (C) 1992 Lawrence Foard
* Version 2 and 3 extensions to driver:
- * Copyright (C) 1998 - 2005 Douglas Gilbert
- *
- * Modified 19-JAN-1998 Richard Gooch <rgooch@atnf.csiro.au> Devfs support
+ * Copyright (C) 1998 - 2014 Douglas Gilbert
*
* 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
@@ -18,11 +16,11 @@
*
*/
-static int sg_version_num = 30534; /* 2 digits for each component */
-#define SG_VERSION_STR "3.5.34"
+static int sg_version_num = 30536; /* 2 digits for each component */
+#define SG_VERSION_STR "3.5.36"
/*
- * D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
+ * D. P. Gilbert (dgilbert@interlog.com), notes:
* - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
* the kernel/module needs to be built with CONFIG_SCSI_LOGGING
* (otherwise the macros compile to empty statements).
@@ -63,7 +61,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */
#ifdef CONFIG_SCSI_PROC_FS
#include <linux/proc_fs.h>
-static char *sg_version_date = "20061027";
+static char *sg_version_date = "20140603";
static int sg_proc_init(void);
static void sg_proc_cleanup(void);
@@ -73,6 +71,12 @@ static void sg_proc_cleanup(void);
#define SG_MAX_DEVS 32768
+/* SG_MAX_CDB_SIZE should be 260 (spc4r37 section 3.1.30) however the type
+ * of sg_io_hdr::cmd_len can only represent 255. All SCSI commands greater
+ * than 16 bytes are "variable length" whose length is a multiple of 4
+ */
+#define SG_MAX_CDB_SIZE 252
+
/*
* Suppose you want to calculate the formula muldiv(x,m,d)=int(x * m / d)
* Then when using 32 bit integers x * m may overflow during the calculation.
@@ -159,7 +163,7 @@ typedef struct sg_fd { /* holds the state of a file descriptor */
char force_packid; /* 1 -> pack_id input to read(), 0 -> ignored */
volatile char closed; /* 1 -> fd closed but request(s) outstanding */
char cmd_q; /* 1 -> allow command queuing, 0 -> don't */
- char next_cmd_len; /* 0 -> automatic (def), >0 -> use on next write() */
+ unsigned char next_cmd_len; /* 0: automatic, >0: use on next write() */
char keep_orphan; /* 0 -> drop orphan (def), 1 -> keep for read() */
char mmap_called; /* 0 -> mmap() never called on this fd */
struct kref f_ref;
@@ -542,7 +546,7 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
Sg_request *srp;
struct sg_header old_hdr;
sg_io_hdr_t *hp;
- unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
if (unlikely(segment_eq(get_fs(), KERNEL_DS)))
return -EINVAL;
@@ -577,12 +581,6 @@ sg_write(struct file *filp, const char __user *buf, size_t count, loff_t * ppos)
buf += SZ_SG_HEADER;
__get_user(opcode, buf);
if (sfp->next_cmd_len > 0) {
- if (sfp->next_cmd_len > MAX_COMMAND_SIZE) {
- SCSI_LOG_TIMEOUT(1, printk("sg_write: command length too long\n"));
- sfp->next_cmd_len = 0;
- sg_remove_request(sfp, srp);
- return -EIO;
- }
cmd_size = sfp->next_cmd_len;
sfp->next_cmd_len = 0; /* reset so only this write() effected */
} else {
@@ -654,7 +652,7 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf,
int k;
Sg_request *srp;
sg_io_hdr_t *hp;
- unsigned char cmnd[MAX_COMMAND_SIZE];
+ unsigned char cmnd[SG_MAX_CDB_SIZE];
int timeout;
unsigned long ul_timeout;
@@ -961,6 +959,8 @@ sg_ioctl(struct file *filp, unsigned int cmd_in, unsigned long arg)
result = get_user(val, ip);
if (result)
return result;
+ if (val > SG_MAX_CDB_SIZE)
+ return -ENOMEM;
sfp->next_cmd_len = (val > 0) ? val : 0;
return 0;
case SG_GET_VERSION_NUM:
@@ -1647,18 +1647,29 @@ static int sg_start_req(Sg_request *srp, unsigned char *cmd)
struct request_queue *q = sfp->parentdp->device->request_queue;
struct rq_map_data *md, map_data;
int rw = hp->dxfer_direction == SG_DXFER_TO_DEV ? WRITE : READ;
+ unsigned char *long_cmdp = NULL;
SCSI_LOG_TIMEOUT(4, printk(KERN_INFO "sg_start_req: dxfer_len=%d\n",
dxfer_len));
+ if (hp->cmd_len > BLK_MAX_CDB) {
+ long_cmdp = kzalloc(hp->cmd_len, GFP_KERNEL);
+ if (!long_cmdp)
+ return -ENOMEM;
+ }
+
rq = blk_get_request(q, rw, GFP_ATOMIC);
- if (!rq)
+ if (!rq) {
+ kfree(long_cmdp);
return -ENOMEM;
+ }
- memcpy(rq->cmd, cmd, hp->cmd_len);
+ blk_rq_set_block_pc(rq);
+ if (hp->cmd_len > BLK_MAX_CDB)
+ rq->cmd = long_cmdp;
+ memcpy(rq->cmd, cmd, hp->cmd_len);
rq->cmd_len = hp->cmd_len;
- rq->cmd_type = REQ_TYPE_BLOCK_PC;
srp->rq = rq;
rq->end_io_data = srp;
@@ -1744,6 +1755,8 @@ static int sg_finish_rem_req(Sg_request * srp)
if (srp->bio)
ret = blk_rq_unmap_user(srp->bio);
+ if (srp->rq->cmd != srp->rq->__cmd)
+ kfree(srp->rq->cmd);
blk_put_request(srp->rq);
}
diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c
index a3eb263e032..b99047a19a2 100644
--- a/drivers/scsi/st.c
+++ b/drivers/scsi/st.c
@@ -488,7 +488,7 @@ static int st_scsi_execute(struct st_request *SRpnt, const unsigned char *cmd,
if (!req)
return DRIVER_ERROR << 24;
- req->cmd_type = REQ_TYPE_BLOCK_PC;
+ blk_rq_set_block_pc(req);
req->cmd_flags |= REQ_QUIET;
mdata->null_mapped = 1;
diff --git a/drivers/slimbus/slim-msm-ngd.c b/drivers/slimbus/slim-msm-ngd.c
index 0455cae605c..4c1a60205ac 100644
--- a/drivers/slimbus/slim-msm-ngd.c
+++ b/drivers/slimbus/slim-msm-ngd.c
@@ -1266,11 +1266,13 @@ static void ngd_adsp_down(struct work_struct *work)
struct slim_controller *ctrl = &dev->ctrl;
struct slim_device *sbdev;
+ mutex_lock(&dev->ssr_lock);
ngd_slim_enable(dev, false);
/* device up should be called again after SSR */
list_for_each_entry(sbdev, &ctrl->devs, dev_list)
slim_report_absent(sbdev);
SLIM_INFO(dev, "SLIM ADSP SSR (DOWN) done\n");
+ mutex_unlock(&dev->ssr_lock);
}
static void ngd_adsp_up(struct work_struct *work)
@@ -1279,7 +1281,9 @@ static void ngd_adsp_up(struct work_struct *work)
container_of(work, struct msm_slim_qmi, ssr_up);
struct msm_slim_ctrl *dev =
container_of(qmi, struct msm_slim_ctrl, qmi);
+ mutex_lock(&dev->ssr_lock);
ngd_slim_enable(dev, true);
+ mutex_unlock(&dev->ssr_lock);
}
static ssize_t show_mask(struct device *device, struct device_attribute *attr,
@@ -1433,6 +1437,7 @@ static int __devinit ngd_slim_probe(struct platform_device *pdev)
init_completion(&dev->ctrl_up);
mutex_init(&dev->tx_lock);
mutex_init(&dev->tx_buf_lock);
+ mutex_init(&dev->ssr_lock);
spin_lock_init(&dev->rx_lock);
dev->ee = 1;
dev->irq = irq->start;
diff --git a/drivers/slimbus/slim-msm.h b/drivers/slimbus/slim-msm.h
index 99297a95f45..91a739edc0a 100644
--- a/drivers/slimbus/slim-msm.h
+++ b/drivers/slimbus/slim-msm.h
@@ -256,6 +256,7 @@ struct msm_slim_ctrl {
struct clk *hclk;
struct mutex tx_lock;
struct mutex tx_buf_lock;
+ struct mutex ssr_lock;
u8 pgdla;
enum msm_slim_msgq use_rx_msgqs;
enum msm_slim_msgq use_tx_msgqs;
diff --git a/drivers/spmi/spmi-dbgfs.c b/drivers/spmi/spmi-dbgfs.c
index b0a354b59a5..86f1b0d889a 100644
--- a/drivers/spmi/spmi-dbgfs.c
+++ b/drivers/spmi/spmi-dbgfs.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
+/* Copyright (c) 2012-2014, 2017, The Linux Foundation. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -69,6 +69,7 @@ struct spmi_trans {
u32 addr; /* 20-bit address: SID + PID + Register offset */
u32 offset; /* Offset of last read data */
bool raw_data; /* Set to true for raw data dump */
+ struct mutex spmi_dfs_lock; /* Prevent thread concurrency */
struct spmi_controller *ctrl;
struct spmi_log_buffer *log; /* log buffer */
};
@@ -168,6 +169,7 @@ static int spmi_dfs_open(struct spmi_ctrl_data *ctrl_data, struct file *file)
trans->addr = ctrl_data->addr;
trans->ctrl = ctrl_data->ctrl;
trans->offset = trans->addr;
+ mutex_init(&trans->spmi_dfs_lock);
file->private_data = trans;
return 0;
@@ -197,6 +199,7 @@ static int spmi_dfs_close(struct inode *inode, struct file *file)
if (trans && trans->log) {
file->private_data = NULL;
+ mutex_destroy(&trans->spmi_dfs_lock);
kfree(trans->log);
kfree(trans);
}
@@ -473,14 +476,21 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
int cnt = 0;
u8 *values;
size_t ret = 0;
-
+ u32 offset;
+ char *kbuf;
struct spmi_trans *trans = file->private_data;
- u32 offset = trans->offset;
+
+ mutex_lock(&trans->spmi_dfs_lock);
+
+ trans = file->private_data;
+ offset = trans->offset;
/* Make a copy of the user data */
- char *kbuf = kmalloc(count + 1, GFP_KERNEL);
- if (!kbuf)
- return -ENOMEM;
+ kbuf = kmalloc(count + 1, GFP_KERNEL);
+ if (!kbuf) {
+ ret = -ENOMEM;
+ goto unlock_mutex;
+ }
ret = copy_from_user(kbuf, buf, count);
if (ret == count) {
@@ -517,6 +527,8 @@ static ssize_t spmi_dfs_reg_write(struct file *file, const char __user *buf,
free_buf:
kfree(kbuf);
+unlock_mutex:
+ mutex_unlock(&trans->spmi_dfs_lock);
return ret;
}
@@ -537,10 +549,13 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
size_t ret;
size_t len;
+ mutex_lock(&trans->spmi_dfs_lock);
/* Is the the log buffer empty */
if (log->rpos >= log->wpos) {
- if (get_log_data(trans) <= 0)
- return 0;
+ if (get_log_data(trans) <= 0) {
+ len = 0;
+ goto unlock_mutex;
+ }
}
len = min(count, log->wpos - log->rpos);
@@ -548,7 +563,8 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
ret = copy_to_user(buf, &log->data[log->rpos], len);
if (ret == len) {
pr_err("error copy SPMI register values to user\n");
- return -EFAULT;
+ len = -EFAULT;
+ goto unlock_mutex;
}
/* 'ret' is the number of bytes not copied */
@@ -556,6 +572,9 @@ static ssize_t spmi_dfs_reg_read(struct file *file, char __user *buf,
*ppos += len;
log->rpos += len;
+
+unlock_mutex:
+ mutex_unlock(&trans->spmi_dfs_lock);
return len;
}
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
index 58a5524fd77..a6eb85cfa0a 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_assoc.c
@@ -2652,7 +2652,7 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t
case eCSR_ROAM_RESULT_IBSS_NEW_PEER:
{
hdd_station_ctx_t *pHddStaCtx = WLAN_HDD_GET_STATION_CTX_PTR(pAdapter);
- struct station_info *staInfo;
+ struct station_info *stainfo;
pr_info ( "IBSS New Peer indication from SME "
"with peerMac " MAC_ADDRESS_STR " BSSID: " MAC_ADDRESS_STR " and stationID= %d",
@@ -2686,22 +2686,20 @@ static eHalStatus roamRoamConnectStatusUpdateHandler( hdd_adapter_t *pAdapter, t
vosStatus, vosStatus );
}
pHddStaCtx->ibss_sta_generation++;
-
- staInfo = vos_mem_malloc(sizeof(*staInfo));
- if (staInfo == NULL) {
+ stainfo = vos_mem_malloc(sizeof(*stainfo));
+ if (stainfo == NULL) {
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
"memory allocation for station_info failed");
return eHAL_STATUS_FAILED_ALLOC;
}
-
- memset(staInfo, 0, sizeof(*staInfo));
- staInfo->filled = 0;
- staInfo->generation = pHddStaCtx->ibss_sta_generation;
+ memset(stainfo, 0, sizeof(*stainfo));
+ stainfo->filled = 0;
+ stainfo->generation = pHddStaCtx->ibss_sta_generation;
cfg80211_new_sta(pAdapter->dev,
- (const u8 *)pRoamInfo->peerMac,
- staInfo, GFP_KERNEL);
- vos_mem_free(staInfo);
+ (const u8 *)pRoamInfo->peerMac,
+ stainfo, GFP_KERNEL);
+ vos_mem_free(stainfo);
if ( eCSR_ENCRYPT_TYPE_WEP40_STATICKEY == pHddStaCtx->ibss_enc_key.encType
||eCSR_ENCRYPT_TYPE_WEP104_STATICKEY == pHddStaCtx->ibss_enc_key.encType
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
index ebb6cd52bde..d64f2eb036d 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -3500,10 +3500,20 @@ static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
pReqMsg->numAp = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_BSSID_HOTLIST_PARAMS_NUM_AP]);
+ if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_HOTLIST_APS) {
+ hddLog(LOGE, FL("Number of AP: %u exceeds max: %u"),
+ pReqMsg->numAp, WLAN_EXTSCAN_MAX_HOTLIST_APS);
+ goto fail;
+ }
hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
nla_for_each_nested(apTh,
tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
+ if (i == pReqMsg->numAp) {
+ hddLog(LOGW, FL("Ignoring excess AP"));
+ break;
+ }
+
if(nla_parse(tb2, QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
nla_data(apTh), nla_len(apTh),
NULL)) {
@@ -3551,6 +3561,13 @@ static int __wlan_hdd_cfg80211_extscan_set_bssid_hotlist(struct wiphy *wiphy,
FL("Channel (%u)"), pReqMsg->ap[i].channel);
i++;
}
+
+ if (i < pReqMsg->numAp) {
+ hddLog(LOGW, FL("Number of AP %u less than expected %u"),
+ i, pReqMsg->numAp);
+ pReqMsg->numAp = i;
+ }
+
status = sme_SetBssHotlist(pHddCtx->hHal, pReqMsg);
if (!HAL_STATUS_SUCCESS(status)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -3678,6 +3695,11 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiph
}
pReqMsg->numAp = nla_get_u32(
tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_SIGNIFICANT_CHANGE_PARAMS_NUM_AP]);
+ if (pReqMsg->numAp > WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS) {
+ hddLog(LOGE, FL("Number of AP %u exceeds max %u"),
+ pReqMsg->numAp, WLAN_EXTSCAN_MAX_SIGNIFICANT_CHANGE_APS);
+ goto fail;
+ }
hddLog(VOS_TRACE_LEVEL_INFO, FL("Number of AP (%d)"), pReqMsg->numAp);
pReqMsg->sessionId = pAdapter->sessionId;
@@ -3685,6 +3707,12 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiph
nla_for_each_nested(apTh,
tb[QCA_WLAN_VENDOR_ATTR_EXTSCAN_AP_THRESHOLD_PARAM], rem) {
+
+ if (i == pReqMsg->numAp) {
+ hddLog(LOGW, FL("Ignoring excess AP"));
+ break;
+ }
+
if(nla_parse(tb2,
QCA_WLAN_VENDOR_ATTR_EXTSCAN_SUBCMD_CONFIG_PARAM_MAX,
nla_data(apTh), nla_len(apTh),
@@ -3733,6 +3761,12 @@ static int __wlan_hdd_cfg80211_extscan_set_significant_change(struct wiphy *wiph
i++;
}
+ if (i < pReqMsg->numAp) {
+ hddLog(LOGW, FL("Number of AP %u less than expected %u"),
+ i, pReqMsg->numAp);
+ pReqMsg->numAp = i;
+ }
+
status = sme_SetSignificantChange(pHddCtx->hHal, pReqMsg);
if (!HAL_STATUS_SUCCESS(status)) {
hddLog(VOS_TRACE_LEVEL_ERROR,
@@ -8817,6 +8851,15 @@ static int __wlan_hdd_change_station(struct wiphy *wiphy,
}
StaParams.supported_channels_len = j;
}
+ if (params->supported_oper_classes_len >
+ SIR_MAC_MAX_SUPP_OPER_CLASSES) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_INFO,
+ "received oper classes:%d, resetting it to max supported %d",
+ params->supported_oper_classes_len,
+ SIR_MAC_MAX_SUPP_OPER_CLASSES);
+ params->supported_oper_classes_len =
+ SIR_MAC_MAX_SUPP_OPER_CLASSES;
+ }
vos_mem_copy(StaParams.supported_oper_classes,
params->supported_oper_classes,
params->supported_oper_classes_len);
@@ -16572,6 +16615,12 @@ static int __wlan_hdd_cfg80211_testmode(struct wiphy *wiphy, void *data, int len
(hb_params_temp->params.lphbTcpParamReq.timePeriodSec == 0))
return -EINVAL;
+ if (buf_len > sizeof(*hb_params)) {
+ hddLog(LOGE, FL("buf_len=%d exceeded hb_params size limit"),
+ buf_len);
+ return -ERANGE;
+ }
+
hb_params = (tSirLPHBReq *)vos_mem_malloc(sizeof(tSirLPHBReq));
if (NULL == hb_params)
{
diff --git a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
index a1a31fa030c..3f37bf929a8 100644
--- a/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
+++ b/drivers/staging/prima/CORE/HDD/src/wlan_hdd_hostapd.c
@@ -1056,28 +1056,28 @@ VOS_STATUS hdd_hostapd_SAPEventCB( tpSap_Event pSapEvent, v_PVOID_t usrDataForCa
#endif
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38))
{
- struct station_info *staInfo;
v_U16_t iesLen = pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.iesLen;
- staInfo = vos_mem_malloc(sizeof(*staInfo));
- if (staInfo == NULL) {
- hddLog(LOGE, FL("alloc station_info failed"));
- return VOS_STATUS_E_NOMEM;
- }
-
- memset(staInfo, 0, sizeof(*staInfo));
if (iesLen <= MAX_ASSOC_IND_IE_LEN )
{
- staInfo->assoc_req_ies =
+ struct station_info *stainfo;
+ stainfo = vos_mem_malloc(sizeof(*stainfo));
+ if (stainfo == NULL) {
+ hddLog(LOGE, FL("alloc station_info failed"));
+ return VOS_STATUS_E_NOMEM;
+ }
+ memset(stainfo, 0, sizeof(*stainfo));
+
+ stainfo->assoc_req_ies =
(const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.ies[0];
- staInfo->assoc_req_ies_len = iesLen;
+ stainfo->assoc_req_ies_len = iesLen;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,0,31))
- staInfo->filled |= STATION_INFO_ASSOC_REQ_IES;
+ stainfo->filled |= STATION_INFO_ASSOC_REQ_IES;
#endif
cfg80211_new_sta(dev,
(const u8 *)&pSapEvent->sapevt.sapStationAssocReassocCompleteEvent.staMac.bytes[0],
- staInfo, GFP_KERNEL);
- vos_mem_free(staInfo);
+ stainfo, GFP_KERNEL);
+ vos_mem_free(stainfo);
}
else
{
@@ -3972,6 +3972,13 @@ static int __iw_set_ap_genie(struct net_device *dev,
return 0;
}
+ if (wrqu->data.length > DOT11F_IE_RSN_MAX_LEN) {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: WPARSN Ie input length is more than max[%d]", __func__,
+ wrqu->data.length);
+ return -EINVAL;
+ }
+
switch (genie[0])
{
case DOT11F_EID_WPA:
diff --git a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
index 89c509272ce..656533e2515 100644
--- a/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
+++ b/drivers/staging/prima/CORE/MAC/src/pe/sch/schBeaconProcess.c
@@ -469,8 +469,8 @@ static void __schBeaconProcessForSession( tpAniSirGlobal pMac,
sendProbeReq = TRUE;
}
- if ( psessionEntry->htCapability && pBeacon->HTInfo.present &&
- (!LIM_IS_IBSS_ROLE(psessionEntry)))
+ if (psessionEntry->htCapability && pBeacon->HTInfo.present &&
+ (!LIM_IS_IBSS_ROLE(psessionEntry)))
{
limUpdateStaRunTimeHTSwitchChnlParams( pMac, &pBeacon->HTInfo, bssIdx,psessionEntry);
}
diff --git a/drivers/target/target_core_pscsi.c b/drivers/target/target_core_pscsi.c
index ec7e71c1e86..6ae813d4456 100644
--- a/drivers/target/target_core_pscsi.c
+++ b/drivers/target/target_core_pscsi.c
@@ -1085,6 +1085,8 @@ static int pscsi_do_task(struct se_task *task)
TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE;
return -ENODEV;
}
+
+ blk_rq_set_block_pc(req);
} else {
BUG_ON(!task->task_size);
@@ -1106,7 +1108,6 @@ static int pscsi_do_task(struct se_task *task)
}
}
- req->cmd_type = REQ_TYPE_BLOCK_PC;
req->end_io = pscsi_req_done;
req->end_io_data = task;
req->cmd_len = scsi_command_size(pt->pscsi_cdb);
diff --git a/drivers/usb/serial/cypress_m8.c b/drivers/usb/serial/cypress_m8.c
index b1b846752c4..ce0aea593f2 100644
--- a/drivers/usb/serial/cypress_m8.c
+++ b/drivers/usb/serial/cypress_m8.c
@@ -464,6 +464,11 @@ static int generic_startup(struct usb_serial *serial)
dbg("%s - port %d", __func__, port->number);
+ if (!port->interrupt_out_urb || !port->interrupt_in_urb) {
+ dev_err(&port->dev, "required endpoint is missing\n");
+ return -ENODEV;
+ }
+
priv = kzalloc(sizeof(struct cypress_private), GFP_KERNEL);
if (!priv)
return -ENOMEM;
@@ -633,12 +638,6 @@ static int cypress_open(struct tty_struct *tty, struct usb_serial_port *port)
cypress_set_termios(tty, port, &priv->tmp_termios);
/* setup the port and start reading from the device */
- if (!port->interrupt_in_urb) {
- dev_err(&port->dev, "%s - interrupt_in_urb is empty!\n",
- __func__);
- return -1;
- }
-
usb_fill_int_urb(port->interrupt_in_urb, serial->dev,
usb_rcvintpipe(serial->dev, port->interrupt_in_endpointAddress),
port->interrupt_in_urb->transfer_buffer,
diff --git a/fs/9p/acl.c b/fs/9p/acl.c
index 9a1d4263075..a4188cfcc9f 100644
--- a/fs/9p/acl.c
+++ b/fs/9p/acl.c
@@ -319,32 +319,26 @@ static int v9fs_xattr_set_acl(struct dentry *dentry, const char *name,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- umode_t mode = inode->i_mode;
- retval = posix_acl_equiv_mode(acl, &mode);
- if (retval < 0)
+ struct iattr iattr;
+
+ retval = posix_acl_update_mode(inode, &iattr.ia_mode, &acl);
+ if (retval)
goto err_out;
- else {
- struct iattr iattr;
- if (retval == 0) {
- /*
- * ACL can be represented
- * by the mode bits. So don't
- * update ACL.
- */
- acl = NULL;
- value = NULL;
- size = 0;
- }
- /* Updte the mode bits */
- iattr.ia_mode = ((mode & S_IALLUGO) |
- (inode->i_mode & ~S_IALLUGO));
- iattr.ia_valid = ATTR_MODE;
- /* FIXME should we update ctime ?
- * What is the following setxattr update the
- * mode ?
+ if (!acl) {
+ /*
+ * ACL can be represented
+ * by the mode bits. So don't
+ * update ACL.
*/
- v9fs_vfs_setattr_dotl(dentry, &iattr);
+ value = NULL;
+ size = 0;
}
+ iattr.ia_valid = ATTR_MODE;
+ /* FIXME should we update ctime ?
+ * What is the following setxattr update the
+ * mode ?
+ */
+ v9fs_vfs_setattr_dotl(dentry, &iattr);
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/btrfs/acl.c b/fs/btrfs/acl.c
index 89b156d85d6..9f55b545ea4 100644
--- a/fs/btrfs/acl.c
+++ b/fs/btrfs/acl.c
@@ -118,8 +118,8 @@ static int btrfs_set_acl(struct btrfs_trans_handle *trans,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- ret = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (ret < 0)
+ ret = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (ret)
return ret;
}
ret = 0;
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 805be43324a..ef830491326 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -146,6 +146,15 @@ static int read_or_initialize_metadata(struct dentry *dentry)
struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
struct ecryptfs_crypt_stat *crypt_stat;
int rc;
+ struct file *lower_file = ecryptfs_file_to_lower(file);
+
+ /*
+ * Don't allow mmap on top of file systems that don't support it
+ * natively. If FILESYSTEM_MAX_STACK_DEPTH > 2 or ecryptfs
+ * allows recursive mounting, this will need to be extended.
+ */
+ if (!lower_file->f_op->mmap)
+ return -ENODEV;
crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
mount_crypt_stat = &ecryptfs_superblock_to_private(
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index 93b7bec021b..81e69c7a74b 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -576,6 +576,13 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags
s->s_maxbytes = path.dentry->d_sb->s_maxbytes;
s->s_blocksize = path.dentry->d_sb->s_blocksize;
s->s_magic = ECRYPTFS_SUPER_MAGIC;
+ s->s_stack_depth = path.dentry->d_sb->s_stack_depth + 1;
+
+ rc = -EINVAL;
+ if (s->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
+ pr_err("eCryptfs: maximum fs stacking depth exceeded\n");
+ goto out_free;
+ }
inode = ecryptfs_get_inode(path.dentry->d_inode, s);
rc = PTR_ERR(inode);
diff --git a/fs/exec.c b/fs/exec.c
index a4d05ce9248..73e9bd4d46e 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1591,6 +1591,11 @@ static int do_execve_common(const char *filename,
if (retval < 0)
goto out;
+ if (d_is_su(file->f_dentry) && capable(CAP_SYS_ADMIN)) {
+ current->flags |= PF_SU;
+ su_exec();
+ }
+
/* execve succeeded */
current->fs->in_exec = 0;
current->in_execve = 0;
diff --git a/fs/ext2/acl.c b/fs/ext2/acl.c
index 35d6a3cfd9f..e38a9b61af3 100644
--- a/fs/ext2/acl.c
+++ b/fs/ext2/acl.c
@@ -194,15 +194,11 @@ ext2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
case ACL_TYPE_ACCESS:
name_index = EXT2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = CURRENT_TIME_SEC;
- mark_inode_dirty(inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = CURRENT_TIME_SEC;
+ mark_inode_dirty(inode);
}
break;
diff --git a/fs/ext3/acl.c b/fs/ext3/acl.c
index c76832c8d19..f3326ca3415 100644
--- a/fs/ext3/acl.c
+++ b/fs/ext3/acl.c
@@ -193,15 +193,11 @@ ext3_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT3_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = CURRENT_TIME_SEC;
- ext3_mark_inode_dirty(handle, inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = CURRENT_TIME_SEC;
+ ext3_mark_inode_dirty(handle, inode);
}
break;
diff --git a/fs/ext4/acl.c b/fs/ext4/acl.c
index 8535c45dfce..5d419a496d9 100644
--- a/fs/ext4/acl.c
+++ b/fs/ext4/acl.c
@@ -198,15 +198,11 @@ ext4_set_acl(handle_t *handle, struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = EXT4_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- inode->i_ctime = ext4_current_time(inode);
- ext4_mark_inode_dirty(handle, inode);
- if (error == 0)
- acl = NULL;
- }
+ inode->i_ctime = ext4_current_time(inode);
+ ext4_mark_inode_dirty(handle, inode);
}
break;
diff --git a/fs/f2fs/acl.c b/fs/f2fs/acl.c
index f431f992555..962e4e98e8a 100644
--- a/fs/f2fs/acl.c
+++ b/fs/f2fs/acl.c
@@ -211,8 +211,8 @@ static int f2fs_set_acl(struct inode *inode, int type,
case ACL_TYPE_ACCESS:
name_index = F2FS_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
set_acl_inode(inode, inode->i_mode);
if (error == 0)
diff --git a/fs/generic_acl.c b/fs/generic_acl.c
index d0dddaceac5..e9c0746e820 100644
--- a/fs/generic_acl.c
+++ b/fs/generic_acl.c
@@ -87,14 +87,10 @@ generic_acl_set(struct dentry *dentry, const char *name, const void *value,
goto failed;
switch (type) {
case ACL_TYPE_ACCESS:
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
goto failed;
inode->i_ctime = CURRENT_TIME;
- if (error == 0) {
- posix_acl_release(acl);
- acl = NULL;
- }
break;
case ACL_TYPE_DEFAULT:
if (!S_ISDIR(inode->i_mode)) {
diff --git a/fs/gfs2/acl.c b/fs/gfs2/acl.c
index 230eb0f005b..846611f2e41 100644
--- a/fs/gfs2/acl.c
+++ b/fs/gfs2/acl.c
@@ -274,15 +274,10 @@ static int gfs2_xattr_system_set(struct dentry *dentry, const char *name,
if (type == ACL_TYPE_ACCESS) {
umode_t mode = inode->i_mode;
- error = posix_acl_equiv_mode(acl, &mode);
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
- if (error <= 0) {
- posix_acl_release(acl);
- acl = NULL;
-
- if (error < 0)
- return error;
- }
+ if (error)
+ goto out_release;
error = gfs2_set_mode(inode, mode);
if (error)
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 922f146e423..398e5c71c50 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -229,9 +229,10 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
case ACL_TYPE_ACCESS:
xprefix = JFFS2_XPREFIX_ACL_ACCESS;
if (acl) {
- umode_t mode = inode->i_mode;
- rc = posix_acl_equiv_mode(acl, &mode);
- if (rc < 0)
+ umode_t mode;
+
+ rc = posix_acl_update_mode(inode, &mode, &acl);
+ if (rc)
return rc;
if (inode->i_mode != mode) {
struct iattr attr;
@@ -243,8 +244,6 @@ static int jffs2_set_acl(struct inode *inode, int type, struct posix_acl *acl)
if (rc < 0)
return rc;
}
- if (rc == 0)
- acl = NULL;
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/jfs/xattr.c b/fs/jfs/xattr.c
index 26683e15b3a..41a0735314f 100644
--- a/fs/jfs/xattr.c
+++ b/fs/jfs/xattr.c
@@ -693,11 +693,11 @@ static int can_set_system_xattr(struct inode *inode, const char *name,
return rc;
}
if (acl) {
- rc = posix_acl_equiv_mode(acl, &inode->i_mode);
+ rc = posix_acl_update_mode(inode, &inode->i_mode, &acl);
posix_acl_release(acl);
- if (rc < 0) {
+ if (rc) {
printk(KERN_ERR
- "posix_acl_equiv_mode returned %d\n",
+ "posix_acl_update_mode returned %d\n",
rc);
return rc;
}
diff --git a/fs/namei.c b/fs/namei.c
index df12b576c21..689339e3e7e 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -1800,6 +1800,16 @@ static int path_lookupat(int dfd, const char *name,
}
}
+ if (!err) {
+ struct super_block *sb = nd->inode->i_sb;
+ if (sb->s_flags & MS_RDONLY) {
+ if (d_is_su(nd->path.dentry) && !su_visible()) {
+ path_put(&nd->path);
+ err = -ENOENT;
+ }
+ }
+ }
+
if (base)
fput(base);
diff --git a/fs/ocfs2/acl.c b/fs/ocfs2/acl.c
index a7219075b4d..eed868e9a89 100644
--- a/fs/ocfs2/acl.c
+++ b/fs/ocfs2/acl.c
@@ -248,19 +248,13 @@ static int ocfs2_set_acl(handle_t *handle,
name_index = OCFS2_XATTR_INDEX_POSIX_ACL_ACCESS;
if (acl) {
umode_t mode = inode->i_mode;
- ret = posix_acl_equiv_mode(acl, &mode);
- if (ret < 0)
+ ret = posix_acl_update_mode(inode, &mode, &acl);
+ if (ret)
+ return ret;
+ ret = ocfs2_acl_set_mode(inode, di_bh,
+ handle, mode);
+ if (ret)
return ret;
- else {
- if (ret == 0)
- acl = NULL;
-
- ret = ocfs2_acl_set_mode(inode, di_bh,
- handle, mode);
- if (ret)
- return ret;
-
- }
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/posix_acl.c b/fs/posix_acl.c
index 64496020bf1..9607a1df282 100644
--- a/fs/posix_acl.c
+++ b/fs/posix_acl.c
@@ -341,6 +341,35 @@ static int posix_acl_create_masq(struct posix_acl *acl, umode_t *mode_p)
return not_equiv;
}
+/**
+ * posix_acl_update_mode - update mode in set_acl
+ *
+ * Update the file mode when setting an ACL: compute the new file permission
+ * bits based on the ACL. In addition, if the ACL is equivalent to the new
+ * file mode, set *acl to NULL to indicate that no ACL should be set.
+ *
+ * As with chmod, clear the setgit bit if the caller is not in the owning group
+ * or capable of CAP_FSETID (see inode_change_ok).
+ *
+ * Called from set_acl inode operations.
+ */
+int posix_acl_update_mode(struct inode *inode, umode_t *mode_p,
+ struct posix_acl **acl)
+{
+ umode_t mode = inode->i_mode;
+ int error;
+
+ error = posix_acl_update_mode(inode, &inode->i_mode, acl);
+ if (error)
+ return error;
+ if (!in_group_p(inode->i_gid) &&
+ !capable(CAP_FSETID))
+ mode &= ~S_ISGID;
+ *mode_p = mode;
+ return 0;
+}
+EXPORT_SYMBOL(posix_acl_update_mode);
+
/*
* Modify the ACL for the chmod syscall.
*/
diff --git a/fs/proc/array.c b/fs/proc/array.c
index e7bb0fed720..607f80c8d50 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -166,16 +166,16 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
int g;
struct fdtable *fdt = NULL;
const struct cred *cred;
- pid_t ppid, tpid;
+ pid_t ppid = 0, tpid = 0;
+ struct task_struct *leader = NULL;
rcu_read_lock();
- ppid = pid_alive(p) ?
- task_tgid_nr_ns(rcu_dereference(p->real_parent), ns) : 0;
- tpid = 0;
if (pid_alive(p)) {
struct task_struct *tracer = ptrace_parent(p);
if (tracer)
tpid = task_pid_nr_ns(tracer, ns);
+ ppid = task_tgid_nr_ns(rcu_dereference(p->real_parent), ns);
+ leader = p->group_leader;
}
cred = get_task_cred(p);
seq_printf(m,
@@ -187,7 +187,7 @@ static inline void task_state(struct seq_file *m, struct pid_namespace *ns,
"Uid:\t%d\t%d\t%d\t%d\n"
"Gid:\t%d\t%d\t%d\t%d\n",
get_task_state(p),
- task_tgid_nr_ns(p, ns),
+ leader ? task_pid_nr_ns(leader, ns) : 0,
pid_nr_ns(pid, ns),
ppid, tpid,
cred->uid, cred->euid, cred->suid, cred->fsuid,
diff --git a/fs/readdir.c b/fs/readdir.c
index cc0a8227cdd..536054080bc 100644
--- a/fs/readdir.c
+++ b/fs/readdir.c
@@ -47,6 +47,14 @@ out:
EXPORT_SYMBOL(vfs_readdir);
+static bool hide_name(const char *name, int namlen)
+{
+ if (namlen == 2 && !memcmp(name, "su", 2))
+ if (!su_visible())
+ return true;
+ return false;
+}
+
/*
* Traditional linux readdir() handling..
*
@@ -68,6 +76,7 @@ struct old_linux_dirent {
struct readdir_callback {
struct old_linux_dirent __user * dirent;
int result;
+ bool romnt;
};
static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset,
@@ -84,6 +93,8 @@ static int fillonedir(void * __buf, const char * name, int namlen, loff_t offset
buf->result = -EOVERFLOW;
return -EOVERFLOW;
}
+ if (hide_name(name, namlen) && buf->romnt)
+ return 0;
buf->result++;
dirent = buf->dirent;
if (!access_ok(VERIFY_WRITE, dirent,
@@ -116,6 +127,7 @@ SYSCALL_DEFINE3(old_readdir, unsigned int, fd,
buf.result = 0;
buf.dirent = dirent;
+ buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY);
error = vfs_readdir(file, fillonedir, &buf);
if (buf.result)
@@ -144,6 +156,7 @@ struct getdents_callback {
struct linux_dirent __user * previous;
int count;
int error;
+ bool romnt;
};
static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
@@ -163,6 +176,8 @@ static int filldir(void * __buf, const char * name, int namlen, loff_t offset,
buf->error = -EOVERFLOW;
return -EOVERFLOW;
}
+ if (hide_name(name, namlen) && buf->romnt)
+ return 0;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
@@ -210,6 +225,7 @@ SYSCALL_DEFINE3(getdents, unsigned int, fd,
buf.previous = NULL;
buf.count = count;
buf.error = 0;
+ buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY);
error = vfs_readdir(file, filldir, &buf);
if (error >= 0)
@@ -231,6 +247,7 @@ struct getdents_callback64 {
struct linux_dirent64 __user * previous;
int count;
int error;
+ bool romnt;
};
static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
@@ -244,6 +261,8 @@ static int filldir64(void * __buf, const char * name, int namlen, loff_t offset,
buf->error = -EINVAL; /* only used if we fail.. */
if (reclen > buf->count)
return -EINVAL;
+ if (hide_name(name, namlen) && buf->romnt)
+ return 0;
dirent = buf->previous;
if (dirent) {
if (__put_user(offset, &dirent->d_off))
@@ -293,6 +312,7 @@ SYSCALL_DEFINE3(getdents64, unsigned int, fd,
buf.previous = NULL;
buf.count = count;
buf.error = 0;
+ buf.romnt = (file->f_path.dentry->d_sb->s_flags & MS_RDONLY);
error = vfs_readdir(file, filldir64, &buf);
if (error >= 0)
diff --git a/fs/reiserfs/xattr_acl.c b/fs/reiserfs/xattr_acl.c
index 44474f9b990..502254b6432 100644
--- a/fs/reiserfs/xattr_acl.c
+++ b/fs/reiserfs/xattr_acl.c
@@ -272,13 +272,9 @@ reiserfs_set_acl(struct reiserfs_transaction_handle *th, struct inode *inode,
case ACL_TYPE_ACCESS:
name = POSIX_ACL_XATTR_ACCESS;
if (acl) {
- error = posix_acl_equiv_mode(acl, &inode->i_mode);
- if (error < 0)
+ error = posix_acl_update_mode(inode, &inode->i_mode, &acl);
+ if (error)
return error;
- else {
- if (error == 0)
- acl = NULL;
- }
}
break;
case ACL_TYPE_DEFAULT:
diff --git a/fs/sdcardfs/main.c b/fs/sdcardfs/main.c
index d46970095cb..97375a13ba1 100644
--- a/fs/sdcardfs/main.c
+++ b/fs/sdcardfs/main.c
@@ -223,6 +223,13 @@ static int sdcardfs_read_super(struct super_block *sb, const char *dev_name,
atomic_inc(&lower_sb->s_active);
sdcardfs_set_lower_super(sb, lower_sb);
+ sb->s_stack_depth = lower_sb->s_stack_depth + 1;
+ if (sb->s_stack_depth > FILESYSTEM_MAX_STACK_DEPTH) {
+ pr_err("sdcardfs: maximum fs stacking depth exceeded\n");
+ err = -EINVAL;
+ goto out_sput;
+ }
+
/* inherit maxbytes from lower file system */
sb->s_maxbytes = lower_sb->s_maxbytes;
diff --git a/fs/xfs/xfs_acl.c b/fs/xfs/xfs_acl.c
index ac702a6eab9..c0f97c319b7 100644
--- a/fs/xfs/xfs_acl.c
+++ b/fs/xfs/xfs_acl.c
@@ -384,16 +384,9 @@ xfs_xattr_acl_set(struct dentry *dentry, const char *name,
if (type == ACL_TYPE_ACCESS) {
umode_t mode = inode->i_mode;
- error = posix_acl_equiv_mode(acl, &mode);
-
- if (error <= 0) {
- posix_acl_release(acl);
- acl = NULL;
-
- if (error < 0)
- return error;
- }
-
+ error = posix_acl_update_mode(inode, &mode, &acl);
+ if (error)
+ goto out_release;
error = xfs_set_mode(inode, mode);
if (error)
goto out_release;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index af67ecf1a5b..7f3196e272c 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -683,6 +683,7 @@ extern void __blk_put_request(struct request_queue *, struct request *);
extern struct request *blk_get_request(struct request_queue *, int, gfp_t);
extern struct request *blk_make_request(struct request_queue *, struct bio *,
gfp_t);
+extern void blk_rq_set_block_pc(struct request *);
extern void blk_requeue_request(struct request_queue *, struct request *);
extern int blk_reinsert_request(struct request_queue *q, struct request *rq);
extern bool blk_reinsert_req_sup(struct request_queue *q);
diff --git a/include/linux/dcache.h b/include/linux/dcache.h
index 92e9d197a68..9c38de0a6a4 100644
--- a/include/linux/dcache.h
+++ b/include/linux/dcache.h
@@ -403,6 +403,13 @@ static inline bool d_need_lookup(struct dentry *dentry)
extern void d_clear_need_lookup(struct dentry *dentry);
+static inline bool d_is_su(const struct dentry *dentry)
+{
+ return dentry &&
+ dentry->d_name.len == 2 &&
+ !memcmp(dentry->d_name.name, "su", 2);
+}
+
extern int sysctl_vfs_cache_pressure;
#endif /* __LINUX_DCACHE_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index b35e178b077..93aea6db689 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -528,6 +528,12 @@ struct iattr {
*/
#include <linux/quota.h>
+/*
+ * Maximum number of layers of fs stack. Needs to be limited to
+ * prevent kernel stack overflow
+ */
+#define FILESYSTEM_MAX_STACK_DEPTH 2
+
/**
* enum positive_aop_returns - aop return codes with specific semantics
*
@@ -1547,6 +1553,11 @@ struct super_block {
/* Being remounted read-only */
int s_readonly_remount;
+
+ /*
+ * Indicates how deep in a filesystem stack this SB is
+ */
+ int s_stack_depth;
};
/* superblock cache pruning functions */
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h
index 87d5f56495a..08c0307260e 100644
--- a/include/linux/perf_event.h
+++ b/include/linux/perf_event.h
@@ -1002,11 +1002,6 @@ struct perf_event {
#endif /* CONFIG_PERF_EVENTS */
};
-enum perf_event_context_type {
- task_context,
- cpu_context,
-};
-
/**
* struct perf_event_context - event context structure
*
@@ -1014,7 +1009,6 @@ enum perf_event_context_type {
*/
struct perf_event_context {
struct pmu *pmu;
- enum perf_event_context_type type;
/*
* Protect the states of the events in the list,
* nr_active, and the list:
diff --git a/include/linux/posix_acl.h b/include/linux/posix_acl.h
index 11bad91c443..9c4bbc29e30 100644
--- a/include/linux/posix_acl.h
+++ b/include/linux/posix_acl.h
@@ -84,6 +84,7 @@ extern struct posix_acl *posix_acl_from_mode(umode_t, gfp_t);
extern int posix_acl_equiv_mode(const struct posix_acl *, umode_t *);
extern int posix_acl_create(struct posix_acl **, gfp_t, umode_t *);
extern int posix_acl_chmod(struct posix_acl **, gfp_t, umode_t);
+extern int posix_acl_update_mode(struct inode *, umode_t *, struct posix_acl **);
extern struct posix_acl *get_posix_acl(struct inode *, int);
extern int set_posix_acl(struct inode *, int, struct posix_acl *);
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 16386d19945..37ad866215d 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -93,6 +93,12 @@ struct sched_param {
#include <asm/processor.h>
+int su_instances(void);
+bool su_running(void);
+bool su_visible(void);
+void su_exec(void);
+void su_exit(void);
+
struct exec_domain;
struct futex_pi_state;
struct robust_list_head;
@@ -1870,6 +1876,8 @@ extern int task_free_unregister(struct notifier_block *n);
#define PF_MUTEX_TESTER 0x20000000 /* Thread belongs to the rt mutex tester */
#define PF_FREEZER_SKIP 0x40000000 /* Freezer should not count it as freezable */
+#define PF_SU 0x80000000 /* task is su */
+
/*
* Only the _current_ task can read/write to tsk->flags, but other
* tasks can access tsk->flags in readonly mode for example
diff --git a/include/scsi/sg.h b/include/scsi/sg.h
index a9f3c6fc3f5..d8c0c4307fc 100644
--- a/include/scsi/sg.h
+++ b/include/scsi/sg.h
@@ -4,77 +4,34 @@
#include <linux/compiler.h>
/*
- History:
- Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
- process control of SCSI devices.
- Development Sponsored by Killy Corp. NY NY
-Original driver (sg.h):
-* Copyright (C) 1992 Lawrence Foard
-Version 2 and 3 extensions to driver:
-* Copyright (C) 1998 - 2006 Douglas Gilbert
-
- Version: 3.5.34 (20060920)
- This version is for 2.6 series kernels.
-
- For a full changelog see http://www.torque.net/sg
-
-Map of SG verions to the Linux kernels in which they appear:
- ---------- ----------------------------------
- original all kernels < 2.2.6
- 2.1.40 2.2.20
- 3.0.x optional version 3 sg driver for 2.2 series
- 3.1.17++ 2.4.0++
- 3.5.30++ 2.6.0++
-
-Major new features in SG 3.x driver (cf SG 2.x drivers)
- - SG_IO ioctl() combines function if write() and read()
- - new interface (sg_io_hdr_t) but still supports old interface
- - scatter/gather in user space, direct IO, and mmap supported
-
- The normal action of this driver is to use the adapter (HBA) driver to DMA
- data into kernel buffers and then use the CPU to copy the data into the
- user space (vice versa for writes). That is called "indirect" IO due to
- the double handling of data. There are two methods offered to remove the
- redundant copy: 1) direct IO and 2) using the mmap() system call to map
- the reserve buffer (this driver has one reserve buffer per fd) into the
- user space. Both have their advantages.
- In terms of absolute speed mmap() is faster. If speed is not a concern,
- indirect IO should be fine. Read the documentation for more information.
-
- ** N.B. To use direct IO 'echo 1 > /proc/scsi/sg/allow_dio' or
- 'echo 1 > /sys/module/sg/parameters/allow_dio' is needed.
- That attribute is 0 by default. **
-
- Historical note: this SCSI pass-through driver has been known as "sg" for
- a decade. In broader kernel discussions "sg" is used to refer to scatter
- gather techniques. The context should clarify which "sg" is referred to.
-
- Documentation
- =============
- A web site for the SG device driver can be found at:
- http://www.torque.net/sg [alternatively check the MAINTAINERS file]
- The documentation for the sg version 3 driver can be found at:
- http://www.torque.net/sg/p/sg_v3_ho.html
- This is a rendering from DocBook source [change the extension to "sgml"
- or "xml"]. There are renderings in "ps", "pdf", "rtf" and "txt" (soon).
- The SG_IO ioctl is now found in other parts kernel (e.g. the block layer).
- For more information see http://www.torque.net/sg/sg_io.html
-
- The older, version 2 documents discuss the original sg interface in detail:
- http://www.torque.net/sg/p/scsi-generic.txt
- http://www.torque.net/sg/p/scsi-generic_long.txt
- Also available: <kernel_source>/Documentation/scsi/scsi-generic.txt
-
- Utility and test programs are available at the sg web site. They are
- packaged as sg3_utils (for the lk 2.4 and 2.6 series) and sg_utils
- (for the lk 2.2 series).
-*/
+ * History:
+ * Started: Aug 9 by Lawrence Foard (entropy@world.std.com), to allow user
+ * process control of SCSI devices.
+ * Development Sponsored by Killy Corp. NY NY
+ *
+ * Original driver (sg.h):
+ * Copyright (C) 1992 Lawrence Foard
+ * Version 2 and 3 extensions to driver:
+ * Copyright (C) 1998 - 2014 Douglas Gilbert
+ *
+ * Version: 3.5.36 (20140603)
+ * This version is for 2.6 and 3 series kernels.
+ *
+ * Documentation
+ * =============
+ * A web site for the SG device driver can be found at:
+ * http://sg.danny.cz/sg [alternatively check the MAINTAINERS file]
+ * The documentation for the sg version 3 driver can be found at:
+ * http://sg.danny.cz/sg/p/sg_v3_ho.html
+ * Also see: <kernel_source>/Documentation/scsi/scsi-generic.txt
+ *
+ * For utility and test programs see: http://sg.danny.cz/sg/sg3_utils.html
+ */
#ifdef __KERNEL__
extern int sg_big_buff; /* for sysctl */
#endif
-/* New interface introduced in the 3.x SG drivers follows */
typedef struct sg_iovec /* same structure as used by readv() Linux system */
{ /* call. It defines one scatter-gather element. */
@@ -87,7 +44,7 @@ typedef struct sg_io_hdr
{
int interface_id; /* [i] 'S' for SCSI generic (required) */
int dxfer_direction; /* [i] data transfer direction */
- unsigned char cmd_len; /* [i] SCSI command length ( <= 16 bytes) */
+ unsigned char cmd_len; /* [i] SCSI command length */
unsigned char mx_sb_len; /* [i] max length to write to sbp */
unsigned short iovec_count; /* [i] 0 implies no scatter gather */
unsigned int dxfer_len; /* [i] byte count of data transfer */
diff --git a/kernel/events/core.c b/kernel/events/core.c
index f06d8db54db..70cdda89939 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -6143,7 +6143,6 @@ skip_type:
__perf_event_init_context(&cpuctx->ctx);
lockdep_set_class(&cpuctx->ctx.mutex, &cpuctx_mutex);
lockdep_set_class(&cpuctx->ctx.lock, &cpuctx_lock);
- cpuctx->ctx.type = cpu_context;
cpuctx->ctx.pmu = pmu;
cpuctx->jiffies_interval = 1;
INIT_LIST_HEAD(&cpuctx->rotation_list);
@@ -6783,7 +6782,19 @@ SYSCALL_DEFINE5(perf_event_open,
* task or CPU context:
*/
if (move_group) {
- if (group_leader->ctx->type != ctx->type)
+ /*
+ * Make sure we're both on the same task, or both
+ * per-cpu events.
+ */
+ if (group_leader->ctx->task != ctx->task)
+ goto err_context;
+
+ /*
+ * Make sure we're both events for the same CPU;
+ * grouping events for different CPUs is broken; since
+ * you can never concurrently schedule them anyhow.
+ */
+ if (group_leader->cpu != event->cpu)
goto err_context;
} else {
if (group_leader->ctx != ctx)
diff --git a/kernel/exit.c b/kernel/exit.c
index f28427b2f95..3eafd262e52 100644
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -957,6 +957,11 @@ void do_exit(long code)
}
exit_signals(tsk); /* sets PF_EXITING */
+
+ if (tsk->flags & PF_SU) {
+ su_exit();
+ }
+
/*
* tsk->flags are checked in the futex code to protect against
* an exiting task cleaning up the robust pi futexes.
diff --git a/kernel/fork.c b/kernel/fork.c
index 75dc3dd46f8..23695d2476e 100644
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -295,6 +295,8 @@ static struct task_struct *dup_task_struct(struct task_struct *orig)
if (err)
goto out;
+ tsk->flags &= ~PF_SU;
+
tsk->stack = ti;
#ifdef CONFIG_SECCOMP
/*
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index ce9cd7bb9d0..037efc35a62 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -89,6 +89,38 @@
#define CREATE_TRACE_POINTS
#include <trace/events/sched.h>
+static atomic_t __su_instances;
+
+int su_instances(void)
+{
+ return atomic_read(&__su_instances);
+}
+
+bool su_running(void)
+{
+ return su_instances() > 0;
+}
+
+bool su_visible(void)
+{
+ uid_t uid = current_uid();
+ if (su_running())
+ return true;
+ if (uid == 0 || uid == 1000)
+ return true;
+ return false;
+}
+
+void su_exec(void)
+{
+ atomic_inc(&__su_instances);
+}
+
+void su_exit(void)
+{
+ atomic_dec(&__su_instances);
+}
+
ATOMIC_NOTIFIER_HEAD(migration_notifier_head);
void start_bandwidth_timer(struct hrtimer *period_timer, ktime_t period)
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 71e7c1e6ac5..44521206f71 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -1454,7 +1454,6 @@ asmlinkage long compat_sys_get_mempolicy(int __user *policy,
asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
compat_ulong_t maxnode)
{
- long err = 0;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
DECLARE_BITMAP(bm, MAX_NUMNODES);
@@ -1463,14 +1462,13 @@ asmlinkage long compat_sys_set_mempolicy(int mode, compat_ulong_t __user *nmask,
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
- err = compat_get_bitmap(bm, nmask, nr_bits);
+ if (compat_get_bitmap(bm, nmask, nr_bits))
+ return -EFAULT;
nm = compat_alloc_user_space(alloc_size);
- err |= copy_to_user(nm, bm, alloc_size);
+ if (copy_to_user(nm, bm, alloc_size))
+ return -EFAULT;
}
- if (err)
- return -EFAULT;
-
return sys_set_mempolicy(mode, nm, nr_bits+1);
}
@@ -1478,7 +1476,6 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
compat_ulong_t mode, compat_ulong_t __user *nmask,
compat_ulong_t maxnode, compat_ulong_t flags)
{
- long err = 0;
unsigned long __user *nm = NULL;
unsigned long nr_bits, alloc_size;
nodemask_t bm;
@@ -1487,14 +1484,13 @@ asmlinkage long compat_sys_mbind(compat_ulong_t start, compat_ulong_t len,
alloc_size = ALIGN(nr_bits, BITS_PER_LONG) / 8;
if (nmask) {
- err = compat_get_bitmap(nodes_addr(bm), nmask, nr_bits);
+ if (compat_get_bitmap(nodes_addr(bm), nmask, nr_bits))
+ return -EFAULT;
nm = compat_alloc_user_space(alloc_size);
- err |= copy_to_user(nm, nodes_addr(bm), alloc_size);
+ if (copy_to_user(nm, nodes_addr(bm), alloc_size))
+ return -EFAULT;
}
- if (err)
- return -EFAULT;
-
return sys_mbind(start, len, mode, nm, nr_bits+1, flags);
}
diff --git a/mm/migrate.c b/mm/migrate.c
index c18e80413e1..73287433c90 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -30,6 +30,7 @@
#include <linux/mempolicy.h>
#include <linux/vmalloc.h>
#include <linux/security.h>
+#include <linux/backing-dev.h>
#include <linux/memcontrol.h>
#include <linux/syscalls.h>
#include <linux/hugetlb.h>
@@ -295,6 +296,8 @@ static int migrate_page_move_mapping(struct address_space *mapping,
struct page *newpage, struct page *page,
struct buffer_head *head, enum migrate_mode mode)
{
+ struct zone *oldzone, *newzone;
+ int dirty;
int expected_count;
void **pslot;
@@ -305,6 +308,9 @@ static int migrate_page_move_mapping(struct address_space *mapping,
return 0;
}
+ oldzone = page_zone(page);
+ newzone = page_zone(newpage);
+
spin_lock_irq(&mapping->tree_lock);
pslot = radix_tree_lookup_slot(&mapping->page_tree,
@@ -345,6 +351,13 @@ static int migrate_page_move_mapping(struct address_space *mapping,
set_page_private(newpage, page_private(page));
}
+ /* Move dirty while page refs frozen and newpage not yet exposed */
+ dirty = PageDirty(page);
+ if (dirty) {
+ ClearPageDirty(page);
+ SetPageDirty(newpage);
+ }
+
radix_tree_replace_slot(pslot, newpage);
/*
@@ -354,6 +367,9 @@ static int migrate_page_move_mapping(struct address_space *mapping,
*/
page_unfreeze_refs(page, expected_count - 1);
+ spin_unlock(&mapping->tree_lock);
+ /* Leave irq disabled to prevent preemption while updating stats */
+
/*
* If moved to a different zone then also account
* the page for that zone. Other VM counters will be
@@ -364,13 +380,19 @@ static int migrate_page_move_mapping(struct address_space *mapping,
* via NR_FILE_PAGES and NR_ANON_PAGES if they
* are mapped to swap space.
*/
- __dec_zone_page_state(page, NR_FILE_PAGES);
- __inc_zone_page_state(newpage, NR_FILE_PAGES);
- if (!PageSwapCache(page) && PageSwapBacked(page)) {
- __dec_zone_page_state(page, NR_SHMEM);
- __inc_zone_page_state(newpage, NR_SHMEM);
+ if (newzone != oldzone) {
+ __dec_zone_state(oldzone, NR_FILE_PAGES);
+ __inc_zone_state(newzone, NR_FILE_PAGES);
+ if (PageSwapBacked(page) && !PageSwapCache(page)) {
+ __dec_zone_state(oldzone, NR_SHMEM);
+ __inc_zone_state(newzone, NR_SHMEM);
+ }
+ if (dirty && mapping_cap_account_dirty(mapping)) {
+ __dec_zone_state(oldzone, NR_FILE_DIRTY);
+ __inc_zone_state(newzone, NR_FILE_DIRTY);
+ }
}
- spin_unlock_irq(&mapping->tree_lock);
+ local_irq_enable();
return 0;
}
@@ -444,17 +466,9 @@ void migrate_page_copy(struct page *newpage, struct page *page)
if (PageMappedToDisk(page))
SetPageMappedToDisk(newpage);
- if (PageDirty(page)) {
- clear_page_dirty_for_io(page);
- /*
- * Want to mark the page and the radix tree as dirty, and
- * redo the accounting that clear_page_dirty_for_io undid,
- * but we can't use set_page_dirty because that function
- * is actually a signal that all of the page has become dirty.
- * Whereas only part of our page may be dirty.
- */
- __set_page_dirty_nobuffers(newpage);
- }
+ /* Move dirty on pages not done by migrate_page_move_mapping() */
+ if (PageDirty(page))
+ SetPageDirty(newpage);
mlock_migrate_page(newpage, page);
ksm_migrate_page(newpage, page);
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c
index 3d1be9911b8..4e619292aa4 100644
--- a/net/ceph/crypto.c
+++ b/net/ceph/crypto.c
@@ -496,6 +496,93 @@ int ceph_encrypt(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
}
}
+static int ceph_aes_crypt(const struct ceph_crypto_key *key, bool encrypt,
+ void *buf, int buf_len, int in_len, int *pout_len)
+{
+ struct crypto_skcipher *tfm = ceph_crypto_alloc_cipher();
+ SKCIPHER_REQUEST_ON_STACK(req, tfm);
+ struct sg_table sgt;
+ struct scatterlist prealloc_sg;
+ char iv[AES_BLOCK_SIZE];
+ int pad_byte = AES_BLOCK_SIZE - (in_len & (AES_BLOCK_SIZE - 1));
+ int crypt_len = encrypt ? in_len + pad_byte : in_len;
+ int ret;
+
+ if (IS_ERR(tfm))
+ return PTR_ERR(tfm);
+
+ WARN_ON(crypt_len > buf_len);
+ if (encrypt)
+ memset(buf + in_len, pad_byte, pad_byte);
+ ret = setup_sgtable(&sgt, &prealloc_sg, buf, crypt_len);
+ if (ret)
+ goto out_tfm;
+
+ crypto_skcipher_setkey((void *)tfm, key->key, key->len);
+ memcpy(iv, aes_iv, AES_BLOCK_SIZE);
+
+ skcipher_request_set_tfm(req, tfm);
+ skcipher_request_set_callback(req, 0, NULL, NULL);
+ skcipher_request_set_crypt(req, sgt.sgl, sgt.sgl, crypt_len, iv);
+
+ /*
+ print_hex_dump(KERN_ERR, "key: ", DUMP_PREFIX_NONE, 16, 1,
+ key->key, key->len, 1);
+ print_hex_dump(KERN_ERR, " in: ", DUMP_PREFIX_NONE, 16, 1,
+ buf, crypt_len, 1);
+ */
+ if (encrypt)
+ ret = crypto_skcipher_encrypt(req);
+ else
+ ret = crypto_skcipher_decrypt(req);
+ skcipher_request_zero(req);
+ if (ret) {
+ pr_err("%s %scrypt failed: %d\n", __func__,
+ encrypt ? "en" : "de", ret);
+ goto out_sgt;
+ }
+ /*
+ print_hex_dump(KERN_ERR, "out: ", DUMP_PREFIX_NONE, 16, 1,
+ buf, crypt_len, 1);
+ */
+
+ if (encrypt) {
+ *pout_len = crypt_len;
+ } else {
+ pad_byte = *(char *)(buf + in_len - 1);
+ if (pad_byte > 0 && pad_byte <= AES_BLOCK_SIZE &&
+ in_len >= pad_byte) {
+ *pout_len = in_len - pad_byte;
+ } else {
+ pr_err("%s got bad padding %d on in_len %d\n",
+ __func__, pad_byte, in_len);
+ ret = -EPERM;
+ goto out_sgt;
+ }
+ }
+
+out_sgt:
+ teardown_sgtable(&sgt);
+out_tfm:
+ crypto_free_skcipher(tfm);
+ return ret;
+}
+
+int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
+ void *buf, int buf_len, int in_len, int *pout_len)
+{
+ switch (key->type) {
+ case CEPH_CRYPTO_NONE:
+ *pout_len = in_len;
+ return 0;
+ case CEPH_CRYPTO_AES:
+ return ceph_aes_crypt(key, encrypt, buf, buf_len, in_len,
+ pout_len);
+ default:
+ return -ENOTSUPP;
+ }
+}
+
int ceph_encrypt2(struct ceph_crypto_key *secret, void *dst, size_t *dst_len,
const void *src1, size_t src1_len,
const void *src2, size_t src2_len)
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h
index 3572dc518bc..8ef8ae945d7 100644
--- a/net/ceph/crypto.h
+++ b/net/ceph/crypto.h
@@ -43,6 +43,8 @@ extern int ceph_encrypt2(struct ceph_crypto_key *secret,
void *dst, size_t *dst_len,
const void *src1, size_t src1_len,
const void *src2, size_t src2_len);
+int ceph_crypt(const struct ceph_crypto_key *key, bool encrypt,
+ void *buf, int buf_len, int in_len, int *pout_len);
extern int ceph_crypto_init(void);
extern void ceph_crypto_shutdown(void);
diff --git a/net/l2tp/l2tp_ip.c b/net/l2tp/l2tp_ip.c
index 2120620bf96..add4613e771 100644
--- a/net/l2tp/l2tp_ip.c
+++ b/net/l2tp/l2tp_ip.c
@@ -254,8 +254,6 @@ static int l2tp_ip_bind(struct sock *sk, struct sockaddr *uaddr, int addr_len)
int ret;
int chk_addr_ret;
- if (!sock_flag(sk, SOCK_ZAPPED))
- return -EINVAL;
if (addr_len < sizeof(struct sockaddr_l2tpip))
return -EINVAL;
if (addr->l2tp_family != AF_INET)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 8d2d0e4e505..b46db84546f 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -1285,13 +1285,16 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags)
return -EINVAL;
}
+ mutex_lock(&fanout_mutex);
+
+ err = -EINVAL;
if (!po->running)
- return -EINVAL;
+ goto out;
+ err = -EALREADY;
if (po->fanout)
- return -EALREADY;
+ goto out;
- mutex_lock(&fanout_mutex);
match = NULL;
list_for_each_entry(f, &fanout_list, list) {
if (f->id == id &&
@@ -1347,17 +1350,16 @@ static void fanout_release(struct sock *sk)
struct packet_sock *po = pkt_sk(sk);
struct packet_fanout *f;
+ mutex_lock(&fanout_mutex);
f = po->fanout;
- if (!f)
- return;
+ if (f) {
+ po->fanout = NULL;
- po->fanout = NULL;
-
- mutex_lock(&fanout_mutex);
- if (atomic_dec_and_test(&f->sk_ref)) {
- list_del(&f->list);
- dev_remove_pack(&f->prot_hook);
- kfree(f);
+ if (atomic_dec_and_test(&f->sk_ref)) {
+ list_del(&f->list);
+ dev_remove_pack(&f->prot_hook);
+ kfree(f);
+ }
}
mutex_unlock(&fanout_mutex);
}
@@ -3135,6 +3137,8 @@ packet_setsockopt(struct socket *sock, int level, int optname, char __user *optv
return -EBUSY;
if (copy_from_user(&val, optval, sizeof(val)))
return -EFAULT;
+ if (val > INT_MAX)
+ return -EINVAL;
po->tp_reserve = val;
return 0;
}
@@ -3644,6 +3648,8 @@ static int packet_set_ring(struct sock *sk, union tpacket_req_u *req_u,
rb->frames_per_block = req->tp_block_size/req->tp_frame_size;
if (unlikely(rb->frames_per_block <= 0))
goto out;
+ if (unlikely(req->tp_block_size > UINT_MAX / req->tp_block_nr))
+ goto out;
if (unlikely((rb->frames_per_block * req->tp_block_nr) !=
req->tp_frame_nr))
goto out;
diff --git a/security/keys/gc.c b/security/keys/gc.c
index 9e496adfa3d..3ffd6d8144f 100644
--- a/security/keys/gc.c
+++ b/security/keys/gc.c
@@ -46,7 +46,7 @@ static unsigned long key_gc_flags;
* immediately unlinked.
*/
struct key_type key_type_dead = {
- .name = "dead",
+ .name = ".dead",
};
/*
diff --git a/security/keys/keyctl.c b/security/keys/keyctl.c
index 0ba68b18d69..64880d05069 100644
--- a/security/keys/keyctl.c
+++ b/security/keys/keyctl.c
@@ -260,7 +260,8 @@ error:
* Create and join an anonymous session keyring or join a named session
* keyring, creating it if necessary. A named session keyring must have Search
* permission for it to be joined. Session keyrings without this permit will
- * be skipped over.
+ * be skipped over. It is not permitted for userspace to create or join
+ * keyrings whose name begin with a dot.
*
* If successful, the ID of the joined session keyring will be returned.
*/
@@ -277,12 +278,16 @@ long keyctl_join_session_keyring(const char __user *_name)
ret = PTR_ERR(name);
goto error;
}
+
+ ret = -EPERM;
+ if (name[0] == '.')
+ goto error_name;
}
/* join the session */
ret = join_session_keyring(name);
+error_name:
kfree(name);
-
error:
return ret;
}
@@ -1188,8 +1193,8 @@ error:
* Read or set the default keyring in which request_key() will cache keys and
* return the old setting.
*
- * If a process keyring is specified then this will be created if it doesn't
- * yet exist. The old setting will be returned if successful.
+ * If a thread or process keyring is specified then it will be created if it
+ * doesn't yet exist. The old setting will be returned if successful.
*/
long keyctl_set_reqkey_keyring(int reqkey_defl)
{
@@ -1214,11 +1219,8 @@ long keyctl_set_reqkey_keyring(int reqkey_defl)
case KEY_REQKEY_DEFL_PROCESS_KEYRING:
ret = install_process_keyring_to_cred(new);
- if (ret < 0) {
- if (ret != -EEXIST)
- goto error;
- ret = 0;
- }
+ if (ret < 0)
+ goto error;
goto set;
case KEY_REQKEY_DEFL_DEFAULT:
diff --git a/security/keys/process_keys.c b/security/keys/process_keys.c
index adbfddd7e00..d34a051faf3 100644
--- a/security/keys/process_keys.c
+++ b/security/keys/process_keys.c
@@ -121,13 +121,18 @@ error:
}
/*
- * Install a fresh thread keyring directly to new credentials. This keyring is
- * allowed to overrun the quota.
+ * Install a thread keyring to the given credentials struct if it didn't have
+ * one already. This is allowed to overrun the quota.
+ *
+ * Return: 0 if a thread keyring is now present; -errno on failure.
*/
int install_thread_keyring_to_cred(struct cred *new)
{
struct key *keyring;
+ if (new->thread_keyring)
+ return 0;
+
keyring = keyring_alloc("_tid", new->uid, new->gid, new,
KEY_ALLOC_QUOTA_OVERRUN, NULL);
if (IS_ERR(keyring))
@@ -138,7 +143,9 @@ int install_thread_keyring_to_cred(struct cred *new)
}
/*
- * Install a fresh thread keyring, discarding the old one.
+ * Install a thread keyring to the current task if it didn't have one already.
+ *
+ * Return: 0 if a thread keyring is now present; -errno on failure.
*/
static int install_thread_keyring(void)
{
@@ -149,8 +156,6 @@ static int install_thread_keyring(void)
if (!new)
return -ENOMEM;
- BUG_ON(new->thread_keyring);
-
ret = install_thread_keyring_to_cred(new);
if (ret < 0) {
abort_creds(new);
@@ -161,10 +166,10 @@ static int install_thread_keyring(void)
}
/*
- * Install a process keyring directly to a credentials struct.
+ * Install a process keyring to the given credentials struct if it didn't have
+ * one already. This is allowed to overrun the quota.
*
- * Returns -EEXIST if there was already a process keyring, 0 if one installed,
- * and other value on any other error
+ * Return: 0 if a process keyring is now present; -errno on failure.
*/
int install_process_keyring_to_cred(struct cred *new)
{
@@ -172,7 +177,7 @@ int install_process_keyring_to_cred(struct cred *new)
int ret;
if (new->tgcred->process_keyring)
- return -EEXIST;
+ return 0;
keyring = keyring_alloc("_pid", new->uid, new->gid,
new, KEY_ALLOC_QUOTA_OVERRUN, NULL);
@@ -193,11 +198,9 @@ int install_process_keyring_to_cred(struct cred *new)
}
/*
- * Make sure a process keyring is installed for the current process. The
- * existing process keyring is not replaced.
+ * Install a process keyring to the current task if it didn't have one already.
*
- * Returns 0 if there is a process keyring by the end of this function, some
- * error otherwise.
+ * Return: 0 if a process keyring is now present; -errno on failure.
*/
static int install_process_keyring(void)
{
@@ -211,14 +214,18 @@ static int install_process_keyring(void)
ret = install_process_keyring_to_cred(new);
if (ret < 0) {
abort_creds(new);
- return ret != -EEXIST ? ret : 0;
+ return ret;
}
return commit_creds(new);
}
/*
- * Install a session keyring directly to a credentials struct.
+ * Install the given keyring as the session keyring of the given credentials
+ * struct, replacing the existing one if any. If the given keyring is NULL,
+ * then install a new anonymous session keyring.
+ *
+ * Return: 0 on success; -errno on failure.
*/
int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
{
@@ -258,8 +265,11 @@ int install_session_keyring_to_cred(struct cred *cred, struct key *keyring)
}
/*
- * Install a session keyring, discarding the old one. If a keyring is not
- * supplied, an empty one is invented.
+ * Install the given keyring as the session keyring of the current task,
+ * replacing the existing one if any. If the given keyring is NULL, then
+ * install a new anonymous session keyring.
+ *
+ * Return: 0 on success; -errno on failure.
*/
static int install_session_keyring(struct key *keyring)
{
diff --git a/sound/soc/codecs/wcd9320.c b/sound/soc/codecs/wcd9320.c
index 68c11c33b28..281688196a9 100644
--- a/sound/soc/codecs/wcd9320.c
+++ b/sound/soc/codecs/wcd9320.c
@@ -1306,7 +1306,15 @@ static int taiko_mad_input_put(struct snd_kcontrol *kcontrol,
taiko_mad_input = ucontrol->value.integer.value[0];
+ if (taiko_mad_input >= ARRAY_SIZE(taiko_conn_mad_text)) {
+ dev_err(codec->dev,
+ "%s: taiko_mad_input = %d out of bounds\n",
+ __func__, taiko_mad_input);
+ return -EINVAL;
+ }
+
micb_4_int_reg = taiko->resmgr.reg_addr->micb_4_int_rbias;
+
pr_debug("%s: taiko_mad_input = %s\n", __func__,
taiko_conn_mad_text[taiko_mad_input]);
diff --git a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
index 35c83668827..c1dcd460436 100644
--- a/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
+++ b/sound/soc/msm/qdsp6v2/msm-pcm-routing-v2.c
@@ -1166,7 +1166,7 @@ static int msm_routing_set_multimedia2_vol_mixer(struct snd_kcontrol *kcontrol,
static int msm_routing_get_channel_map_mixer(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol)
{
- char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL];
+ char channel_map[PCM_FORMAT_MAX_NUM_CHANNEL] = {0};
int i;
adm_get_multi_ch_map(channel_map);