mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-10-01 01:35:54 -04:00
Switch to new CVE patchset
This commit is contained in:
parent
57ce42402b
commit
11c7037780
345
Patches/Linux_CVEs/CVE-2012-4220/ANY/0001.patch
Normal file
345
Patches/Linux_CVEs/CVE-2012-4220/ANY/0001.patch
Normal file
@ -0,0 +1,345 @@
|
||||
From 77ad483f7b82d944aae5b944cd28e923a5293668 Mon Sep 17 00:00:00 2001
|
||||
From: Ravi Aravamudhan <aravamud@codeaurora.org>
|
||||
Date: Thu, 15 Nov 2012 16:04:04 -0800
|
||||
Subject: diag: Improve handling of IOCTLs
|
||||
|
||||
DIAG kernel driver interacts with user space processes using
|
||||
IOCTLS. This change adds conditions to avoid potential integer
|
||||
over/underflow, incorrect buffer copy.
|
||||
|
||||
CVE-2012-4220
|
||||
CVE-2012-4221
|
||||
|
||||
Change-Id: Ic1e815051ae9544c911c9a5bd0c9218c1225f6d5
|
||||
CRs-Fixed: 385352
|
||||
CRs-Fixed: 385349
|
||||
Signed-off-by: Shalabh Jain <shalabhj@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diagchar.h | 1 +
|
||||
drivers/char/diag/diagchar_core.c | 188 ++++++++++++++++++++++++++++----------
|
||||
2 files changed, 142 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
|
||||
index 28d0565..de3cf522 100644
|
||||
--- a/drivers/char/diag/diagchar.h
|
||||
+++ b/drivers/char/diag/diagchar.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#define IN_BUF_SIZE 16384
|
||||
#define MAX_IN_BUF_SIZE 32768
|
||||
#define MAX_SYNC_OBJ_NAME_SIZE 32
|
||||
+#define UINT32_MAX UINT_MAX
|
||||
/* Size of the buffer used for deframing a packet
|
||||
reveived from the PC tool*/
|
||||
#define HDLC_MAX 4096
|
||||
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
|
||||
index 19c6ed2..7b17ce4 100644
|
||||
--- a/drivers/char/diag/diagchar_core.c
|
||||
+++ b/drivers/char/diag/diagchar_core.c
|
||||
@@ -358,7 +358,7 @@ void diag_clear_reg(int proc_num)
|
||||
}
|
||||
|
||||
void diag_add_reg(int j, struct bindpkt_params *params,
|
||||
- int *success, int *count_entries)
|
||||
+ int *success, unsigned int *count_entries)
|
||||
{
|
||||
*success = 1;
|
||||
driver->table[j].cmd_code = params->cmd_code;
|
||||
@@ -399,79 +399,153 @@ inline uint16_t diag_get_remote_device_mask(void) { return 0; }
|
||||
long diagchar_ioctl(struct file *filp,
|
||||
unsigned int iocmd, unsigned long ioarg)
|
||||
{
|
||||
- int i, j, count_entries = 0, temp;
|
||||
- int success = -1;
|
||||
+ int i, j, temp, success = -1, status;
|
||||
+ unsigned int count_entries = 0, interim_count = 0;
|
||||
void *temp_buf;
|
||||
uint16_t support_list = 0;
|
||||
- struct diag_dci_client_tbl *params =
|
||||
- kzalloc(sizeof(struct diag_dci_client_tbl), GFP_KERNEL);
|
||||
+ struct diag_dci_client_tbl *dci_params;
|
||||
struct diag_dci_health_stats stats;
|
||||
- int status;
|
||||
|
||||
if (iocmd == DIAG_IOCTL_COMMAND_REG) {
|
||||
- struct bindpkt_params_per_process *pkt_params =
|
||||
- (struct bindpkt_params_per_process *) ioarg;
|
||||
+ struct bindpkt_params_per_process pkt_params;
|
||||
+ struct bindpkt_params *params;
|
||||
+ struct bindpkt_params *head_params;
|
||||
+ if (copy_from_user(&pkt_params, (void *)ioarg,
|
||||
+ sizeof(struct bindpkt_params_per_process))) {
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if ((UINT32_MAX/sizeof(struct bindpkt_params)) <
|
||||
+ pkt_params.count) {
|
||||
+ pr_warning("diag: integer overflow while multiply\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ params = kzalloc(pkt_params.count*sizeof(
|
||||
+ struct bindpkt_params), GFP_KERNEL);
|
||||
+ if (!params) {
|
||||
+ pr_err("diag: unable to alloc memory\n");
|
||||
+ return -ENOMEM;
|
||||
+ } else
|
||||
+ head_params = params;
|
||||
+
|
||||
+ if (copy_from_user(params, pkt_params.params,
|
||||
+ pkt_params.count*sizeof(struct bindpkt_params))) {
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
for (i = 0; i < diag_max_reg; i++) {
|
||||
if (driver->table[i].process_id == 0) {
|
||||
- diag_add_reg(i, pkt_params->params,
|
||||
- &success, &count_entries);
|
||||
- if (pkt_params->count > count_entries) {
|
||||
- pkt_params->params++;
|
||||
+ diag_add_reg(i, params, &success,
|
||||
+ &count_entries);
|
||||
+ if (pkt_params.count > count_entries) {
|
||||
+ params++;
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i < diag_threshold_reg) {
|
||||
/* Increase table size by amount required */
|
||||
- diag_max_reg += pkt_params->count -
|
||||
+ if (pkt_params.count >= count_entries) {
|
||||
+ interim_count = pkt_params.count -
|
||||
count_entries;
|
||||
+ } else {
|
||||
+ pr_warning("diag: error in params count\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (UINT32_MAX - diag_max_reg >=
|
||||
+ interim_count) {
|
||||
+ diag_max_reg += interim_count;
|
||||
+ } else {
|
||||
+ pr_warning("diag: Integer overflow\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
/* Make sure size doesnt go beyond threshold */
|
||||
if (diag_max_reg > diag_threshold_reg) {
|
||||
diag_max_reg = diag_threshold_reg;
|
||||
pr_info("diag: best case memory allocation\n");
|
||||
}
|
||||
+ if (UINT32_MAX/sizeof(struct diag_master_table) <
|
||||
+ diag_max_reg) {
|
||||
+ pr_warning("diag: integer overflow\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
temp_buf = krealloc(driver->table,
|
||||
diag_max_reg*sizeof(struct
|
||||
diag_master_table), GFP_KERNEL);
|
||||
if (!temp_buf) {
|
||||
- diag_max_reg -= pkt_params->count -
|
||||
- count_entries;
|
||||
- pr_alert("diag: Insufficient memory for reg.");
|
||||
+ pr_alert("diag: Insufficient memory for reg.\n");
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+
|
||||
+ if (pkt_params.count >= count_entries) {
|
||||
+ interim_count = pkt_params.count -
|
||||
+ count_entries;
|
||||
+ } else {
|
||||
+ pr_warning("diag: params count error\n");
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (diag_max_reg >= interim_count) {
|
||||
+ diag_max_reg -= interim_count;
|
||||
+ } else {
|
||||
+ pr_warning("diag: Integer underflow\n");
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ kfree(head_params);
|
||||
return 0;
|
||||
} else {
|
||||
driver->table = temp_buf;
|
||||
}
|
||||
for (j = i; j < diag_max_reg; j++) {
|
||||
- diag_add_reg(j, pkt_params->params,
|
||||
- &success, &count_entries);
|
||||
- if (pkt_params->count > count_entries) {
|
||||
- pkt_params->params++;
|
||||
+ diag_add_reg(j, params, &success,
|
||||
+ &count_entries);
|
||||
+ if (pkt_params.count > count_entries) {
|
||||
+ params++;
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
+ kfree(head_params);
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
pr_err("Max size reached, Pkt Registration failed for"
|
||||
" Process %d", current->tgid);
|
||||
}
|
||||
success = 0;
|
||||
} else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) {
|
||||
- struct diagpkt_delay_params *delay_params =
|
||||
- (struct diagpkt_delay_params *) ioarg;
|
||||
-
|
||||
- if ((delay_params->rsp_ptr) &&
|
||||
- (delay_params->size == sizeof(delayed_rsp_id)) &&
|
||||
- (delay_params->num_bytes_ptr)) {
|
||||
- *((uint16_t *)delay_params->rsp_ptr) =
|
||||
- DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id);
|
||||
- *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id);
|
||||
+ struct diagpkt_delay_params delay_params;
|
||||
+ uint16_t interim_rsp_id;
|
||||
+ int interim_size;
|
||||
+ if (copy_from_user(&delay_params, (void *)ioarg,
|
||||
+ sizeof(struct diagpkt_delay_params)))
|
||||
+ return -EFAULT;
|
||||
+ if ((delay_params.rsp_ptr) &&
|
||||
+ (delay_params.size == sizeof(delayed_rsp_id)) &&
|
||||
+ (delay_params.num_bytes_ptr)) {
|
||||
+ interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID(
|
||||
+ delayed_rsp_id);
|
||||
+ if (copy_to_user((void *)delay_params.rsp_ptr,
|
||||
+ &interim_rsp_id, sizeof(uint16_t)))
|
||||
+ return -EFAULT;
|
||||
+ interim_size = sizeof(delayed_rsp_id);
|
||||
+ if (copy_to_user((void *)delay_params.num_bytes_ptr,
|
||||
+ &interim_size, sizeof(int)))
|
||||
+ return -EFAULT;
|
||||
success = 0;
|
||||
}
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_REG) {
|
||||
@@ -479,7 +553,13 @@ long diagchar_ioctl(struct file *filp,
|
||||
return DIAG_DCI_NO_REG;
|
||||
if (driver->num_dci_client >= MAX_DCI_CLIENTS)
|
||||
return DIAG_DCI_NO_REG;
|
||||
- if (copy_from_user(params, (void *)ioarg,
|
||||
+ dci_params = kzalloc(sizeof(struct diag_dci_client_tbl),
|
||||
+ GFP_KERNEL);
|
||||
+ if (dci_params == NULL) {
|
||||
+ pr_err("diag: unable to alloc memory\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ if (copy_from_user(dci_params, (void *)ioarg,
|
||||
sizeof(struct diag_dci_client_tbl)))
|
||||
return -EFAULT;
|
||||
mutex_lock(&driver->dci_mutex);
|
||||
@@ -492,9 +572,9 @@ long diagchar_ioctl(struct file *filp,
|
||||
if (driver->dci_client_tbl[i].client == NULL) {
|
||||
driver->dci_client_tbl[i].client = current;
|
||||
driver->dci_client_tbl[i].list =
|
||||
- params->list;
|
||||
+ dci_params->list;
|
||||
driver->dci_client_tbl[i].signal_type =
|
||||
- params->signal_type;
|
||||
+ dci_params->signal_type;
|
||||
create_dci_log_mask_tbl(driver->
|
||||
dci_client_tbl[i].dci_log_mask);
|
||||
create_dci_event_mask_tbl(driver->
|
||||
@@ -512,6 +592,7 @@ long diagchar_ioctl(struct file *filp,
|
||||
}
|
||||
}
|
||||
mutex_unlock(&driver->dci_mutex);
|
||||
+ kfree(dci_params);
|
||||
return driver->dci_client_id;
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
|
||||
success = -1;
|
||||
@@ -536,25 +617,29 @@ long diagchar_ioctl(struct file *filp,
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) {
|
||||
if (driver->ch_dci)
|
||||
support_list = support_list | DIAG_CON_MPSS;
|
||||
- *(uint16_t *)ioarg = support_list;
|
||||
+ if (copy_to_user((void *)ioarg, &support_list,
|
||||
+ sizeof(uint16_t)))
|
||||
+ return -EFAULT;
|
||||
return DIAG_DCI_NO_ERROR;
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_HEALTH_STATS) {
|
||||
if (copy_from_user(&stats, (void *)ioarg,
|
||||
sizeof(struct diag_dci_health_stats)))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
|
||||
- params = &(driver->dci_client_tbl[i]);
|
||||
- if (params->client &&
|
||||
- params->client->tgid == current->tgid) {
|
||||
- stats.dropped_logs = params->dropped_logs;
|
||||
- stats.dropped_events = params->dropped_events;
|
||||
- stats.received_logs = params->received_logs;
|
||||
- stats.received_events = params->received_events;
|
||||
+ dci_params = &(driver->dci_client_tbl[i]);
|
||||
+ if (dci_params->client &&
|
||||
+ dci_params->client->tgid == current->tgid) {
|
||||
+ stats.dropped_logs = dci_params->dropped_logs;
|
||||
+ stats.dropped_events =
|
||||
+ dci_params->dropped_events;
|
||||
+ stats.received_logs = dci_params->received_logs;
|
||||
+ stats.received_events =
|
||||
+ dci_params->received_events;
|
||||
if (stats.reset_status) {
|
||||
- params->dropped_logs = 0;
|
||||
- params->dropped_events = 0;
|
||||
- params->received_logs = 0;
|
||||
- params->received_events = 0;
|
||||
+ dci_params->dropped_logs = 0;
|
||||
+ dci_params->dropped_events = 0;
|
||||
+ dci_params->received_logs = 0;
|
||||
+ dci_params->received_events = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -567,7 +652,7 @@ long diagchar_ioctl(struct file *filp,
|
||||
for (i = 0; i < driver->num_clients; i++)
|
||||
if (driver->client_map[i].pid == current->tgid)
|
||||
break;
|
||||
- if (i == -1)
|
||||
+ if (i == driver->num_clients)
|
||||
return -EINVAL;
|
||||
driver->data_ready[i] |= DEINIT_TYPE;
|
||||
wake_up_interruptible(&driver->wait_q);
|
||||
@@ -1068,7 +1153,7 @@ static int diagchar_write(struct file *file, const char __user *buf,
|
||||
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
|
||||
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
|
||||
void *buf_copy = NULL;
|
||||
- int payload_size;
|
||||
+ unsigned int payload_size;
|
||||
#ifdef CONFIG_DIAG_OVER_USB
|
||||
if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) ||
|
||||
(driver->logging_mode == NO_LOGGING_MODE)) {
|
||||
@@ -1079,8 +1164,17 @@ static int diagchar_write(struct file *file, const char __user *buf,
|
||||
/* Get the packet type F3/log/event/Pkt response */
|
||||
err = copy_from_user((&pkt_type), buf, 4);
|
||||
/* First 4 bytes indicate the type of payload - ignore these */
|
||||
+ if (count < 4) {
|
||||
+ pr_err("diag: Client sending short data\n");
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
payload_size = count - 4;
|
||||
-
|
||||
+ if (payload_size > USER_SPACE_DATA) {
|
||||
+ pr_err("diag: Dropping packet, packet payload size crosses 8KB limit. Current payload size %d\n",
|
||||
+ payload_size);
|
||||
+ driver->dropped_count++;
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
if (pkt_type == DCI_DATA_TYPE) {
|
||||
err = copy_from_user(driver->user_space_data, buf + 4,
|
||||
payload_size);
|
||||
--
|
||||
cgit v1.1
|
||||
|
345
Patches/Linux_CVEs/CVE-2012-4221/ANY/0001.patch
Normal file
345
Patches/Linux_CVEs/CVE-2012-4221/ANY/0001.patch
Normal file
@ -0,0 +1,345 @@
|
||||
From 77ad483f7b82d944aae5b944cd28e923a5293668 Mon Sep 17 00:00:00 2001
|
||||
From: Ravi Aravamudhan <aravamud@codeaurora.org>
|
||||
Date: Thu, 15 Nov 2012 16:04:04 -0800
|
||||
Subject: diag: Improve handling of IOCTLs
|
||||
|
||||
DIAG kernel driver interacts with user space processes using
|
||||
IOCTLS. This change adds conditions to avoid potential integer
|
||||
over/underflow, incorrect buffer copy.
|
||||
|
||||
CVE-2012-4220
|
||||
CVE-2012-4221
|
||||
|
||||
Change-Id: Ic1e815051ae9544c911c9a5bd0c9218c1225f6d5
|
||||
CRs-Fixed: 385352
|
||||
CRs-Fixed: 385349
|
||||
Signed-off-by: Shalabh Jain <shalabhj@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diagchar.h | 1 +
|
||||
drivers/char/diag/diagchar_core.c | 188 ++++++++++++++++++++++++++++----------
|
||||
2 files changed, 142 insertions(+), 47 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diagchar.h b/drivers/char/diag/diagchar.h
|
||||
index 28d0565..de3cf522 100644
|
||||
--- a/drivers/char/diag/diagchar.h
|
||||
+++ b/drivers/char/diag/diagchar.h
|
||||
@@ -29,6 +29,7 @@
|
||||
#define IN_BUF_SIZE 16384
|
||||
#define MAX_IN_BUF_SIZE 32768
|
||||
#define MAX_SYNC_OBJ_NAME_SIZE 32
|
||||
+#define UINT32_MAX UINT_MAX
|
||||
/* Size of the buffer used for deframing a packet
|
||||
reveived from the PC tool*/
|
||||
#define HDLC_MAX 4096
|
||||
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
|
||||
index 19c6ed2..7b17ce4 100644
|
||||
--- a/drivers/char/diag/diagchar_core.c
|
||||
+++ b/drivers/char/diag/diagchar_core.c
|
||||
@@ -358,7 +358,7 @@ void diag_clear_reg(int proc_num)
|
||||
}
|
||||
|
||||
void diag_add_reg(int j, struct bindpkt_params *params,
|
||||
- int *success, int *count_entries)
|
||||
+ int *success, unsigned int *count_entries)
|
||||
{
|
||||
*success = 1;
|
||||
driver->table[j].cmd_code = params->cmd_code;
|
||||
@@ -399,79 +399,153 @@ inline uint16_t diag_get_remote_device_mask(void) { return 0; }
|
||||
long diagchar_ioctl(struct file *filp,
|
||||
unsigned int iocmd, unsigned long ioarg)
|
||||
{
|
||||
- int i, j, count_entries = 0, temp;
|
||||
- int success = -1;
|
||||
+ int i, j, temp, success = -1, status;
|
||||
+ unsigned int count_entries = 0, interim_count = 0;
|
||||
void *temp_buf;
|
||||
uint16_t support_list = 0;
|
||||
- struct diag_dci_client_tbl *params =
|
||||
- kzalloc(sizeof(struct diag_dci_client_tbl), GFP_KERNEL);
|
||||
+ struct diag_dci_client_tbl *dci_params;
|
||||
struct diag_dci_health_stats stats;
|
||||
- int status;
|
||||
|
||||
if (iocmd == DIAG_IOCTL_COMMAND_REG) {
|
||||
- struct bindpkt_params_per_process *pkt_params =
|
||||
- (struct bindpkt_params_per_process *) ioarg;
|
||||
+ struct bindpkt_params_per_process pkt_params;
|
||||
+ struct bindpkt_params *params;
|
||||
+ struct bindpkt_params *head_params;
|
||||
+ if (copy_from_user(&pkt_params, (void *)ioarg,
|
||||
+ sizeof(struct bindpkt_params_per_process))) {
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if ((UINT32_MAX/sizeof(struct bindpkt_params)) <
|
||||
+ pkt_params.count) {
|
||||
+ pr_warning("diag: integer overflow while multiply\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ params = kzalloc(pkt_params.count*sizeof(
|
||||
+ struct bindpkt_params), GFP_KERNEL);
|
||||
+ if (!params) {
|
||||
+ pr_err("diag: unable to alloc memory\n");
|
||||
+ return -ENOMEM;
|
||||
+ } else
|
||||
+ head_params = params;
|
||||
+
|
||||
+ if (copy_from_user(params, pkt_params.params,
|
||||
+ pkt_params.count*sizeof(struct bindpkt_params))) {
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
mutex_lock(&driver->diagchar_mutex);
|
||||
for (i = 0; i < diag_max_reg; i++) {
|
||||
if (driver->table[i].process_id == 0) {
|
||||
- diag_add_reg(i, pkt_params->params,
|
||||
- &success, &count_entries);
|
||||
- if (pkt_params->count > count_entries) {
|
||||
- pkt_params->params++;
|
||||
+ diag_add_reg(i, params, &success,
|
||||
+ &count_entries);
|
||||
+ if (pkt_params.count > count_entries) {
|
||||
+ params++;
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (i < diag_threshold_reg) {
|
||||
/* Increase table size by amount required */
|
||||
- diag_max_reg += pkt_params->count -
|
||||
+ if (pkt_params.count >= count_entries) {
|
||||
+ interim_count = pkt_params.count -
|
||||
count_entries;
|
||||
+ } else {
|
||||
+ pr_warning("diag: error in params count\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (UINT32_MAX - diag_max_reg >=
|
||||
+ interim_count) {
|
||||
+ diag_max_reg += interim_count;
|
||||
+ } else {
|
||||
+ pr_warning("diag: Integer overflow\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
/* Make sure size doesnt go beyond threshold */
|
||||
if (diag_max_reg > diag_threshold_reg) {
|
||||
diag_max_reg = diag_threshold_reg;
|
||||
pr_info("diag: best case memory allocation\n");
|
||||
}
|
||||
+ if (UINT32_MAX/sizeof(struct diag_master_table) <
|
||||
+ diag_max_reg) {
|
||||
+ pr_warning("diag: integer overflow\n");
|
||||
+ kfree(head_params);
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
temp_buf = krealloc(driver->table,
|
||||
diag_max_reg*sizeof(struct
|
||||
diag_master_table), GFP_KERNEL);
|
||||
if (!temp_buf) {
|
||||
- diag_max_reg -= pkt_params->count -
|
||||
- count_entries;
|
||||
- pr_alert("diag: Insufficient memory for reg.");
|
||||
+ pr_alert("diag: Insufficient memory for reg.\n");
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+
|
||||
+ if (pkt_params.count >= count_entries) {
|
||||
+ interim_count = pkt_params.count -
|
||||
+ count_entries;
|
||||
+ } else {
|
||||
+ pr_warning("diag: params count error\n");
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (diag_max_reg >= interim_count) {
|
||||
+ diag_max_reg -= interim_count;
|
||||
+ } else {
|
||||
+ pr_warning("diag: Integer underflow\n");
|
||||
+ mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ kfree(head_params);
|
||||
return 0;
|
||||
} else {
|
||||
driver->table = temp_buf;
|
||||
}
|
||||
for (j = i; j < diag_max_reg; j++) {
|
||||
- diag_add_reg(j, pkt_params->params,
|
||||
- &success, &count_entries);
|
||||
- if (pkt_params->count > count_entries) {
|
||||
- pkt_params->params++;
|
||||
+ diag_add_reg(j, params, &success,
|
||||
+ &count_entries);
|
||||
+ if (pkt_params.count > count_entries) {
|
||||
+ params++;
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
return success;
|
||||
}
|
||||
}
|
||||
+ kfree(head_params);
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
} else {
|
||||
mutex_unlock(&driver->diagchar_mutex);
|
||||
+ kfree(head_params);
|
||||
pr_err("Max size reached, Pkt Registration failed for"
|
||||
" Process %d", current->tgid);
|
||||
}
|
||||
success = 0;
|
||||
} else if (iocmd == DIAG_IOCTL_GET_DELAYED_RSP_ID) {
|
||||
- struct diagpkt_delay_params *delay_params =
|
||||
- (struct diagpkt_delay_params *) ioarg;
|
||||
-
|
||||
- if ((delay_params->rsp_ptr) &&
|
||||
- (delay_params->size == sizeof(delayed_rsp_id)) &&
|
||||
- (delay_params->num_bytes_ptr)) {
|
||||
- *((uint16_t *)delay_params->rsp_ptr) =
|
||||
- DIAGPKT_NEXT_DELAYED_RSP_ID(delayed_rsp_id);
|
||||
- *(delay_params->num_bytes_ptr) = sizeof(delayed_rsp_id);
|
||||
+ struct diagpkt_delay_params delay_params;
|
||||
+ uint16_t interim_rsp_id;
|
||||
+ int interim_size;
|
||||
+ if (copy_from_user(&delay_params, (void *)ioarg,
|
||||
+ sizeof(struct diagpkt_delay_params)))
|
||||
+ return -EFAULT;
|
||||
+ if ((delay_params.rsp_ptr) &&
|
||||
+ (delay_params.size == sizeof(delayed_rsp_id)) &&
|
||||
+ (delay_params.num_bytes_ptr)) {
|
||||
+ interim_rsp_id = DIAGPKT_NEXT_DELAYED_RSP_ID(
|
||||
+ delayed_rsp_id);
|
||||
+ if (copy_to_user((void *)delay_params.rsp_ptr,
|
||||
+ &interim_rsp_id, sizeof(uint16_t)))
|
||||
+ return -EFAULT;
|
||||
+ interim_size = sizeof(delayed_rsp_id);
|
||||
+ if (copy_to_user((void *)delay_params.num_bytes_ptr,
|
||||
+ &interim_size, sizeof(int)))
|
||||
+ return -EFAULT;
|
||||
success = 0;
|
||||
}
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_REG) {
|
||||
@@ -479,7 +553,13 @@ long diagchar_ioctl(struct file *filp,
|
||||
return DIAG_DCI_NO_REG;
|
||||
if (driver->num_dci_client >= MAX_DCI_CLIENTS)
|
||||
return DIAG_DCI_NO_REG;
|
||||
- if (copy_from_user(params, (void *)ioarg,
|
||||
+ dci_params = kzalloc(sizeof(struct diag_dci_client_tbl),
|
||||
+ GFP_KERNEL);
|
||||
+ if (dci_params == NULL) {
|
||||
+ pr_err("diag: unable to alloc memory\n");
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+ if (copy_from_user(dci_params, (void *)ioarg,
|
||||
sizeof(struct diag_dci_client_tbl)))
|
||||
return -EFAULT;
|
||||
mutex_lock(&driver->dci_mutex);
|
||||
@@ -492,9 +572,9 @@ long diagchar_ioctl(struct file *filp,
|
||||
if (driver->dci_client_tbl[i].client == NULL) {
|
||||
driver->dci_client_tbl[i].client = current;
|
||||
driver->dci_client_tbl[i].list =
|
||||
- params->list;
|
||||
+ dci_params->list;
|
||||
driver->dci_client_tbl[i].signal_type =
|
||||
- params->signal_type;
|
||||
+ dci_params->signal_type;
|
||||
create_dci_log_mask_tbl(driver->
|
||||
dci_client_tbl[i].dci_log_mask);
|
||||
create_dci_event_mask_tbl(driver->
|
||||
@@ -512,6 +592,7 @@ long diagchar_ioctl(struct file *filp,
|
||||
}
|
||||
}
|
||||
mutex_unlock(&driver->dci_mutex);
|
||||
+ kfree(dci_params);
|
||||
return driver->dci_client_id;
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_DEINIT) {
|
||||
success = -1;
|
||||
@@ -536,25 +617,29 @@ long diagchar_ioctl(struct file *filp,
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_SUPPORT) {
|
||||
if (driver->ch_dci)
|
||||
support_list = support_list | DIAG_CON_MPSS;
|
||||
- *(uint16_t *)ioarg = support_list;
|
||||
+ if (copy_to_user((void *)ioarg, &support_list,
|
||||
+ sizeof(uint16_t)))
|
||||
+ return -EFAULT;
|
||||
return DIAG_DCI_NO_ERROR;
|
||||
} else if (iocmd == DIAG_IOCTL_DCI_HEALTH_STATS) {
|
||||
if (copy_from_user(&stats, (void *)ioarg,
|
||||
sizeof(struct diag_dci_health_stats)))
|
||||
return -EFAULT;
|
||||
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
|
||||
- params = &(driver->dci_client_tbl[i]);
|
||||
- if (params->client &&
|
||||
- params->client->tgid == current->tgid) {
|
||||
- stats.dropped_logs = params->dropped_logs;
|
||||
- stats.dropped_events = params->dropped_events;
|
||||
- stats.received_logs = params->received_logs;
|
||||
- stats.received_events = params->received_events;
|
||||
+ dci_params = &(driver->dci_client_tbl[i]);
|
||||
+ if (dci_params->client &&
|
||||
+ dci_params->client->tgid == current->tgid) {
|
||||
+ stats.dropped_logs = dci_params->dropped_logs;
|
||||
+ stats.dropped_events =
|
||||
+ dci_params->dropped_events;
|
||||
+ stats.received_logs = dci_params->received_logs;
|
||||
+ stats.received_events =
|
||||
+ dci_params->received_events;
|
||||
if (stats.reset_status) {
|
||||
- params->dropped_logs = 0;
|
||||
- params->dropped_events = 0;
|
||||
- params->received_logs = 0;
|
||||
- params->received_events = 0;
|
||||
+ dci_params->dropped_logs = 0;
|
||||
+ dci_params->dropped_events = 0;
|
||||
+ dci_params->received_logs = 0;
|
||||
+ dci_params->received_events = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -567,7 +652,7 @@ long diagchar_ioctl(struct file *filp,
|
||||
for (i = 0; i < driver->num_clients; i++)
|
||||
if (driver->client_map[i].pid == current->tgid)
|
||||
break;
|
||||
- if (i == -1)
|
||||
+ if (i == driver->num_clients)
|
||||
return -EINVAL;
|
||||
driver->data_ready[i] |= DEINIT_TYPE;
|
||||
wake_up_interruptible(&driver->wait_q);
|
||||
@@ -1068,7 +1153,7 @@ static int diagchar_write(struct file *file, const char __user *buf,
|
||||
struct diag_send_desc_type send = { NULL, NULL, DIAG_STATE_START, 0 };
|
||||
struct diag_hdlc_dest_type enc = { NULL, NULL, 0 };
|
||||
void *buf_copy = NULL;
|
||||
- int payload_size;
|
||||
+ unsigned int payload_size;
|
||||
#ifdef CONFIG_DIAG_OVER_USB
|
||||
if (((driver->logging_mode == USB_MODE) && (!driver->usb_connected)) ||
|
||||
(driver->logging_mode == NO_LOGGING_MODE)) {
|
||||
@@ -1079,8 +1164,17 @@ static int diagchar_write(struct file *file, const char __user *buf,
|
||||
/* Get the packet type F3/log/event/Pkt response */
|
||||
err = copy_from_user((&pkt_type), buf, 4);
|
||||
/* First 4 bytes indicate the type of payload - ignore these */
|
||||
+ if (count < 4) {
|
||||
+ pr_err("diag: Client sending short data\n");
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
payload_size = count - 4;
|
||||
-
|
||||
+ if (payload_size > USER_SPACE_DATA) {
|
||||
+ pr_err("diag: Dropping packet, packet payload size crosses 8KB limit. Current payload size %d\n",
|
||||
+ payload_size);
|
||||
+ driver->dropped_count++;
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
if (pkt_type == DCI_DATA_TYPE) {
|
||||
err = copy_from_user(driver->user_space_data, buf + 4,
|
||||
payload_size);
|
||||
--
|
||||
cgit v1.1
|
||||
|
65
Patches/Linux_CVEs/CVE-2012-4222/ANY/0001.patch
Normal file
65
Patches/Linux_CVEs/CVE-2012-4222/ANY/0001.patch
Normal file
@ -0,0 +1,65 @@
|
||||
From 1e76f61bb001b93795a227f8f808104b6c10b048 Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
Date: Wed, 8 Aug 2012 13:24:21 -0600
|
||||
Subject: msm: kgsl: Detect and avoid malformed ioctl codes
|
||||
|
||||
Because we were using _IO_NR, one could construct a malformed ioctl
|
||||
code that would avoid allocating memory yet go to a function that
|
||||
expected that memory. Still use _IO_NR to index the array of ioctls,
|
||||
but check that the full values match before jumping to the helper
|
||||
function.
|
||||
|
||||
CRs-fixed: 385592
|
||||
Change-Id: Ic0dedbaded469035bd0a2bb0f20fecb2a3045ca5
|
||||
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
---
|
||||
drivers/gpu/msm/kgsl.c | 19 +++++++++++++++++--
|
||||
1 file changed, 17 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/msm/kgsl.c b/drivers/gpu/msm/kgsl.c
|
||||
index 57a0e2b..53eff77 100644
|
||||
--- a/drivers/gpu/msm/kgsl.c
|
||||
+++ b/drivers/gpu/msm/kgsl.c
|
||||
@@ -2176,7 +2176,7 @@ static const struct {
|
||||
static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct kgsl_device_private *dev_priv = filep->private_data;
|
||||
- unsigned int nr = _IOC_NR(cmd);
|
||||
+ unsigned int nr;
|
||||
kgsl_ioctl_func_t func;
|
||||
int lock, ret;
|
||||
char ustack[64];
|
||||
@@ -2192,6 +2192,8 @@ static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
else if (cmd == IOCTL_KGSL_CMDSTREAM_READTIMESTAMP_OLD)
|
||||
cmd = IOCTL_KGSL_CMDSTREAM_READTIMESTAMP;
|
||||
|
||||
+ nr = _IOC_NR(cmd);
|
||||
+
|
||||
if (cmd & (IOC_IN | IOC_OUT)) {
|
||||
if (_IOC_SIZE(cmd) < sizeof(ustack))
|
||||
uptr = ustack;
|
||||
@@ -2216,7 +2218,20 @@ static long kgsl_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
}
|
||||
|
||||
if (nr < ARRAY_SIZE(kgsl_ioctl_funcs) &&
|
||||
- kgsl_ioctl_funcs[nr].func != NULL) {
|
||||
+ kgsl_ioctl_funcs[nr].func != NULL) {
|
||||
+
|
||||
+ /*
|
||||
+ * Make sure that nobody tried to send us a malformed ioctl code
|
||||
+ * with a valid NR but bogus flags
|
||||
+ */
|
||||
+
|
||||
+ if (kgsl_ioctl_funcs[nr].cmd != cmd) {
|
||||
+ KGSL_DRV_ERR(dev_priv->device,
|
||||
+ "Malformed ioctl code %08x\n", cmd);
|
||||
+ ret = -ENOIOCTLCMD;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
func = kgsl_ioctl_funcs[nr].func;
|
||||
lock = kgsl_ioctl_funcs[nr].lock;
|
||||
} else {
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,31 +0,0 @@
|
||||
From 81ce573830e9d5531531b3ec778c58e6b9167bcd Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Wed, 5 Sep 2012 15:32:18 +0300
|
||||
Subject: [PATCH] ALSA: compress_core: integer overflow in
|
||||
snd_compr_allocate_buffer()
|
||||
|
||||
These are 32 bit values that come from the user, we need to check for
|
||||
integer overflows or we could end up allocating a smaller buffer than
|
||||
expected.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/compress_offload.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
|
||||
index eb60cb8dbb8a6..68fe02c7400a2 100644
|
||||
--- a/sound/core/compress_offload.c
|
||||
+++ b/sound/core/compress_offload.c
|
||||
@@ -407,6 +407,10 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
|
||||
unsigned int buffer_size;
|
||||
void *buffer;
|
||||
|
||||
+ if (params->buffer.fragment_size == 0 ||
|
||||
+ params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
buffer_size = params->buffer.fragment_size * params->buffer.fragments;
|
||||
if (stream->ops->copy) {
|
||||
buffer = NULL;
|
52
Patches/Linux_CVEs/CVE-2013-2596/ANY/0001.patch
Normal file
52
Patches/Linux_CVEs/CVE-2013-2596/ANY/0001.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From 24b51892b863ad23a9fcb2a28a45e5cc15c2f3b5 Mon Sep 17 00:00:00 2001
|
||||
From: Manoj Rao <manojraj@codeaurora.org>
|
||||
Date: Tue, 16 Apr 2013 17:42:38 -0700
|
||||
Subject: mdss: mdss_fb: remove mmio access through mmap
|
||||
|
||||
Disable access to mm io and add
|
||||
appropriate range checks to ensure valid accesses
|
||||
through framebuffer mmap. This prevents illegal
|
||||
access into memory.
|
||||
|
||||
Change-Id: Ic6e47ec726d330d48ce9a7a708418492a553543b
|
||||
CRs-Fixed: 474706
|
||||
Signed-off-by: Manoj Rao <manojraj@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/mdss/mdss_fb.c | 16 +++++-----------
|
||||
1 file changed, 5 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/msm/mdss/mdss_fb.c b/drivers/video/msm/mdss/mdss_fb.c
|
||||
index e2d8cf6..f42df2a 100644
|
||||
--- a/drivers/video/msm/mdss/mdss_fb.c
|
||||
+++ b/drivers/video/msm/mdss/mdss_fb.c
|
||||
@@ -669,22 +669,16 @@ static int mdss_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
|
||||
}
|
||||
|
||||
mdss_fb_pan_idle(mfd);
|
||||
- if (off >= len) {
|
||||
- /* memory mapped io */
|
||||
- off -= len;
|
||||
- if (info->var.accel_flags) {
|
||||
- mutex_unlock(&info->lock);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- start = info->fix.mmio_start;
|
||||
- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
|
||||
- }
|
||||
|
||||
/* Set VM flags. */
|
||||
start &= PAGE_MASK;
|
||||
- if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
+ if ((vma->vm_end <= vma->vm_start) ||
|
||||
+ (off >= len) ||
|
||||
+ ((vma->vm_end - vma->vm_start) > (len - off)))
|
||||
return -EINVAL;
|
||||
off += start;
|
||||
+ if (off < start)
|
||||
+ return -EINVAL;
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
/* This is an IO map - tell maydump to skip this VMA */
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED;
|
||||
--
|
||||
cgit v1.1
|
||||
|
64
Patches/Linux_CVEs/CVE-2013-2596/ANY/0002.patch
Normal file
64
Patches/Linux_CVEs/CVE-2013-2596/ANY/0002.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 7e9785f78415d32e0b17b1d296a172b66e0d2ab7 Mon Sep 17 00:00:00 2001
|
||||
From: Manoj Rao <manojraj@codeaurora.org>
|
||||
Date: Fri, 12 Apr 2013 18:37:14 -0700
|
||||
Subject: msm: msm_fb: remove mmio access through mmap
|
||||
|
||||
Disable access to mm io and add
|
||||
appropriate range checks to ensure valid accesses
|
||||
through framebuffer mmap. This prevents illegal
|
||||
access into memory.
|
||||
|
||||
CRs-Fixed: 474706
|
||||
Change-Id: If25166f2732433ef967e99c716440030b567aae9
|
||||
Signed-off-by: Manoj Rao <manojraj@codeaurora.org>
|
||||
(cherry picked from commit b571bef36cf51f9bb4cd1ad3ba23e3cee6d1d3cb)
|
||||
|
||||
Conflicts:
|
||||
|
||||
drivers/video/msm/msm_fb.c
|
||||
|
||||
Signed-off-by: Raviteja <adimur@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/msm_fb.c | 22 ++++++++++------------
|
||||
1 file changed, 10 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
|
||||
index 7d11fa9..2b626a0 100644
|
||||
--- a/drivers/video/msm/msm_fb.c
|
||||
+++ b/drivers/video/msm/msm_fb.c
|
||||
@@ -1004,22 +1004,20 @@ static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
|
||||
u32 len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.smem_len);
|
||||
unsigned long off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
|
||||
- if (off >= len) {
|
||||
- /* memory mapped io */
|
||||
- off -= len;
|
||||
- if (info->var.accel_flags) {
|
||||
- mutex_unlock(&info->lock);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- start = info->fix.mmio_start;
|
||||
- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
|
||||
- }
|
||||
|
||||
+ if (!start)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if ((vma->vm_end <= vma->vm_start) ||
|
||||
+ (off >= len) ||
|
||||
+ ((vma->vm_end - vma->vm_start) > (len - off)))
|
||||
+ return -EINVAL;
|
||||
/* Set VM flags. */
|
||||
start &= PAGE_MASK;
|
||||
- if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
- return -EINVAL;
|
||||
off += start;
|
||||
+ if (off < start)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
/* This is an IO map - tell maydump to skip this VMA */
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED;
|
||||
--
|
||||
cgit v1.1
|
||||
|
56
Patches/Linux_CVEs/CVE-2013-2596/ANY/0003.patch
Normal file
56
Patches/Linux_CVEs/CVE-2013-2596/ANY/0003.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From cdde1a87792a52274763eb006d326ca254ec3c63 Mon Sep 17 00:00:00 2001
|
||||
From: Manoj Rao <manojraj@codeaurora.org>
|
||||
Date: Fri, 12 Apr 2013 18:37:14 -0700
|
||||
Subject: msm: msm_fb: remove mmio access through mmap
|
||||
|
||||
Disable access to mm io and add
|
||||
appropriate range checks to ensure valid accesses
|
||||
through framebuffer mmap. This prevents illegal
|
||||
access into memory.
|
||||
|
||||
CRs-Fixed: 474706
|
||||
Change-Id: If25166f2732433ef967e99c716440030b567aae9
|
||||
Signed-off-by: Manoj Rao <manojraj@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/msm_fb.c | 21 ++++++++-------------
|
||||
1 file changed, 8 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/msm/msm_fb.c
|
||||
index adf50ed..9efe766 100644
|
||||
--- a/drivers/video/msm/msm_fb.c
|
||||
+++ b/drivers/video/msm/msm_fb.c
|
||||
@@ -1166,23 +1166,18 @@ static int msm_fb_mmap(struct fb_info *info, struct vm_area_struct * vma)
|
||||
if (!start)
|
||||
return -EINVAL;
|
||||
|
||||
- msm_fb_pan_idle(mfd);
|
||||
- if (off >= len) {
|
||||
- /* memory mapped io */
|
||||
- off -= len;
|
||||
- if (info->var.accel_flags) {
|
||||
- mutex_unlock(&info->lock);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- start = info->fix.mmio_start;
|
||||
- len = PAGE_ALIGN((start & ~PAGE_MASK) + info->fix.mmio_len);
|
||||
- }
|
||||
+ if ((vma->vm_end <= vma->vm_start) ||
|
||||
+ (off >= len) ||
|
||||
+ ((vma->vm_end - vma->vm_start) > (len - off)))
|
||||
+ return -EINVAL;
|
||||
|
||||
+ msm_fb_pan_idle(mfd);
|
||||
/* Set VM flags. */
|
||||
start &= PAGE_MASK;
|
||||
- if ((vma->vm_end - vma->vm_start + off) > len)
|
||||
- return -EINVAL;
|
||||
off += start;
|
||||
+ if (off < start)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
vma->vm_pgoff = off >> PAGE_SHIFT;
|
||||
/* This is an IO map - tell maydump to skip this VMA */
|
||||
vma->vm_flags |= VM_IO | VM_RESERVED;
|
||||
--
|
||||
cgit v1.1
|
||||
|
32
Patches/Linux_CVEs/CVE-2013-2597/ANY/0001.patch
Normal file
32
Patches/Linux_CVEs/CVE-2013-2597/ANY/0001.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From b44d5f71da7d2c44a7575376c582f9f1cde1cf6d Mon Sep 17 00:00:00 2001
|
||||
From: Ben Romberger <bromberg@codeaurora.org>
|
||||
Date: Wed, 3 Apr 2013 16:20:18 -0700
|
||||
Subject: ASoC: msm: Add size safety check to ACDB driver
|
||||
|
||||
Check that the size sent by userspace is not larger
|
||||
then the internal amount allowed. This protects
|
||||
against overflowing the stack due to an invalid size.
|
||||
|
||||
Change-Id: I4a5b5ca5212bea32b671027d68a66367c5d4c4e7
|
||||
CRs-fixed: 470222
|
||||
Signed-off-by: Ben Romberger <bromberg@codeaurora.org>
|
||||
---
|
||||
sound/soc/msm/qdsp6v2/audio_acdb.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/soc/msm/qdsp6v2/audio_acdb.c b/sound/soc/msm/qdsp6v2/audio_acdb.c
|
||||
index 16d6e81c..b2a469b 100644
|
||||
--- a/sound/soc/msm/qdsp6v2/audio_acdb.c
|
||||
+++ b/sound/soc/msm/qdsp6v2/audio_acdb.c
|
||||
@@ -1064,7 +1064,7 @@ static long acdb_ioctl(struct file *f,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (size <= 0) {
|
||||
+ if ((size <= 0) || (size > sizeof(data))) {
|
||||
pr_err("%s: Invalid size sent to driver: %d\n",
|
||||
__func__, size);
|
||||
result = -EFAULT;
|
||||
--
|
||||
cgit v1.1
|
||||
|
32
Patches/Linux_CVEs/CVE-2013-2597/ANY/0002.patch
Normal file
32
Patches/Linux_CVEs/CVE-2013-2597/ANY/0002.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 76fb3e419e2b149292c3adf1e9171e2b542831bf Mon Sep 17 00:00:00 2001
|
||||
From: Ben Romberger <bromberg@codeaurora.org>
|
||||
Date: Wed, 8 May 2013 12:46:26 -0700
|
||||
Subject: msm: audio: qdsp6v2: Add size safety check to ACDB driver
|
||||
|
||||
Check that the size sent by userspace is not larger
|
||||
then the internal amount allowed. This protects
|
||||
against overflowing the stack due to an invalid size.
|
||||
|
||||
Change-Id: I8230fdb00a7b57d398929e8ab0eb6587476f3db1
|
||||
CRs-fixed: 470222
|
||||
Signed-off-by: Ben Romberger <bromberg@codeaurora.org>
|
||||
---
|
||||
arch/arm/mach-msm/qdsp6v2/audio_acdb.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
|
||||
index 8efd808..aad14be 100644
|
||||
--- a/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
|
||||
+++ b/arch/arm/mach-msm/qdsp6v2/audio_acdb.c
|
||||
@@ -770,7 +770,7 @@ static long acdb_ioctl(struct file *f,
|
||||
goto done;
|
||||
}
|
||||
|
||||
- if (size <= 0) {
|
||||
+ if ((size <= 0) || (size > sizeof(data))) {
|
||||
pr_err("%s: Invalid size sent to driver: %d\n",
|
||||
__func__, size);
|
||||
result = -EFAULT;
|
||||
--
|
||||
cgit v1.1
|
||||
|
125
Patches/Linux_CVEs/CVE-2013-4736/ANY/0002.patch
Normal file
125
Patches/Linux_CVEs/CVE-2013-4736/ANY/0002.patch
Normal file
@ -0,0 +1,125 @@
|
||||
From 8c5300aec8cd9882b89e9d169680221541da0d7f Mon Sep 17 00:00:00 2001
|
||||
From: Monika Alekhya <malekh@codeaurora.org>
|
||||
Date: Fri, 28 Jun 2013 18:23:40 +0530
|
||||
Subject: msm:camera: Fix overflow issue in ioctl_hw_cmds function
|
||||
|
||||
'len' is of type signed int 32bit,but the assigned value
|
||||
may exceed maximum unsigned int32 range.Add overflow check
|
||||
and graceful exit if 'm'exceeds UINT32_MAX value.
|
||||
|
||||
Change-Id: I38f0d10a0cb44d08d0054f91044fc891c246ebd1
|
||||
CRs-Fixed: 493314
|
||||
Signed-off-by: Monika Alekhya <malekh@codeaurora.org>
|
||||
---
|
||||
drivers/media/video/msm/gemini/msm_gemini_sync.c | 9 ++++++++-
|
||||
drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c | 10 ++++++++--
|
||||
drivers/media/video/msm/mercury/msm_mercury_sync.c | 10 ++++++++--
|
||||
3 files changed, 24 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/video/msm/gemini/msm_gemini_sync.c b/drivers/media/video/msm/gemini/msm_gemini_sync.c
|
||||
index ef727fd..f5089ae 100644
|
||||
--- a/drivers/media/video/msm/gemini/msm_gemini_sync.c
|
||||
+++ b/drivers/media/video/msm/gemini/msm_gemini_sync.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <mach/msm_bus.h>
|
||||
#include <mach/msm_bus_board.h>
|
||||
|
||||
+# define UINT32_MAX (4294967295U)
|
||||
static int release_buf;
|
||||
|
||||
/* size is based on 4k page size */
|
||||
@@ -804,7 +805,7 @@ int msm_gemini_ioctl_hw_cmds(struct msm_gemini_device *pgmn_dev,
|
||||
void * __user arg)
|
||||
{
|
||||
int is_copy_to_user;
|
||||
- int len;
|
||||
+ uint32_t len;
|
||||
uint32_t m;
|
||||
struct msm_gemini_hw_cmds *hw_cmds_p;
|
||||
struct msm_gemini_hw_cmd *hw_cmd_p;
|
||||
@@ -813,6 +814,12 @@ int msm_gemini_ioctl_hw_cmds(struct msm_gemini_device *pgmn_dev,
|
||||
GMN_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
+ if ((m == 0) || (m > ((UINT32_MAX-sizeof(struct msm_gemini_hw_cmds))/
|
||||
+ sizeof(struct msm_gemini_hw_cmd)))) {
|
||||
+ GMN_PR_ERR("%s:%d] outof range of hwcmds\n",
|
||||
+ __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
len = sizeof(struct msm_gemini_hw_cmds) +
|
||||
sizeof(struct msm_gemini_hw_cmd) * (m - 1);
|
||||
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
|
||||
index 6ac4a5e..4a81fa6 100644
|
||||
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
|
||||
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_sync.c
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "msm_jpeg_platform.h"
|
||||
#include "msm_jpeg_common.h"
|
||||
|
||||
+#define UINT32_MAX (4294967295U)
|
||||
static int release_buf;
|
||||
|
||||
inline void msm_jpeg_q_init(char const *name, struct msm_jpeg_q *q_p)
|
||||
@@ -631,7 +632,7 @@ int msm_jpeg_ioctl_hw_cmds(struct msm_jpeg_device *pgmn_dev,
|
||||
void * __user arg)
|
||||
{
|
||||
int is_copy_to_user;
|
||||
- int len;
|
||||
+ uint32_t len;
|
||||
uint32_t m;
|
||||
struct msm_jpeg_hw_cmds *hw_cmds_p;
|
||||
struct msm_jpeg_hw_cmd *hw_cmd_p;
|
||||
@@ -640,7 +641,12 @@ int msm_jpeg_ioctl_hw_cmds(struct msm_jpeg_device *pgmn_dev,
|
||||
JPEG_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
-
|
||||
+ if ((m == 0) || (m > ((UINT32_MAX-sizeof(struct msm_jpeg_hw_cmds))/
|
||||
+ sizeof(struct msm_jpeg_hw_cmd)))) {
|
||||
+ JPEG_PR_ERR("%s:%d] outof range of hwcmds\n",
|
||||
+ __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
len = sizeof(struct msm_jpeg_hw_cmds) +
|
||||
sizeof(struct msm_jpeg_hw_cmd) * (m - 1);
|
||||
hw_cmds_p = kmalloc(len, GFP_KERNEL);
|
||||
diff --git a/drivers/media/video/msm/mercury/msm_mercury_sync.c b/drivers/media/video/msm/mercury/msm_mercury_sync.c
|
||||
index 9293aad..fe74a0a 100644
|
||||
--- a/drivers/media/video/msm/mercury/msm_mercury_sync.c
|
||||
+++ b/drivers/media/video/msm/mercury/msm_mercury_sync.c
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "msm_mercury_macros.h"
|
||||
#include "msm_mercury_hw_reg.h"
|
||||
|
||||
+#define UINT32_MAX (4294967295U)
|
||||
static struct msm_mercury_core_buf out_buf_local;
|
||||
static struct msm_mercury_core_buf in_buf_local;
|
||||
|
||||
@@ -470,7 +471,7 @@ int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmercury_dev,
|
||||
void * __user arg)
|
||||
{
|
||||
int is_copy_to_user;
|
||||
- int len;
|
||||
+ uint32_t len;
|
||||
uint32_t m;
|
||||
struct msm_mercury_hw_cmds *hw_cmds_p;
|
||||
struct msm_mercury_hw_cmd *hw_cmd_p;
|
||||
@@ -479,7 +480,12 @@ int msm_mercury_ioctl_hw_cmds(struct msm_mercury_device *pmercury_dev,
|
||||
MCR_PR_ERR("%s:%d] failed\n", __func__, __LINE__);
|
||||
return -EFAULT;
|
||||
}
|
||||
-
|
||||
+ if ((m == 0) || (m > ((UINT32_MAX-sizeof(struct msm_mercury_hw_cmds))/
|
||||
+ sizeof(struct msm_mercury_hw_cmd)))) {
|
||||
+ MCR_PR_ERR("%s:%d] outof range of hwcmds\n",
|
||||
+ __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
len = sizeof(struct msm_mercury_hw_cmds) +
|
||||
sizeof(struct msm_mercury_hw_cmd) * (m - 1);
|
||||
hw_cmds_p = kmalloc(len, GFP_KERNEL);
|
||||
--
|
||||
cgit v1.1
|
||||
|
101
Patches/Linux_CVEs/CVE-2013-4736/ANY/0003.patch
Normal file
101
Patches/Linux_CVEs/CVE-2013-4736/ANY/0003.patch
Normal file
@ -0,0 +1,101 @@
|
||||
From 81947189009afcfac17d1106101260c660421265 Mon Sep 17 00:00:00 2001
|
||||
From: Monika Alekhya <malekh@codeaurora.org>
|
||||
Date: Tue, 11 Jun 2013 19:32:27 +0530
|
||||
Subject: msm:camera: Fix signedness issue in hw_exec_cmds
|
||||
|
||||
In hw_exec_cmds()second argument m_cmds should be
|
||||
of type unsigned interger
|
||||
|
||||
Change-Id: Idad2eb1a59481f3fe9f90221ff2061e8dae57013
|
||||
CRs-Fixed: 493314
|
||||
Signed-off-by: Monika Alekhya <malekh@codeaurora.org>
|
||||
---
|
||||
drivers/media/video/msm/gemini/msm_gemini_hw.c | 2 +-
|
||||
drivers/media/video/msm/gemini/msm_gemini_hw.h | 2 +-
|
||||
drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c | 2 +-
|
||||
drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h | 2 +-
|
||||
drivers/media/video/msm/mercury/msm_mercury_hw.c | 2 +-
|
||||
drivers/media/video/msm/mercury/msm_mercury_hw.h | 2 +-
|
||||
6 files changed, 6 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.c b/drivers/media/video/msm/gemini/msm_gemini_hw.c
|
||||
index 116edcf..99b76be 100644
|
||||
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.c
|
||||
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.c
|
||||
@@ -432,7 +432,7 @@ void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us)
|
||||
}
|
||||
}
|
||||
|
||||
-int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds)
|
||||
+int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, uint32_t m_cmds)
|
||||
{
|
||||
int is_copy_to_user = -1;
|
||||
uint32_t data;
|
||||
diff --git a/drivers/media/video/msm/gemini/msm_gemini_hw.h b/drivers/media/video/msm/gemini/msm_gemini_hw.h
|
||||
index 0abd4c4..23d31ef 100644
|
||||
--- a/drivers/media/video/msm/gemini/msm_gemini_hw.h
|
||||
+++ b/drivers/media/video/msm/gemini/msm_gemini_hw.h
|
||||
@@ -94,7 +94,7 @@ uint32_t msm_gemini_hw_read(struct msm_gemini_hw_cmd *hw_cmd_p);
|
||||
void msm_gemini_hw_write(struct msm_gemini_hw_cmd *hw_cmd_p);
|
||||
int msm_gemini_hw_wait(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
|
||||
void msm_gemini_hw_delay(struct msm_gemini_hw_cmd *hw_cmd_p, int m_us);
|
||||
-int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, int m_cmds);
|
||||
+int msm_gemini_hw_exec_cmds(struct msm_gemini_hw_cmd *hw_cmd_p, uint32_t m_cmds);
|
||||
void msm_gemini_hw_region_dump(int size);
|
||||
void msm_gemini_io_dump(int size);
|
||||
|
||||
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
|
||||
index 0bfb6a8..d92caab 100644
|
||||
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
|
||||
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.c
|
||||
@@ -295,7 +295,7 @@ void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us)
|
||||
}
|
||||
}
|
||||
|
||||
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds)
|
||||
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds)
|
||||
{
|
||||
int is_copy_to_user = -1;
|
||||
uint32_t data;
|
||||
diff --git a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
|
||||
index 73a0e27..5545115 100644
|
||||
--- a/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
|
||||
+++ b/drivers/media/video/msm/jpeg_10/msm_jpeg_hw.h
|
||||
@@ -94,7 +94,7 @@ uint32_t msm_jpeg_hw_read(struct msm_jpeg_hw_cmd *hw_cmd_p);
|
||||
void msm_jpeg_hw_write(struct msm_jpeg_hw_cmd *hw_cmd_p);
|
||||
int msm_jpeg_hw_wait(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
|
||||
void msm_jpeg_hw_delay(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_us);
|
||||
-int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, int m_cmds);
|
||||
+int msm_jpeg_hw_exec_cmds(struct msm_jpeg_hw_cmd *hw_cmd_p, uint32_t m_cmds);
|
||||
void msm_jpeg_hw_region_dump(int size);
|
||||
void msm_jpeg_io_dump(int size);
|
||||
|
||||
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.c b/drivers/media/video/msm/mercury/msm_mercury_hw.c
|
||||
index 244c038..a940dd6 100644
|
||||
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.c
|
||||
+++ b/drivers/media/video/msm/mercury/msm_mercury_hw.c
|
||||
@@ -263,7 +263,7 @@ void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us)
|
||||
}
|
||||
}
|
||||
|
||||
-int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds)
|
||||
+int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, uint32_t m_cmds)
|
||||
{
|
||||
int is_copy_to_user = -1;
|
||||
uint32_t data;
|
||||
diff --git a/drivers/media/video/msm/mercury/msm_mercury_hw.h b/drivers/media/video/msm/mercury/msm_mercury_hw.h
|
||||
index 54fc818..f69d8ba 100644
|
||||
--- a/drivers/media/video/msm/mercury/msm_mercury_hw.h
|
||||
+++ b/drivers/media/video/msm/mercury/msm_mercury_hw.h
|
||||
@@ -55,7 +55,7 @@ uint32_t msm_mercury_hw_read(struct msm_mercury_hw_cmd *hw_cmd_p);
|
||||
void msm_mercury_hw_write(struct msm_mercury_hw_cmd *hw_cmd_p);
|
||||
int msm_mercury_hw_wait(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
|
||||
void msm_mercury_hw_delay(struct msm_mercury_hw_cmd *hw_cmd_p, int m_us);
|
||||
-int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, int m_cmds);
|
||||
+int msm_mercury_hw_exec_cmds(struct msm_mercury_hw_cmd *hw_cmd_p, uint32_t m_cmds);
|
||||
void msm_mercury_hw_region_dump(int size);
|
||||
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
150
Patches/Linux_CVEs/CVE-2013-4737/ANY/0001.patch
Normal file
150
Patches/Linux_CVEs/CVE-2013-4737/ANY/0001.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From 4256415b296348ff16cd17a5b8f8dce4dea37328 Mon Sep 17 00:00:00 2001
|
||||
From: Larry Bassel <lbassel@codeaurora.org>
|
||||
Date: Mon, 29 Jul 2013 13:43:17 -0700
|
||||
Subject: msm: Make CONFIG_STRICT_MEMORY_RWX even stricter
|
||||
|
||||
If CONFIG_STRICT_MEMORY_RWX was set, the first section (containing
|
||||
the kernel page table and the initial code) and the section
|
||||
containing the init code were both given RWX permission, which is
|
||||
a potential security hole.
|
||||
|
||||
Pad the first section after the initial code (which will never
|
||||
be executed when the MMU is on) to make the rest of the kernel
|
||||
text start in the second section and make the first section RW.
|
||||
|
||||
Move some data which had ended up in the "init text"
|
||||
section into the "init data" one, as this is RW, not RX.
|
||||
Make the "init text" RX.
|
||||
|
||||
We will not free the section containing the "init text",
|
||||
because if we do, the kernel will allocate memory for RW data there.
|
||||
|
||||
Change-Id: I6ca5f4e07342c374246f04a3fee18042fd47c33b
|
||||
CRs-fixed: 513919
|
||||
Signed-off-by: Larry Bassel <lbassel@codeaurora.org>
|
||||
---
|
||||
arch/arm/kernel/vmlinux.lds.S | 12 +++++++-----
|
||||
arch/arm/mm/init.c | 9 +++++++++
|
||||
arch/arm/mm/mmu.c | 15 +++++++--------
|
||||
3 files changed, 23 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/kernel/vmlinux.lds.S b/arch/arm/kernel/vmlinux.lds.S
|
||||
index ae59e5a..0bf55ae 100644
|
||||
--- a/arch/arm/kernel/vmlinux.lds.S
|
||||
+++ b/arch/arm/kernel/vmlinux.lds.S
|
||||
@@ -93,6 +93,9 @@ SECTIONS
|
||||
_text = .;
|
||||
HEAD_TEXT
|
||||
}
|
||||
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
+ . = ALIGN(1<<SECTION_SHIFT);
|
||||
+#endif
|
||||
|
||||
.text : { /* Real text segment */
|
||||
_stext = .; /* Text and read-only data */
|
||||
@@ -115,10 +118,10 @@ SECTIONS
|
||||
*(.got) /* Global offset table */
|
||||
ARM_CPU_KEEP(PROC_INFO)
|
||||
}
|
||||
+
|
||||
#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
. = ALIGN(1<<SECTION_SHIFT);
|
||||
#endif
|
||||
-
|
||||
RO_DATA(PAGE_SIZE)
|
||||
|
||||
#ifdef CONFIG_ARM_UNWIND
|
||||
@@ -156,6 +159,9 @@ SECTIONS
|
||||
.init.proc.info : {
|
||||
ARM_CPU_DISCARD(PROC_INFO)
|
||||
}
|
||||
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
+ . = ALIGN(1<<SECTION_SHIFT);
|
||||
+#endif
|
||||
.init.arch.info : {
|
||||
__arch_info_begin = .;
|
||||
*(.arch.info.init)
|
||||
@@ -190,10 +196,6 @@ SECTIONS
|
||||
INIT_RAM_FS
|
||||
}
|
||||
#ifndef CONFIG_XIP_KERNEL
|
||||
-#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
- . = ALIGN(1<<SECTION_SHIFT);
|
||||
-#endif
|
||||
- __init_data = .;
|
||||
.exit.data : {
|
||||
ARM_EXIT_KEEP(EXIT_DATA)
|
||||
}
|
||||
diff --git a/arch/arm/mm/init.c b/arch/arm/mm/init.c
|
||||
index 34cb153..e82ea2b 100644
|
||||
--- a/arch/arm/mm/init.c
|
||||
+++ b/arch/arm/mm/init.c
|
||||
@@ -909,6 +909,14 @@ void free_initmem(void)
|
||||
"TCM link");
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
+ poison_init_mem((char *)__arch_info_begin,
|
||||
+ __init_end - (char *)__arch_info_begin);
|
||||
+ reclaimed_initmem = free_area(__phys_to_pfn(__pa(__arch_info_begin)),
|
||||
+ __phys_to_pfn(__pa(__init_end)),
|
||||
+ "init");
|
||||
+ totalram_pages += reclaimed_initmem;
|
||||
+#else
|
||||
poison_init_mem(__init_begin, __init_end - __init_begin);
|
||||
if (!machine_is_integrator() && !machine_is_cintegrator()) {
|
||||
reclaimed_initmem = free_area(__phys_to_pfn(__pa(__init_begin)),
|
||||
@@ -916,6 +924,7 @@ void free_initmem(void)
|
||||
"init");
|
||||
totalram_pages += reclaimed_initmem;
|
||||
}
|
||||
+#endif
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BLK_DEV_INITRD
|
||||
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
|
||||
index c2efc34..e5a60a9 100644
|
||||
--- a/arch/arm/mm/mmu.c
|
||||
+++ b/arch/arm/mm/mmu.c
|
||||
@@ -1379,8 +1379,6 @@ void mem_text_write_kernel_word(unsigned long *addr, unsigned long word)
|
||||
}
|
||||
EXPORT_SYMBOL(mem_text_write_kernel_word);
|
||||
|
||||
-extern char __init_data[];
|
||||
-
|
||||
static void __init map_lowmem(void)
|
||||
{
|
||||
struct memblock_region *reg;
|
||||
@@ -1401,7 +1399,7 @@ static void __init map_lowmem(void)
|
||||
#ifdef CONFIG_STRICT_MEMORY_RWX
|
||||
if (start <= __pa(_text) && __pa(_text) < end) {
|
||||
map.length = SECTION_SIZE;
|
||||
- map.type = MT_MEMORY;
|
||||
+ map.type = MT_MEMORY_RW;
|
||||
|
||||
create_mapping(&map);
|
||||
|
||||
@@ -1421,14 +1419,15 @@ static void __init map_lowmem(void)
|
||||
|
||||
map.pfn = __phys_to_pfn(__pa(__init_begin));
|
||||
map.virtual = (unsigned long)__init_begin;
|
||||
- map.length = __init_data - __init_begin;
|
||||
- map.type = MT_MEMORY;
|
||||
+ map.length = (char *)__arch_info_begin - __init_begin;
|
||||
+ map.type = MT_MEMORY_RX;
|
||||
|
||||
create_mapping(&map);
|
||||
|
||||
- map.pfn = __phys_to_pfn(__pa(__init_data));
|
||||
- map.virtual = (unsigned long)__init_data;
|
||||
- map.length = __phys_to_virt(end) - (unsigned int)__init_data;
|
||||
+ map.pfn = __phys_to_pfn(__pa(__arch_info_begin));
|
||||
+ map.virtual = (unsigned long)__arch_info_begin;
|
||||
+ map.length = __phys_to_virt(end) -
|
||||
+ (unsigned long)__arch_info_begin;
|
||||
map.type = MT_MEMORY_RW;
|
||||
} else {
|
||||
map.length = end - start;
|
||||
--
|
||||
cgit v1.1
|
||||
|
34
Patches/Linux_CVEs/CVE-2013-4738/ANY/0001.patch
Normal file
34
Patches/Linux_CVEs/CVE-2013-4738/ANY/0001.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From c9c81836ee44db9974007d34cf2aaeb1a51a8d45 Mon Sep 17 00:00:00 2001
|
||||
From: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
Date: Fri, 9 Aug 2013 11:21:50 -0700
|
||||
Subject: msm: camera: Bound check length for Dequeue stream buff info
|
||||
|
||||
Bound check the length param from user space given to
|
||||
copy_from_user function to avoid any invalid memory access.
|
||||
|
||||
Change-Id: I926509a5fffd49cfc0130d182f246fbb9335b60e
|
||||
CRs-Fixed: 519124
|
||||
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
|
||||
index d302131..3aaff78 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/pproc/vpe/msm_vpe.c
|
||||
@@ -1323,6 +1323,11 @@ static long msm_vpe_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
struct msm_vpe_buff_queue_info_t *buff_queue_info;
|
||||
|
||||
VPE_DBG("VIDIOC_MSM_VPE_DEQUEUE_STREAM_BUFF_INFO\n");
|
||||
+ if (ioctl_ptr->len != sizeof(uint32_t)) {
|
||||
+ pr_err("%s:%d Invalid len\n", __func__, __LINE__);
|
||||
+ mutex_unlock(&vpe_dev->mutex);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
rc = (copy_from_user(&identity,
|
||||
(void __user *)ioctl_ptr->ioctl_ptr,
|
||||
--
|
||||
cgit v1.1
|
||||
|
33
Patches/Linux_CVEs/CVE-2013-4738/ANY/0002.patch
Normal file
33
Patches/Linux_CVEs/CVE-2013-4738/ANY/0002.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 28385b9c3054c91dca1aa194ffa750550c50f3ce Mon Sep 17 00:00:00 2001
|
||||
From: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
Date: Fri, 26 Jul 2013 13:39:05 -0700
|
||||
Subject: msm: camera: Add lower and upper bounds check in msm_cpp.c ioctl()
|
||||
|
||||
Add a check for upper and lower bounds in msm_cpp_subdev_ioctl() for
|
||||
command code VIDIOC_MSM_CPP_DEQUEUE_STREAM_BUFF_INFO.
|
||||
|
||||
CRs-fixed: 518731
|
||||
Change-Id: I72996e13b7370a3b49f645297c52a118775b2b12
|
||||
Signed-off-by: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
|
||||
index 822c0c8..8c8570d 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/pproc/cpp/msm_cpp.c
|
||||
@@ -1536,6 +1536,10 @@ long msm_cpp_subdev_ioctl(struct v4l2_subdev *sd,
|
||||
uint32_t identity;
|
||||
struct msm_cpp_buff_queue_info_t *buff_queue_info;
|
||||
|
||||
+ if ((ioctl_ptr->len == 0) ||
|
||||
+ (ioctl_ptr->len > sizeof(uint32_t)))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
rc = (copy_from_user(&identity,
|
||||
(void __user *)ioctl_ptr->ioctl_ptr,
|
||||
ioctl_ptr->len) ? -EFAULT : 0);
|
||||
--
|
||||
cgit v1.1
|
||||
|
50
Patches/Linux_CVEs/CVE-2013-4739/ANY/0001.patch
Normal file
50
Patches/Linux_CVEs/CVE-2013-4739/ANY/0001.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 8604847927f952cc8e773b97eca24e1060a570f2 Mon Sep 17 00:00:00 2001
|
||||
From: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
Date: Thu, 25 Jul 2013 18:01:32 -0700
|
||||
Subject: msm: camera: Fix uninitialized memory returned to userspace
|
||||
|
||||
Local structures have not been initialized to all zeroes, so fix
|
||||
this by setting them to all zeroes to prevent uninitialized memory
|
||||
being copied to userspace.
|
||||
|
||||
CRs-fixed: 518478
|
||||
Change-Id: I6e76355c3f854514def1bd18dcc5c3ef6db38f16
|
||||
Signed-off-by: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c | 3 ++-
|
||||
drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c | 1 +
|
||||
2 files changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c
|
||||
index 9293aad..e6483c1 100644
|
||||
--- a/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c
|
||||
+++ b/drivers/media/platform/msm/camera_v1/mercury/msm_mercury_sync.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
|
||||
+/* Copyright (c) 2012-2013, 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
|
||||
@@ -196,6 +196,7 @@ int msm_mercury_evt_get(struct msm_mercury_device *pmercury_dev,
|
||||
int rc = 0;
|
||||
|
||||
MCR_DBG("(%d)%s() Enter\n", __LINE__, __func__);
|
||||
+ memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
|
||||
ctrl_cmd.type = (uint32_t)msm_mercury_q_wait(&pmercury_dev->evt_q);
|
||||
|
||||
rc = copy_to_user(arg, &ctrl_cmd, sizeof(ctrl_cmd));
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
|
||||
index aa6f034..debbf03 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/jpeg_10/msm_jpeg_sync.c
|
||||
@@ -221,6 +221,7 @@ int msm_jpeg_evt_get(struct msm_jpeg_device *pgmn_dev,
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
+ memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
|
||||
ctrl_cmd.type = buf_p->vbuf.type;
|
||||
kfree(buf_p);
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
300
Patches/Linux_CVEs/CVE-2013-4740/ANY/0001.patch
Normal file
300
Patches/Linux_CVEs/CVE-2013-4740/ANY/0001.patch
Normal file
@ -0,0 +1,300 @@
|
||||
From f53bcf29a6e7a66b3d935b8d562fa00829261f05 Mon Sep 17 00:00:00 2001
|
||||
From: Bingzhe Cai <bingzhec@codeaurora.org>
|
||||
Date: Tue, 24 Sep 2013 01:42:12 +0800
|
||||
Subject: input: touchpanel: fix security issues in GT915 driver
|
||||
|
||||
There are multiple buffer overflow and input validation issues
|
||||
in Goodix gt915 driver, fix these issues by adding data length
|
||||
check and change file system node mode.
|
||||
|
||||
CRs-Fixed: 526101
|
||||
Change-Id: I5173fc1ca021fd45c939c7c8a4f460651330de5b
|
||||
Signed-off-by: Bingzhe Cai <bingzhec@codeaurora.org>
|
||||
---
|
||||
drivers/input/touchscreen/gt9xx/goodix_tool.c | 110 +++++++++++++++++++-------
|
||||
1 file changed, 83 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
index bdac3fd..aa8159f 100644
|
||||
--- a/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
+++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "gt9xx.h"
|
||||
+#include <linux/mutex.h>
|
||||
|
||||
#define DATA_LENGTH_UINT 512
|
||||
#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8 *))
|
||||
@@ -53,6 +54,8 @@ static struct i2c_client *gt_client;
|
||||
|
||||
static struct proc_dir_entry *goodix_proc_entry;
|
||||
|
||||
+static struct mutex lock;
|
||||
+
|
||||
static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
unsigned long len, void *data);
|
||||
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
@@ -188,7 +191,7 @@ static void unregister_i2c_func(void)
|
||||
|
||||
s32 init_wr_node(struct i2c_client *client)
|
||||
{
|
||||
- s32 i;
|
||||
+ u8 i;
|
||||
|
||||
gt_client = client;
|
||||
memset(&cmd_head, 0, sizeof(cmd_head));
|
||||
@@ -202,8 +205,8 @@ s32 init_wr_node(struct i2c_client *client)
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
- DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH;
|
||||
- GTP_INFO("Applied memory size:%d.", DATA_LENGTH);
|
||||
+ DATA_LENGTH = i * DATA_LENGTH_UINT;
|
||||
+ dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH);
|
||||
} else {
|
||||
GTP_ERROR("Apply for memory failed.");
|
||||
return FAIL;
|
||||
@@ -214,8 +217,9 @@ s32 init_wr_node(struct i2c_client *client)
|
||||
|
||||
register_i2c_func();
|
||||
|
||||
+ mutex_init(&lock);
|
||||
tool_set_proc_name(procname);
|
||||
- goodix_proc_entry = create_proc_entry(procname, 0666, NULL);
|
||||
+ goodix_proc_entry = create_proc_entry(procname, 0660, NULL);
|
||||
if (goodix_proc_entry == NULL) {
|
||||
GTP_ERROR("Couldn't create proc entry!");
|
||||
return FAIL;
|
||||
@@ -334,9 +338,13 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
GTP_DEBUG_FUNC();
|
||||
GTP_DEBUG_ARRAY((u8 *)buff, len);
|
||||
|
||||
+ mutex_lock(&lock);
|
||||
ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
GTP_ERROR("copy_from_user failed.");
|
||||
+ ret = -EACCES;
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
GTP_DEBUG("wr :0x%02x.", cmd_head.wr);
|
||||
GTP_DEBUG("flag:0x%02x.", cmd_head.flag);
|
||||
@@ -354,6 +362,19 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
GTP_DEBUG("len:%d.", (s32)len);
|
||||
GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]);
|
||||
|
||||
+ if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) {
|
||||
+ pr_err("data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH));
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ if (cmd_head.addr_len > GTP_ADDR_LENGTH) {
|
||||
+ pr_err(" addr len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.addr_len, GTP_ADDR_LENGTH);
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
if (cmd_head.wr == 1) {
|
||||
/* copy_from_user(&cmd_head.data[cmd_head.addr_len],
|
||||
&buff[CMD_HEAD_LENGTH], cmd_head.data_len); */
|
||||
@@ -373,7 +394,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (cmd_head.flag == 1) {
|
||||
if (FAIL == comfirm()) {
|
||||
GTP_ERROR("[WRITE]Comfirm fail!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == 2) {
|
||||
/* Need interrupt! */
|
||||
@@ -382,7 +404,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
|
||||
cmd_head.data_len + cmd_head.addr_len) <= 0) {
|
||||
GTP_ERROR("[WRITE]Write data failed!");
|
||||
- return FAIL;
|
||||
+ ret = -EIO;
|
||||
+ goto exit;
|
||||
}
|
||||
|
||||
GTP_DEBUG_ARRAY(
|
||||
@@ -391,7 +414,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (cmd_head.delay)
|
||||
msleep(cmd_head.delay);
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 3) { /* Write ic type */
|
||||
|
||||
ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH],
|
||||
@@ -399,30 +423,40 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (ret)
|
||||
GTP_ERROR("copy_from_user failed.");
|
||||
|
||||
+ if (cmd_head.data_len > sizeof(IC_TYPE)) {
|
||||
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len, sizeof(IC_TYPE));
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
|
||||
|
||||
register_i2c_func();
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
- } else if (cmd_head.wr == 3) {
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
+ } else if (cmd_head.wr == 5) {
|
||||
|
||||
/* memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); */
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 7) { /* disable irq! */
|
||||
gtp_irq_disable(i2c_get_clientdata(gt_client));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
gtp_esd_switch(gt_client, SWITCH_OFF);
|
||||
#endif
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 9) { /* enable irq! */
|
||||
gtp_irq_enable(i2c_get_clientdata(gt_client));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
gtp_esd_switch(gt_client, SWITCH_ON);
|
||||
#endif
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 17) {
|
||||
struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
|
||||
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
|
||||
@@ -436,27 +470,41 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
ts->gtp_rawdiff_mode = false;
|
||||
GTP_DEBUG("gtp leave rawdiff.");
|
||||
}
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
}
|
||||
#ifdef UPDATE_FUNCTIONS
|
||||
else if (cmd_head.wr == 11) { /* Enter update mode! */
|
||||
- if (FAIL == gup_enter_update_mode(gt_client))
|
||||
- return FAIL;
|
||||
+ if (FAIL == gup_enter_update_mode(gt_client)) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto exit;
|
||||
+ }
|
||||
} else if (cmd_head.wr == 13) { /* Leave update mode! */
|
||||
gup_leave_update_mode();
|
||||
} else if (cmd_head.wr == 15) { /* Update firmware! */
|
||||
show_len = 0;
|
||||
total_len = 0;
|
||||
+ if (cmd_head.data_len + 1 > DATA_LENGTH) {
|
||||
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len + 1, DATA_LENGTH);
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
memset(cmd_head.data, 0, cmd_head.data_len + 1);
|
||||
memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH],
|
||||
cmd_head.data_len);
|
||||
|
||||
- if (FAIL == gup_update_proc((void *)cmd_head.data))
|
||||
- return FAIL;
|
||||
+ if (FAIL == gup_update_proc((void *)cmd_head.data)) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto exit;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+exit:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
@@ -470,10 +518,14 @@ Output:
|
||||
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
int *eof, void *data)
|
||||
{
|
||||
+ s32 ret;
|
||||
GTP_DEBUG_FUNC();
|
||||
|
||||
+ mutex_lock(&lock);
|
||||
if (cmd_head.wr % 2) {
|
||||
- return FAIL;
|
||||
+ pr_err("<< [READ]command head wrong\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
} else if (!cmd_head.wr) {
|
||||
u16 len = 0;
|
||||
s16 data_len = 0;
|
||||
@@ -482,7 +534,8 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
if (cmd_head.flag == 1) {
|
||||
if (FAIL == comfirm()) {
|
||||
GTP_ERROR("[READ]Comfirm fail!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == 2) {
|
||||
/* Need interrupt! */
|
||||
@@ -505,11 +558,12 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
else
|
||||
len = data_len;
|
||||
|
||||
- data_len -= DATA_LENGTH;
|
||||
+ data_len -= len;
|
||||
|
||||
if (tool_i2c_read(cmd_head.data, len) <= 0) {
|
||||
GTP_ERROR("[READ]Read data failed!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH],
|
||||
len);
|
||||
@@ -525,15 +579,14 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
|
||||
GTP_DEBUG("Return ic type:%s len:%d.", page,
|
||||
(s32)cmd_head.data_len);
|
||||
- return cmd_head.data_len;
|
||||
+ ret = cmd_head.data_len;
|
||||
+ goto exit;
|
||||
/* return sizeof(IC_TYPE_NAME); */
|
||||
} else if (cmd_head.wr == 4) {
|
||||
page[0] = show_len >> 8;
|
||||
page[1] = show_len & 0xff;
|
||||
page[2] = total_len >> 8;
|
||||
page[3] = total_len & 0xff;
|
||||
-
|
||||
- return cmd_head.data_len;
|
||||
} else if (6 == cmd_head.wr) {
|
||||
/* Read error code! */
|
||||
} else if (8 == cmd_head.wr) { /*Read driver version */
|
||||
@@ -544,6 +597,9 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
memcpy(page, GTP_DRIVER_VERSION, tmp_len);
|
||||
page[tmp_len] = 0;
|
||||
}
|
||||
+ ret = cmd_head.data_len;
|
||||
|
||||
- return cmd_head.data_len;
|
||||
+exit:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
300
Patches/Linux_CVEs/CVE-2013-6122/ANY/0001.patch
Normal file
300
Patches/Linux_CVEs/CVE-2013-6122/ANY/0001.patch
Normal file
@ -0,0 +1,300 @@
|
||||
From f53bcf29a6e7a66b3d935b8d562fa00829261f05 Mon Sep 17 00:00:00 2001
|
||||
From: Bingzhe Cai <bingzhec@codeaurora.org>
|
||||
Date: Tue, 24 Sep 2013 01:42:12 +0800
|
||||
Subject: input: touchpanel: fix security issues in GT915 driver
|
||||
|
||||
There are multiple buffer overflow and input validation issues
|
||||
in Goodix gt915 driver, fix these issues by adding data length
|
||||
check and change file system node mode.
|
||||
|
||||
CRs-Fixed: 526101
|
||||
Change-Id: I5173fc1ca021fd45c939c7c8a4f460651330de5b
|
||||
Signed-off-by: Bingzhe Cai <bingzhec@codeaurora.org>
|
||||
---
|
||||
drivers/input/touchscreen/gt9xx/goodix_tool.c | 110 +++++++++++++++++++-------
|
||||
1 file changed, 83 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/drivers/input/touchscreen/gt9xx/goodix_tool.c b/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
index bdac3fd..aa8159f 100644
|
||||
--- a/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
+++ b/drivers/input/touchscreen/gt9xx/goodix_tool.c
|
||||
@@ -22,6 +22,7 @@
|
||||
*/
|
||||
|
||||
#include "gt9xx.h"
|
||||
+#include <linux/mutex.h>
|
||||
|
||||
#define DATA_LENGTH_UINT 512
|
||||
#define CMD_HEAD_LENGTH (sizeof(st_cmd_head) - sizeof(u8 *))
|
||||
@@ -53,6 +54,8 @@ static struct i2c_client *gt_client;
|
||||
|
||||
static struct proc_dir_entry *goodix_proc_entry;
|
||||
|
||||
+static struct mutex lock;
|
||||
+
|
||||
static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
unsigned long len, void *data);
|
||||
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
@@ -188,7 +191,7 @@ static void unregister_i2c_func(void)
|
||||
|
||||
s32 init_wr_node(struct i2c_client *client)
|
||||
{
|
||||
- s32 i;
|
||||
+ u8 i;
|
||||
|
||||
gt_client = client;
|
||||
memset(&cmd_head, 0, sizeof(cmd_head));
|
||||
@@ -202,8 +205,8 @@ s32 init_wr_node(struct i2c_client *client)
|
||||
i--;
|
||||
}
|
||||
if (i) {
|
||||
- DATA_LENGTH = i * DATA_LENGTH_UINT + GTP_ADDR_LENGTH;
|
||||
- GTP_INFO("Applied memory size:%d.", DATA_LENGTH);
|
||||
+ DATA_LENGTH = i * DATA_LENGTH_UINT;
|
||||
+ dev_dbg(&client->dev, "Applied memory size:%d.", DATA_LENGTH);
|
||||
} else {
|
||||
GTP_ERROR("Apply for memory failed.");
|
||||
return FAIL;
|
||||
@@ -214,8 +217,9 @@ s32 init_wr_node(struct i2c_client *client)
|
||||
|
||||
register_i2c_func();
|
||||
|
||||
+ mutex_init(&lock);
|
||||
tool_set_proc_name(procname);
|
||||
- goodix_proc_entry = create_proc_entry(procname, 0666, NULL);
|
||||
+ goodix_proc_entry = create_proc_entry(procname, 0660, NULL);
|
||||
if (goodix_proc_entry == NULL) {
|
||||
GTP_ERROR("Couldn't create proc entry!");
|
||||
return FAIL;
|
||||
@@ -334,9 +338,13 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
GTP_DEBUG_FUNC();
|
||||
GTP_DEBUG_ARRAY((u8 *)buff, len);
|
||||
|
||||
+ mutex_lock(&lock);
|
||||
ret = copy_from_user(&cmd_head, buff, CMD_HEAD_LENGTH);
|
||||
- if (ret)
|
||||
+ if (ret) {
|
||||
GTP_ERROR("copy_from_user failed.");
|
||||
+ ret = -EACCES;
|
||||
+ goto exit;
|
||||
+ }
|
||||
|
||||
GTP_DEBUG("wr :0x%02x.", cmd_head.wr);
|
||||
GTP_DEBUG("flag:0x%02x.", cmd_head.flag);
|
||||
@@ -354,6 +362,19 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
GTP_DEBUG("len:%d.", (s32)len);
|
||||
GTP_DEBUG("buf[20]:0x%02x.", buff[CMD_HEAD_LENGTH]);
|
||||
|
||||
+ if (cmd_head.data_len > (DATA_LENGTH - GTP_ADDR_LENGTH)) {
|
||||
+ pr_err("data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len, (DATA_LENGTH - GTP_ADDR_LENGTH));
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+ if (cmd_head.addr_len > GTP_ADDR_LENGTH) {
|
||||
+ pr_err(" addr len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.addr_len, GTP_ADDR_LENGTH);
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
+
|
||||
if (cmd_head.wr == 1) {
|
||||
/* copy_from_user(&cmd_head.data[cmd_head.addr_len],
|
||||
&buff[CMD_HEAD_LENGTH], cmd_head.data_len); */
|
||||
@@ -373,7 +394,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (cmd_head.flag == 1) {
|
||||
if (FAIL == comfirm()) {
|
||||
GTP_ERROR("[WRITE]Comfirm fail!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == 2) {
|
||||
/* Need interrupt! */
|
||||
@@ -382,7 +404,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
&cmd_head.data[GTP_ADDR_LENGTH - cmd_head.addr_len],
|
||||
cmd_head.data_len + cmd_head.addr_len) <= 0) {
|
||||
GTP_ERROR("[WRITE]Write data failed!");
|
||||
- return FAIL;
|
||||
+ ret = -EIO;
|
||||
+ goto exit;
|
||||
}
|
||||
|
||||
GTP_DEBUG_ARRAY(
|
||||
@@ -391,7 +414,8 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (cmd_head.delay)
|
||||
msleep(cmd_head.delay);
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 3) { /* Write ic type */
|
||||
|
||||
ret = copy_from_user(&cmd_head.data[0], &buff[CMD_HEAD_LENGTH],
|
||||
@@ -399,30 +423,40 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
if (ret)
|
||||
GTP_ERROR("copy_from_user failed.");
|
||||
|
||||
+ if (cmd_head.data_len > sizeof(IC_TYPE)) {
|
||||
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len, sizeof(IC_TYPE));
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len);
|
||||
|
||||
register_i2c_func();
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
- } else if (cmd_head.wr == 3) {
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
+ } else if (cmd_head.wr == 5) {
|
||||
|
||||
/* memcpy(IC_TYPE, cmd_head.data, cmd_head.data_len); */
|
||||
|
||||
- return cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ ret = cmd_head.data_len + CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 7) { /* disable irq! */
|
||||
gtp_irq_disable(i2c_get_clientdata(gt_client));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
gtp_esd_switch(gt_client, SWITCH_OFF);
|
||||
#endif
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 9) { /* enable irq! */
|
||||
gtp_irq_enable(i2c_get_clientdata(gt_client));
|
||||
|
||||
#if GTP_ESD_PROTECT
|
||||
gtp_esd_switch(gt_client, SWITCH_ON);
|
||||
#endif
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
} else if (cmd_head.wr == 17) {
|
||||
struct goodix_ts_data *ts = i2c_get_clientdata(gt_client);
|
||||
ret = copy_from_user(&cmd_head.data[GTP_ADDR_LENGTH],
|
||||
@@ -436,27 +470,41 @@ static s32 goodix_tool_write(struct file *filp, const char __user *buff,
|
||||
ts->gtp_rawdiff_mode = false;
|
||||
GTP_DEBUG("gtp leave rawdiff.");
|
||||
}
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
+ goto exit;
|
||||
}
|
||||
#ifdef UPDATE_FUNCTIONS
|
||||
else if (cmd_head.wr == 11) { /* Enter update mode! */
|
||||
- if (FAIL == gup_enter_update_mode(gt_client))
|
||||
- return FAIL;
|
||||
+ if (FAIL == gup_enter_update_mode(gt_client)) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto exit;
|
||||
+ }
|
||||
} else if (cmd_head.wr == 13) { /* Leave update mode! */
|
||||
gup_leave_update_mode();
|
||||
} else if (cmd_head.wr == 15) { /* Update firmware! */
|
||||
show_len = 0;
|
||||
total_len = 0;
|
||||
+ if (cmd_head.data_len + 1 > DATA_LENGTH) {
|
||||
+ pr_err("<<-GTP->> data len %d > data buff %d, rejected!\n",
|
||||
+ cmd_head.data_len + 1, DATA_LENGTH);
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
+ }
|
||||
memset(cmd_head.data, 0, cmd_head.data_len + 1);
|
||||
memcpy(cmd_head.data, &buff[CMD_HEAD_LENGTH],
|
||||
cmd_head.data_len);
|
||||
|
||||
- if (FAIL == gup_update_proc((void *)cmd_head.data))
|
||||
- return FAIL;
|
||||
+ if (FAIL == gup_update_proc((void *)cmd_head.data)) {
|
||||
+ ret = -EBUSY;
|
||||
+ goto exit;
|
||||
+ }
|
||||
}
|
||||
#endif
|
||||
+ ret = CMD_HEAD_LENGTH;
|
||||
|
||||
- return CMD_HEAD_LENGTH;
|
||||
+exit:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
}
|
||||
|
||||
/*******************************************************
|
||||
@@ -470,10 +518,14 @@ Output:
|
||||
static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
int *eof, void *data)
|
||||
{
|
||||
+ s32 ret;
|
||||
GTP_DEBUG_FUNC();
|
||||
|
||||
+ mutex_lock(&lock);
|
||||
if (cmd_head.wr % 2) {
|
||||
- return FAIL;
|
||||
+ pr_err("<< [READ]command head wrong\n");
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
} else if (!cmd_head.wr) {
|
||||
u16 len = 0;
|
||||
s16 data_len = 0;
|
||||
@@ -482,7 +534,8 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
if (cmd_head.flag == 1) {
|
||||
if (FAIL == comfirm()) {
|
||||
GTP_ERROR("[READ]Comfirm fail!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
} else if (cmd_head.flag == 2) {
|
||||
/* Need interrupt! */
|
||||
@@ -505,11 +558,12 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
else
|
||||
len = data_len;
|
||||
|
||||
- data_len -= DATA_LENGTH;
|
||||
+ data_len -= len;
|
||||
|
||||
if (tool_i2c_read(cmd_head.data, len) <= 0) {
|
||||
GTP_ERROR("[READ]Read data failed!");
|
||||
- return FAIL;
|
||||
+ ret = -EINVAL;
|
||||
+ goto exit;
|
||||
}
|
||||
memcpy(&page[loc], &cmd_head.data[GTP_ADDR_LENGTH],
|
||||
len);
|
||||
@@ -525,15 +579,14 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
|
||||
GTP_DEBUG("Return ic type:%s len:%d.", page,
|
||||
(s32)cmd_head.data_len);
|
||||
- return cmd_head.data_len;
|
||||
+ ret = cmd_head.data_len;
|
||||
+ goto exit;
|
||||
/* return sizeof(IC_TYPE_NAME); */
|
||||
} else if (cmd_head.wr == 4) {
|
||||
page[0] = show_len >> 8;
|
||||
page[1] = show_len & 0xff;
|
||||
page[2] = total_len >> 8;
|
||||
page[3] = total_len & 0xff;
|
||||
-
|
||||
- return cmd_head.data_len;
|
||||
} else if (6 == cmd_head.wr) {
|
||||
/* Read error code! */
|
||||
} else if (8 == cmd_head.wr) { /*Read driver version */
|
||||
@@ -544,6 +597,9 @@ static s32 goodix_tool_read(char *page, char **start, off_t off, int count,
|
||||
memcpy(page, GTP_DRIVER_VERSION, tmp_len);
|
||||
page[tmp_len] = 0;
|
||||
}
|
||||
+ ret = cmd_head.data_len;
|
||||
|
||||
- return cmd_head.data_len;
|
||||
+exit:
|
||||
+ mutex_unlock(&lock);
|
||||
+ return ret;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
39
Patches/Linux_CVEs/CVE-2013-6123/ANY/0001.patch
Normal file
39
Patches/Linux_CVEs/CVE-2013-6123/ANY/0001.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From 7beb04ea945a7178e61d935918d3cb152996b558 Mon Sep 17 00:00:00 2001
|
||||
From: Alok Kediya <kediya@codeaurora.org>
|
||||
Date: Mon, 9 Dec 2013 10:52:49 +0530
|
||||
Subject: msm: camera: Added bounds check for index parameter
|
||||
|
||||
Bound check the index param from user space to avoid
|
||||
any invalid memory access.
|
||||
|
||||
CRs-Fixed: 583366
|
||||
|
||||
Change-Id: I0f887bb8f1fa5a69a55e23dbb522b3bb694ad27f
|
||||
Signed-off-by: Alok Kediya <kediya@codeaurora.org>
|
||||
---
|
||||
drivers/media/video/msm/server/msm_cam_server.c | 9 +++++++++
|
||||
1 file changed, 9 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
|
||||
index 5fc8e83..6e49082 100644
|
||||
--- a/drivers/media/video/msm/server/msm_cam_server.c
|
||||
+++ b/drivers/media/video/msm/server/msm_cam_server.c
|
||||
@@ -1390,6 +1390,15 @@ static long msm_ioctl_server(struct file *file, void *fh,
|
||||
}
|
||||
|
||||
mutex_lock(&g_server_dev.server_queue_lock);
|
||||
+
|
||||
+ if(u_isp_event.isp_data.ctrl.queue_idx < 0 ||
|
||||
+ u_isp_event.isp_data.ctrl.queue_idx >= MAX_NUM_ACTIVE_CAMERA) {
|
||||
+ pr_err("%s: Invalid index %d\n", __func__,
|
||||
+ u_isp_event.isp_data.ctrl.queue_idx);
|
||||
+ rc = -EINVAL;
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
if (!g_server_dev.server_queue
|
||||
[u_isp_event.isp_data.ctrl.queue_idx].queue_active) {
|
||||
pr_err("%s: Invalid queue\n", __func__);
|
||||
--
|
||||
cgit v1.1
|
||||
|
67
Patches/Linux_CVEs/CVE-2013-6123/ANY/0002.patch
Normal file
67
Patches/Linux_CVEs/CVE-2013-6123/ANY/0002.patch
Normal file
@ -0,0 +1,67 @@
|
||||
From 60e4af06161d91d5aeaa04c7d6e9f4345a6acdd4 Mon Sep 17 00:00:00 2001
|
||||
From: Alok Kediya <kediya@codeaurora.org>
|
||||
Date: Thu, 10 Oct 2013 12:11:01 +0530
|
||||
Subject: msm:camera: Bounds and validity check for params
|
||||
|
||||
Check the range and validity of parameters before accessing.
|
||||
|
||||
CRs-fixed: 550607, 554434, 554436
|
||||
|
||||
Change-Id: I2d6aec4f9cb9385789c0df6a2c4abefe9e87539f
|
||||
Signed-off-by: Alok Kediya <kediya@codeaurora.org>
|
||||
---
|
||||
drivers/media/video/msm/server/msm_cam_server.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/video/msm/server/msm_cam_server.c b/drivers/media/video/msm/server/msm_cam_server.c
|
||||
index 4bda7a3..5fc8e83 100644
|
||||
--- a/drivers/media/video/msm/server/msm_cam_server.c
|
||||
+++ b/drivers/media/video/msm/server/msm_cam_server.c
|
||||
@@ -311,6 +311,13 @@ static int msm_ctrl_cmd_done(void *arg)
|
||||
goto ctrl_cmd_done_error;
|
||||
}
|
||||
|
||||
+ if(command->queue_idx < 0 ||
|
||||
+ command->queue_idx >= MAX_NUM_ACTIVE_CAMERA) {
|
||||
+ pr_err("%s: Invalid value OR index %d\n", __func__,
|
||||
+ command->queue_idx);
|
||||
+ goto ctrl_cmd_done_error;
|
||||
+ }
|
||||
+
|
||||
if (!g_server_dev.server_queue[command->queue_idx].queue_active) {
|
||||
pr_err("%s: Invalid queue\n", __func__);
|
||||
goto ctrl_cmd_done_error;
|
||||
@@ -339,7 +346,8 @@ static int msm_ctrl_cmd_done(void *arg)
|
||||
max_control_command_size);
|
||||
goto ctrl_cmd_done_error;
|
||||
}
|
||||
- if (copy_from_user(command->value, uptr, command->length)) {
|
||||
+ if (copy_from_user(command->value, (void __user *)uptr,
|
||||
+ command->length)) {
|
||||
pr_err("%s: copy_from_user failed, size=%d\n",
|
||||
__func__, sizeof(struct msm_ctrl_cmd));
|
||||
goto ctrl_cmd_done_error;
|
||||
@@ -2650,13 +2658,17 @@ int msm_server_send_ctrl(struct msm_ctrl_cmd *out,
|
||||
struct msm_queue_cmd *event_qcmd;
|
||||
struct msm_ctrl_cmd *ctrlcmd;
|
||||
struct msm_cam_server_dev *server_dev = &g_server_dev;
|
||||
- struct msm_device_queue *queue =
|
||||
- &server_dev->server_queue[out->queue_idx].ctrl_q;
|
||||
-
|
||||
+ struct msm_device_queue *queue;
|
||||
struct v4l2_event v4l2_evt;
|
||||
struct msm_isp_event_ctrl *isp_event;
|
||||
void *ctrlcmd_data;
|
||||
|
||||
+ if(out->queue_idx < 0 || out->queue_idx >= MAX_NUM_ACTIVE_CAMERA) {
|
||||
+ pr_err("%s: Invalid index %d\n", __func__, out->queue_idx);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ queue = &server_dev->server_queue[out->queue_idx].ctrl_q;
|
||||
+
|
||||
event_qcmd = kzalloc(sizeof(struct msm_queue_cmd), GFP_KERNEL);
|
||||
if (!event_qcmd) {
|
||||
pr_err("%s Insufficient memory. return", __func__);
|
||||
--
|
||||
cgit v1.1
|
||||
|
253
Patches/Linux_CVEs/CVE-2013-6282/ANY/0001.patch
Normal file
253
Patches/Linux_CVEs/CVE-2013-6282/ANY/0001.patch
Normal file
@ -0,0 +1,253 @@
|
||||
From 76565e3d786bed66f247c682bd9f591098522483 Mon Sep 17 00:00:00 2001
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Date: Fri, 7 Sep 2012 18:22:28 +0100
|
||||
Subject: ARM: 7527/1: uaccess: explicitly check __user pointer when
|
||||
!CPU_USE_DOMAINS
|
||||
|
||||
The {get,put}_user macros don't perform range checking on the provided
|
||||
__user address when !CPU_HAS_DOMAINS.
|
||||
|
||||
This patch reworks the out-of-line assembly accessors to check the user
|
||||
address against a specified limit, returning -EFAULT if is is out of
|
||||
range.
|
||||
|
||||
[will: changed get_user register allocation to match put_user]
|
||||
[rmk: fixed building on older ARM architectures]
|
||||
|
||||
CRs-Fixed: 504011
|
||||
Change-Id: I3818045a136fcdf72deb1371b132e090fd7ed643
|
||||
Reported-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Git-commit: 8404663f81d212918ff85f493649a7991209fa04
|
||||
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
Signed-off-by: Laura Abbott <lauraa@codeaurora.org>
|
||||
---
|
||||
arch/arm/include/asm/assembler.h | 8 ++++++++
|
||||
arch/arm/include/asm/uaccess.h | 40 +++++++++++++++++++++++++++-------------
|
||||
arch/arm/lib/getuser.S | 23 +++++++++++++++--------
|
||||
arch/arm/lib/putuser.S | 6 ++++++
|
||||
4 files changed, 56 insertions(+), 21 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/assembler.h b/arch/arm/include/asm/assembler.h
|
||||
index 03fb936..5c8b3bf4 100644
|
||||
--- a/arch/arm/include/asm/assembler.h
|
||||
+++ b/arch/arm/include/asm/assembler.h
|
||||
@@ -320,4 +320,12 @@
|
||||
.size \name , . - \name
|
||||
.endm
|
||||
|
||||
+ .macro check_uaccess, addr:req, size:req, limit:req, tmp:req, bad:req
|
||||
+#ifndef CONFIG_CPU_USE_DOMAINS
|
||||
+ adds \tmp, \addr, #\size - 1
|
||||
+ sbcccs \tmp, \tmp, \limit
|
||||
+ bcs \bad
|
||||
+#endif
|
||||
+ .endm
|
||||
+
|
||||
#endif /* __ASM_ASSEMBLER_H__ */
|
||||
diff --git a/arch/arm/include/asm/uaccess.h b/arch/arm/include/asm/uaccess.h
|
||||
index 71f6536..0a070e9 100644
|
||||
--- a/arch/arm/include/asm/uaccess.h
|
||||
+++ b/arch/arm/include/asm/uaccess.h
|
||||
@@ -101,28 +101,39 @@ extern int __get_user_1(void *);
|
||||
extern int __get_user_2(void *);
|
||||
extern int __get_user_4(void *);
|
||||
|
||||
-#define __get_user_x(__r2,__p,__e,__s,__i...) \
|
||||
+#define __GUP_CLOBBER_1 "lr", "cc"
|
||||
+#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
+#define __GUP_CLOBBER_2 "ip", "lr", "cc"
|
||||
+#else
|
||||
+#define __GUP_CLOBBER_2 "lr", "cc"
|
||||
+#endif
|
||||
+#define __GUP_CLOBBER_4 "lr", "cc"
|
||||
+
|
||||
+#define __get_user_x(__r2,__p,__e,__l,__s) \
|
||||
__asm__ __volatile__ ( \
|
||||
__asmeq("%0", "r0") __asmeq("%1", "r2") \
|
||||
+ __asmeq("%3", "r1") \
|
||||
"bl __get_user_" #__s \
|
||||
: "=&r" (__e), "=r" (__r2) \
|
||||
- : "0" (__p) \
|
||||
- : __i, "cc")
|
||||
+ : "0" (__p), "r" (__l) \
|
||||
+ : __GUP_CLOBBER_##__s)
|
||||
|
||||
#define get_user(x,p) \
|
||||
({ \
|
||||
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||
register const typeof(*(p)) __user *__p asm("r0") = (p);\
|
||||
register unsigned long __r2 asm("r2"); \
|
||||
+ register unsigned long __l asm("r1") = __limit; \
|
||||
register int __e asm("r0"); \
|
||||
switch (sizeof(*(__p))) { \
|
||||
case 1: \
|
||||
- __get_user_x(__r2, __p, __e, 1, "lr"); \
|
||||
- break; \
|
||||
+ __get_user_x(__r2, __p, __e, __l, 1); \
|
||||
+ break; \
|
||||
case 2: \
|
||||
- __get_user_x(__r2, __p, __e, 2, "r3", "lr"); \
|
||||
+ __get_user_x(__r2, __p, __e, __l, 2); \
|
||||
break; \
|
||||
case 4: \
|
||||
- __get_user_x(__r2, __p, __e, 4, "lr"); \
|
||||
+ __get_user_x(__r2, __p, __e, __l, 4); \
|
||||
break; \
|
||||
default: __e = __get_user_bad(); break; \
|
||||
} \
|
||||
@@ -135,31 +146,34 @@ extern int __put_user_2(void *, unsigned int);
|
||||
extern int __put_user_4(void *, unsigned int);
|
||||
extern int __put_user_8(void *, unsigned long long);
|
||||
|
||||
-#define __put_user_x(__r2,__p,__e,__s) \
|
||||
+#define __put_user_x(__r2,__p,__e,__l,__s) \
|
||||
__asm__ __volatile__ ( \
|
||||
__asmeq("%0", "r0") __asmeq("%2", "r2") \
|
||||
+ __asmeq("%3", "r1") \
|
||||
"bl __put_user_" #__s \
|
||||
: "=&r" (__e) \
|
||||
- : "0" (__p), "r" (__r2) \
|
||||
+ : "0" (__p), "r" (__r2), "r" (__l) \
|
||||
: "ip", "lr", "cc")
|
||||
|
||||
#define put_user(x,p) \
|
||||
({ \
|
||||
+ unsigned long __limit = current_thread_info()->addr_limit - 1; \
|
||||
register const typeof(*(p)) __r2 asm("r2") = (x); \
|
||||
register const typeof(*(p)) __user *__p asm("r0") = (p);\
|
||||
+ register unsigned long __l asm("r1") = __limit; \
|
||||
register int __e asm("r0"); \
|
||||
switch (sizeof(*(__p))) { \
|
||||
case 1: \
|
||||
- __put_user_x(__r2, __p, __e, 1); \
|
||||
+ __put_user_x(__r2, __p, __e, __l, 1); \
|
||||
break; \
|
||||
case 2: \
|
||||
- __put_user_x(__r2, __p, __e, 2); \
|
||||
+ __put_user_x(__r2, __p, __e, __l, 2); \
|
||||
break; \
|
||||
case 4: \
|
||||
- __put_user_x(__r2, __p, __e, 4); \
|
||||
+ __put_user_x(__r2, __p, __e, __l, 4); \
|
||||
break; \
|
||||
case 8: \
|
||||
- __put_user_x(__r2, __p, __e, 8); \
|
||||
+ __put_user_x(__r2, __p, __e, __l, 8); \
|
||||
break; \
|
||||
default: __e = __put_user_bad(); break; \
|
||||
} \
|
||||
diff --git a/arch/arm/lib/getuser.S b/arch/arm/lib/getuser.S
|
||||
index 11093a7..9b06bb4 100644
|
||||
--- a/arch/arm/lib/getuser.S
|
||||
+++ b/arch/arm/lib/getuser.S
|
||||
@@ -16,8 +16,9 @@
|
||||
* __get_user_X
|
||||
*
|
||||
* Inputs: r0 contains the address
|
||||
+ * r1 contains the address limit, which must be preserved
|
||||
* Outputs: r0 is the error code
|
||||
- * r2, r3 contains the zero-extended value
|
||||
+ * r2 contains the zero-extended value
|
||||
* lr corrupted
|
||||
*
|
||||
* No other registers must be altered. (see <asm/uaccess.h>
|
||||
@@ -27,33 +28,39 @@
|
||||
* Note also that it is intended that __get_user_bad is not global.
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
+#include <asm/assembler.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/domain.h>
|
||||
|
||||
ENTRY(__get_user_1)
|
||||
+ check_uaccess r0, 1, r1, r2, __get_user_bad
|
||||
1: TUSER(ldrb) r2, [r0]
|
||||
mov r0, #0
|
||||
mov pc, lr
|
||||
ENDPROC(__get_user_1)
|
||||
|
||||
ENTRY(__get_user_2)
|
||||
-#ifdef CONFIG_THUMB2_KERNEL
|
||||
-2: TUSER(ldrb) r2, [r0]
|
||||
-3: TUSER(ldrb) r3, [r0, #1]
|
||||
+ check_uaccess r0, 2, r1, r2, __get_user_bad
|
||||
+#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
+rb .req ip
|
||||
+2: ldrbt r2, [r0], #1
|
||||
+3: ldrbt rb, [r0], #0
|
||||
#else
|
||||
-2: TUSER(ldrb) r2, [r0], #1
|
||||
-3: TUSER(ldrb) r3, [r0]
|
||||
+rb .req r0
|
||||
+2: ldrb r2, [r0]
|
||||
+3: ldrb rb, [r0, #1]
|
||||
#endif
|
||||
#ifndef __ARMEB__
|
||||
- orr r2, r2, r3, lsl #8
|
||||
+ orr r2, r2, rb, lsl #8
|
||||
#else
|
||||
- orr r2, r3, r2, lsl #8
|
||||
+ orr r2, rb, r2, lsl #8
|
||||
#endif
|
||||
mov r0, #0
|
||||
mov pc, lr
|
||||
ENDPROC(__get_user_2)
|
||||
|
||||
ENTRY(__get_user_4)
|
||||
+ check_uaccess r0, 4, r1, r2, __get_user_bad
|
||||
4: TUSER(ldr) r2, [r0]
|
||||
mov r0, #0
|
||||
mov pc, lr
|
||||
diff --git a/arch/arm/lib/putuser.S b/arch/arm/lib/putuser.S
|
||||
index 7db2599..3d73dcb9 100644
|
||||
--- a/arch/arm/lib/putuser.S
|
||||
+++ b/arch/arm/lib/putuser.S
|
||||
@@ -16,6 +16,7 @@
|
||||
* __put_user_X
|
||||
*
|
||||
* Inputs: r0 contains the address
|
||||
+ * r1 contains the address limit, which must be preserved
|
||||
* r2, r3 contains the value
|
||||
* Outputs: r0 is the error code
|
||||
* lr corrupted
|
||||
@@ -27,16 +28,19 @@
|
||||
* Note also that it is intended that __put_user_bad is not global.
|
||||
*/
|
||||
#include <linux/linkage.h>
|
||||
+#include <asm/assembler.h>
|
||||
#include <asm/errno.h>
|
||||
#include <asm/domain.h>
|
||||
|
||||
ENTRY(__put_user_1)
|
||||
+ check_uaccess r0, 1, r1, ip, __put_user_bad
|
||||
1: TUSER(strb) r2, [r0]
|
||||
mov r0, #0
|
||||
mov pc, lr
|
||||
ENDPROC(__put_user_1)
|
||||
|
||||
ENTRY(__put_user_2)
|
||||
+ check_uaccess r0, 2, r1, ip, __put_user_bad
|
||||
mov ip, r2, lsr #8
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
#ifndef __ARMEB__
|
||||
@@ -60,12 +64,14 @@ ENTRY(__put_user_2)
|
||||
ENDPROC(__put_user_2)
|
||||
|
||||
ENTRY(__put_user_4)
|
||||
+ check_uaccess r0, 4, r1, ip, __put_user_bad
|
||||
4: TUSER(str) r2, [r0]
|
||||
mov r0, #0
|
||||
mov pc, lr
|
||||
ENDPROC(__put_user_4)
|
||||
|
||||
ENTRY(__put_user_8)
|
||||
+ check_uaccess r0, 8, r1, ip, __put_user_bad
|
||||
#ifdef CONFIG_THUMB2_KERNEL
|
||||
5: TUSER(str) r2, [r0]
|
||||
6: TUSER(str) r3, [r0, #4]
|
||||
--
|
||||
cgit v1.1
|
||||
|
320
Patches/Linux_CVEs/CVE-2013-7446/ANY/0001.patch
Normal file
320
Patches/Linux_CVEs/CVE-2013-7446/ANY/0001.patch
Normal file
@ -0,0 +1,320 @@
|
||||
From 7d267278a9ece963d77eefec61630223fce08c6c Mon Sep 17 00:00:00 2001
|
||||
From: Rainer Weikusat <rweikusat@mobileactivedefense.com>
|
||||
Date: Fri, 20 Nov 2015 22:07:23 +0000
|
||||
Subject: unix: avoid use-after-free in ep_remove_wait_queue
|
||||
|
||||
Rainer Weikusat <rweikusat@mobileactivedefense.com> writes:
|
||||
An AF_UNIX datagram socket being the client in an n:1 association with
|
||||
some server socket is only allowed to send messages to the server if the
|
||||
receive queue of this socket contains at most sk_max_ack_backlog
|
||||
datagrams. This implies that prospective writers might be forced to go
|
||||
to sleep despite none of the message presently enqueued on the server
|
||||
receive queue were sent by them. In order to ensure that these will be
|
||||
woken up once space becomes again available, the present unix_dgram_poll
|
||||
routine does a second sock_poll_wait call with the peer_wait wait queue
|
||||
of the server socket as queue argument (unix_dgram_recvmsg does a wake
|
||||
up on this queue after a datagram was received). This is inherently
|
||||
problematic because the server socket is only guaranteed to remain alive
|
||||
for as long as the client still holds a reference to it. In case the
|
||||
connection is dissolved via connect or by the dead peer detection logic
|
||||
in unix_dgram_sendmsg, the server socket may be freed despite "the
|
||||
polling mechanism" (in particular, epoll) still has a pointer to the
|
||||
corresponding peer_wait queue. There's no way to forcibly deregister a
|
||||
wait queue with epoll.
|
||||
|
||||
Based on an idea by Jason Baron, the patch below changes the code such
|
||||
that a wait_queue_t belonging to the client socket is enqueued on the
|
||||
peer_wait queue of the server whenever the peer receive queue full
|
||||
condition is detected by either a sendmsg or a poll. A wake up on the
|
||||
peer queue is then relayed to the ordinary wait queue of the client
|
||||
socket via wake function. The connection to the peer wait queue is again
|
||||
dissolved if either a wake up is about to be relayed or the client
|
||||
socket reconnects or a dead peer is detected or the client socket is
|
||||
itself closed. This enables removing the second sock_poll_wait from
|
||||
unix_dgram_poll, thus avoiding the use-after-free, while still ensuring
|
||||
that no blocked writer sleeps forever.
|
||||
|
||||
Signed-off-by: Rainer Weikusat <rweikusat@mobileactivedefense.com>
|
||||
Fixes: ec0d215f9420 ("af_unix: fix 'poll for write'/connected DGRAM sockets")
|
||||
Reviewed-by: Jason Baron <jbaron@akamai.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/unix/af_unix.c | 183 +++++++++++++++++++++++++++++++++++++++++++++++------
|
||||
1 file changed, 164 insertions(+), 19 deletions(-)
|
||||
|
||||
(limited to 'net/unix/af_unix.c')
|
||||
|
||||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
||||
index 955ec15..4e95bdf 100644
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -326,6 +326,118 @@ found:
|
||||
return s;
|
||||
}
|
||||
|
||||
+/* Support code for asymmetrically connected dgram sockets
|
||||
+ *
|
||||
+ * If a datagram socket is connected to a socket not itself connected
|
||||
+ * to the first socket (eg, /dev/log), clients may only enqueue more
|
||||
+ * messages if the present receive queue of the server socket is not
|
||||
+ * "too large". This means there's a second writeability condition
|
||||
+ * poll and sendmsg need to test. The dgram recv code will do a wake
|
||||
+ * up on the peer_wait wait queue of a socket upon reception of a
|
||||
+ * datagram which needs to be propagated to sleeping would-be writers
|
||||
+ * since these might not have sent anything so far. This can't be
|
||||
+ * accomplished via poll_wait because the lifetime of the server
|
||||
+ * socket might be less than that of its clients if these break their
|
||||
+ * association with it or if the server socket is closed while clients
|
||||
+ * are still connected to it and there's no way to inform "a polling
|
||||
+ * implementation" that it should let go of a certain wait queue
|
||||
+ *
|
||||
+ * In order to propagate a wake up, a wait_queue_t of the client
|
||||
+ * socket is enqueued on the peer_wait queue of the server socket
|
||||
+ * whose wake function does a wake_up on the ordinary client socket
|
||||
+ * wait queue. This connection is established whenever a write (or
|
||||
+ * poll for write) hit the flow control condition and broken when the
|
||||
+ * association to the server socket is dissolved or after a wake up
|
||||
+ * was relayed.
|
||||
+ */
|
||||
+
|
||||
+static int unix_dgram_peer_wake_relay(wait_queue_t *q, unsigned mode, int flags,
|
||||
+ void *key)
|
||||
+{
|
||||
+ struct unix_sock *u;
|
||||
+ wait_queue_head_t *u_sleep;
|
||||
+
|
||||
+ u = container_of(q, struct unix_sock, peer_wake);
|
||||
+
|
||||
+ __remove_wait_queue(&unix_sk(u->peer_wake.private)->peer_wait,
|
||||
+ q);
|
||||
+ u->peer_wake.private = NULL;
|
||||
+
|
||||
+ /* relaying can only happen while the wq still exists */
|
||||
+ u_sleep = sk_sleep(&u->sk);
|
||||
+ if (u_sleep)
|
||||
+ wake_up_interruptible_poll(u_sleep, key);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static int unix_dgram_peer_wake_connect(struct sock *sk, struct sock *other)
|
||||
+{
|
||||
+ struct unix_sock *u, *u_other;
|
||||
+ int rc;
|
||||
+
|
||||
+ u = unix_sk(sk);
|
||||
+ u_other = unix_sk(other);
|
||||
+ rc = 0;
|
||||
+ spin_lock(&u_other->peer_wait.lock);
|
||||
+
|
||||
+ if (!u->peer_wake.private) {
|
||||
+ u->peer_wake.private = other;
|
||||
+ __add_wait_queue(&u_other->peer_wait, &u->peer_wake);
|
||||
+
|
||||
+ rc = 1;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock(&u_other->peer_wait.lock);
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+static void unix_dgram_peer_wake_disconnect(struct sock *sk,
|
||||
+ struct sock *other)
|
||||
+{
|
||||
+ struct unix_sock *u, *u_other;
|
||||
+
|
||||
+ u = unix_sk(sk);
|
||||
+ u_other = unix_sk(other);
|
||||
+ spin_lock(&u_other->peer_wait.lock);
|
||||
+
|
||||
+ if (u->peer_wake.private == other) {
|
||||
+ __remove_wait_queue(&u_other->peer_wait, &u->peer_wake);
|
||||
+ u->peer_wake.private = NULL;
|
||||
+ }
|
||||
+
|
||||
+ spin_unlock(&u_other->peer_wait.lock);
|
||||
+}
|
||||
+
|
||||
+static void unix_dgram_peer_wake_disconnect_wakeup(struct sock *sk,
|
||||
+ struct sock *other)
|
||||
+{
|
||||
+ unix_dgram_peer_wake_disconnect(sk, other);
|
||||
+ wake_up_interruptible_poll(sk_sleep(sk),
|
||||
+ POLLOUT |
|
||||
+ POLLWRNORM |
|
||||
+ POLLWRBAND);
|
||||
+}
|
||||
+
|
||||
+/* preconditions:
|
||||
+ * - unix_peer(sk) == other
|
||||
+ * - association is stable
|
||||
+ */
|
||||
+static int unix_dgram_peer_wake_me(struct sock *sk, struct sock *other)
|
||||
+{
|
||||
+ int connected;
|
||||
+
|
||||
+ connected = unix_dgram_peer_wake_connect(sk, other);
|
||||
+
|
||||
+ if (unix_recvq_full(other))
|
||||
+ return 1;
|
||||
+
|
||||
+ if (connected)
|
||||
+ unix_dgram_peer_wake_disconnect(sk, other);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int unix_writable(const struct sock *sk)
|
||||
{
|
||||
return sk->sk_state != TCP_LISTEN &&
|
||||
@@ -431,6 +543,8 @@ static void unix_release_sock(struct sock *sk, int embrion)
|
||||
skpair->sk_state_change(skpair);
|
||||
sk_wake_async(skpair, SOCK_WAKE_WAITD, POLL_HUP);
|
||||
}
|
||||
+
|
||||
+ unix_dgram_peer_wake_disconnect(sk, skpair);
|
||||
sock_put(skpair); /* It may now die */
|
||||
unix_peer(sk) = NULL;
|
||||
}
|
||||
@@ -666,6 +780,7 @@ static struct sock *unix_create1(struct net *net, struct socket *sock, int kern)
|
||||
INIT_LIST_HEAD(&u->link);
|
||||
mutex_init(&u->readlock); /* single task reading lock */
|
||||
init_waitqueue_head(&u->peer_wait);
|
||||
+ init_waitqueue_func_entry(&u->peer_wake, unix_dgram_peer_wake_relay);
|
||||
unix_insert_socket(unix_sockets_unbound(sk), sk);
|
||||
out:
|
||||
if (sk == NULL)
|
||||
@@ -1033,6 +1148,8 @@ restart:
|
||||
if (unix_peer(sk)) {
|
||||
struct sock *old_peer = unix_peer(sk);
|
||||
unix_peer(sk) = other;
|
||||
+ unix_dgram_peer_wake_disconnect_wakeup(sk, old_peer);
|
||||
+
|
||||
unix_state_double_unlock(sk, other);
|
||||
|
||||
if (other != old_peer)
|
||||
@@ -1472,6 +1589,7 @@ static int unix_dgram_sendmsg(struct socket *sock, struct msghdr *msg,
|
||||
struct scm_cookie scm;
|
||||
int max_level;
|
||||
int data_len = 0;
|
||||
+ int sk_locked;
|
||||
|
||||
wait_for_unix_gc();
|
||||
err = scm_send(sock, msg, &scm, false);
|
||||
@@ -1550,12 +1668,14 @@ restart:
|
||||
goto out_free;
|
||||
}
|
||||
|
||||
+ sk_locked = 0;
|
||||
unix_state_lock(other);
|
||||
+restart_locked:
|
||||
err = -EPERM;
|
||||
if (!unix_may_send(sk, other))
|
||||
goto out_unlock;
|
||||
|
||||
- if (sock_flag(other, SOCK_DEAD)) {
|
||||
+ if (unlikely(sock_flag(other, SOCK_DEAD))) {
|
||||
/*
|
||||
* Check with 1003.1g - what should
|
||||
* datagram error
|
||||
@@ -1563,10 +1683,14 @@ restart:
|
||||
unix_state_unlock(other);
|
||||
sock_put(other);
|
||||
|
||||
+ if (!sk_locked)
|
||||
+ unix_state_lock(sk);
|
||||
+
|
||||
err = 0;
|
||||
- unix_state_lock(sk);
|
||||
if (unix_peer(sk) == other) {
|
||||
unix_peer(sk) = NULL;
|
||||
+ unix_dgram_peer_wake_disconnect_wakeup(sk, other);
|
||||
+
|
||||
unix_state_unlock(sk);
|
||||
|
||||
unix_dgram_disconnected(sk, other);
|
||||
@@ -1592,21 +1716,38 @@ restart:
|
||||
goto out_unlock;
|
||||
}
|
||||
|
||||
- if (unix_peer(other) != sk && unix_recvq_full(other)) {
|
||||
- if (!timeo) {
|
||||
- err = -EAGAIN;
|
||||
- goto out_unlock;
|
||||
+ if (unlikely(unix_peer(other) != sk && unix_recvq_full(other))) {
|
||||
+ if (timeo) {
|
||||
+ timeo = unix_wait_for_peer(other, timeo);
|
||||
+
|
||||
+ err = sock_intr_errno(timeo);
|
||||
+ if (signal_pending(current))
|
||||
+ goto out_free;
|
||||
+
|
||||
+ goto restart;
|
||||
}
|
||||
|
||||
- timeo = unix_wait_for_peer(other, timeo);
|
||||
+ if (!sk_locked) {
|
||||
+ unix_state_unlock(other);
|
||||
+ unix_state_double_lock(sk, other);
|
||||
+ }
|
||||
|
||||
- err = sock_intr_errno(timeo);
|
||||
- if (signal_pending(current))
|
||||
- goto out_free;
|
||||
+ if (unix_peer(sk) != other ||
|
||||
+ unix_dgram_peer_wake_me(sk, other)) {
|
||||
+ err = -EAGAIN;
|
||||
+ sk_locked = 1;
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
|
||||
- goto restart;
|
||||
+ if (!sk_locked) {
|
||||
+ sk_locked = 1;
|
||||
+ goto restart_locked;
|
||||
+ }
|
||||
}
|
||||
|
||||
+ if (unlikely(sk_locked))
|
||||
+ unix_state_unlock(sk);
|
||||
+
|
||||
if (sock_flag(other, SOCK_RCVTSTAMP))
|
||||
__net_timestamp(skb);
|
||||
maybe_add_creds(skb, sock, other);
|
||||
@@ -1620,6 +1761,8 @@ restart:
|
||||
return len;
|
||||
|
||||
out_unlock:
|
||||
+ if (sk_locked)
|
||||
+ unix_state_unlock(sk);
|
||||
unix_state_unlock(other);
|
||||
out_free:
|
||||
kfree_skb(skb);
|
||||
@@ -2476,14 +2619,16 @@ static unsigned int unix_dgram_poll(struct file *file, struct socket *sock,
|
||||
return mask;
|
||||
|
||||
writable = unix_writable(sk);
|
||||
- other = unix_peer_get(sk);
|
||||
- if (other) {
|
||||
- if (unix_peer(other) != sk) {
|
||||
- sock_poll_wait(file, &unix_sk(other)->peer_wait, wait);
|
||||
- if (unix_recvq_full(other))
|
||||
- writable = 0;
|
||||
- }
|
||||
- sock_put(other);
|
||||
+ if (writable) {
|
||||
+ unix_state_lock(sk);
|
||||
+
|
||||
+ other = unix_peer(sk);
|
||||
+ if (other && unix_peer(other) != sk &&
|
||||
+ unix_recvq_full(other) &&
|
||||
+ unix_dgram_peer_wake_me(sk, other))
|
||||
+ writable = 0;
|
||||
+
|
||||
+ unix_state_unlock(sk);
|
||||
}
|
||||
|
||||
if (writable)
|
||||
--
|
||||
cgit v1.1
|
||||
|
181
Patches/Linux_CVEs/CVE-2014-0972/ANY/0001.patch
Normal file
181
Patches/Linux_CVEs/CVE-2014-0972/ANY/0001.patch
Normal file
@ -0,0 +1,181 @@
|
||||
From 7613c9d520ee4d227e635f6db0270d4cf26102bc Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
Date: Mon, 21 Apr 2014 15:04:54 -0600
|
||||
Subject: msm: kgsl: Protect CP_STATE_DEBUG_INDEX
|
||||
|
||||
Put CP_STATE_DEBUG_INDEX and CP_STATE_DEBUG_DATA under protection
|
||||
to keep it from being written from an IB1. Doing so however opens
|
||||
up a subtle "feature" in the microcode: memory read opcodes turn off
|
||||
protected mode in the microcode to do the read and then turns it
|
||||
back on regardless of the initial state. This is a problem if the
|
||||
memory read happens while protected mode is turned off and then we
|
||||
try to access a protected register which then complains and goes boom.
|
||||
|
||||
To account for this irregularity explicitly turn back off protected
|
||||
mode in all the places where we know this will be a problem.
|
||||
|
||||
Change-Id: Ic0dedbad1397ca9b80132241ac006560a615e042
|
||||
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
---
|
||||
drivers/gpu/msm/adreno.c | 24 +++++++++++++-----------
|
||||
drivers/gpu/msm/adreno.h | 10 ++++++++++
|
||||
drivers/gpu/msm/adreno_a3xx.c | 1 +
|
||||
drivers/gpu/msm/kgsl_iommu.c | 16 ++++++++++++++++
|
||||
4 files changed, 40 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/gpu/msm/adreno.c b/drivers/gpu/msm/adreno.c
|
||||
index 4b21218..9bd07c6 100644
|
||||
--- a/drivers/gpu/msm/adreno.c
|
||||
+++ b/drivers/gpu/msm/adreno.c
|
||||
@@ -1150,9 +1150,7 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
||||
uint32_t flags)
|
||||
{
|
||||
phys_addr_t pt_val;
|
||||
- unsigned int link[230];
|
||||
- unsigned int *cmds = &link[0];
|
||||
- int sizedwords = 0;
|
||||
+ unsigned int *link = NULL, *cmds;
|
||||
struct adreno_device *adreno_dev = ADRENO_DEVICE(device);
|
||||
int num_iommu_units;
|
||||
struct kgsl_context *context;
|
||||
@@ -1170,6 +1168,14 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
||||
if (context)
|
||||
adreno_ctx = ADRENO_CONTEXT(context);
|
||||
|
||||
+ link = kmalloc(PAGE_SIZE, GFP_KERNEL);
|
||||
+ if (link == NULL) {
|
||||
+ result = -ENOMEM;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
+ cmds = link;
|
||||
+
|
||||
result = kgsl_mmu_enable_clk(&device->mmu, KGSL_IOMMU_CONTEXT_USER);
|
||||
|
||||
if (result)
|
||||
@@ -1192,17 +1198,11 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
||||
cmds += _adreno_iommu_setstate_v1(device, cmds, pt_val,
|
||||
num_iommu_units, flags);
|
||||
|
||||
- sizedwords += (cmds - &link[0]);
|
||||
- if (sizedwords == 0) {
|
||||
- KGSL_DRV_ERR(device, "no commands generated\n");
|
||||
- BUG();
|
||||
- }
|
||||
/* invalidate all base pointers */
|
||||
*cmds++ = cp_type3_packet(CP_INVALIDATE_STATE, 1);
|
||||
*cmds++ = 0x7fff;
|
||||
- sizedwords += 2;
|
||||
|
||||
- if (sizedwords > (ARRAY_SIZE(link))) {
|
||||
+ if ((unsigned int) (cmds - link) > (PAGE_SIZE / sizeof(unsigned int))) {
|
||||
KGSL_DRV_ERR(device, "Temp command buffer overflow\n");
|
||||
BUG();
|
||||
}
|
||||
@@ -1211,7 +1211,8 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
||||
* use the global timestamp for iommu clock disablement
|
||||
*/
|
||||
result = adreno_ringbuffer_issuecmds(device, adreno_ctx,
|
||||
- KGSL_CMD_FLAGS_PMODE, &link[0], sizedwords);
|
||||
+ KGSL_CMD_FLAGS_PMODE, link,
|
||||
+ (unsigned int)(cmds - link));
|
||||
|
||||
/*
|
||||
* On error disable the IOMMU clock right away otherwise turn it off
|
||||
@@ -1225,6 +1226,7 @@ static int adreno_iommu_setstate(struct kgsl_device *device,
|
||||
KGSL_IOMMU_CONTEXT_USER);
|
||||
|
||||
done:
|
||||
+ kfree(link);
|
||||
kgsl_context_put(context);
|
||||
return result;
|
||||
}
|
||||
diff --git a/drivers/gpu/msm/adreno.h b/drivers/gpu/msm/adreno.h
|
||||
index 8e162ca..0b793fa 100644
|
||||
--- a/drivers/gpu/msm/adreno.h
|
||||
+++ b/drivers/gpu/msm/adreno.h
|
||||
@@ -805,6 +805,11 @@ static inline int adreno_add_read_cmds(struct kgsl_device *device,
|
||||
*cmds++ = val;
|
||||
*cmds++ = 0xFFFFFFFF;
|
||||
*cmds++ = 0xFFFFFFFF;
|
||||
+
|
||||
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
cmds += __adreno_add_idle_indirect_cmds(cmds, nop_gpuaddr);
|
||||
return cmds - start;
|
||||
}
|
||||
@@ -850,6 +855,11 @@ static inline int adreno_wait_reg_mem(unsigned int *cmds, unsigned int addr,
|
||||
*cmds++ = val; /* ref val */
|
||||
*cmds++ = mask;
|
||||
*cmds++ = interval;
|
||||
+
|
||||
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
return cmds - start;
|
||||
}
|
||||
/*
|
||||
diff --git a/drivers/gpu/msm/adreno_a3xx.c b/drivers/gpu/msm/adreno_a3xx.c
|
||||
index 70ba50e..873a5c9 100644
|
||||
--- a/drivers/gpu/msm/adreno_a3xx.c
|
||||
+++ b/drivers/gpu/msm/adreno_a3xx.c
|
||||
@@ -2038,6 +2038,7 @@ static void a3xx_protect_init(struct kgsl_device *device)
|
||||
|
||||
/* CP registers */
|
||||
adreno_set_protected_registers(device, &index, 0x1C0, 5);
|
||||
+ adreno_set_protected_registers(device, &index, 0x1EC, 1);
|
||||
adreno_set_protected_registers(device, &index, 0x1F6, 1);
|
||||
adreno_set_protected_registers(device, &index, 0x1F8, 2);
|
||||
adreno_set_protected_registers(device, &index, 0x45E, 2);
|
||||
diff --git a/drivers/gpu/msm/kgsl_iommu.c b/drivers/gpu/msm/kgsl_iommu.c
|
||||
index dba23b0..68b3420 100644
|
||||
--- a/drivers/gpu/msm/kgsl_iommu.c
|
||||
+++ b/drivers/gpu/msm/kgsl_iommu.c
|
||||
@@ -1036,6 +1036,10 @@ static unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu,
|
||||
*cmds++ = 0x1;
|
||||
*cmds++ = 0x1;
|
||||
|
||||
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
*cmds++ = cp_type3_packet(CP_MEM_WRITE, 2);
|
||||
*cmds++ = lock_vars->turn;
|
||||
*cmds++ = 0;
|
||||
@@ -1050,11 +1054,19 @@ static unsigned int kgsl_iommu_sync_lock(struct kgsl_mmu *mmu,
|
||||
*cmds++ = 0x1;
|
||||
*cmds++ = 0x1;
|
||||
|
||||
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
*cmds++ = cp_type3_packet(CP_TEST_TWO_MEMS, 3);
|
||||
*cmds++ = lock_vars->flag[PROC_APPS];
|
||||
*cmds++ = lock_vars->turn;
|
||||
*cmds++ = 0;
|
||||
|
||||
+ /* TEST_TWO_MEMS turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
cmds += adreno_add_idle_cmds(adreno_dev, cmds);
|
||||
|
||||
return cmds - start;
|
||||
@@ -1092,6 +1104,10 @@ static unsigned int kgsl_iommu_sync_unlock(struct kgsl_mmu *mmu,
|
||||
*cmds++ = 0x1;
|
||||
*cmds++ = 0x1;
|
||||
|
||||
+ /* WAIT_REG_MEM turns back on protected mode - push it off */
|
||||
+ *cmds++ = cp_type3_packet(CP_SET_PROTECTED_MODE, 1);
|
||||
+ *cmds++ = 0;
|
||||
+
|
||||
cmds += adreno_add_idle_cmds(adreno_dev, cmds);
|
||||
|
||||
return cmds - start;
|
||||
--
|
||||
cgit v1.1
|
||||
|
31
Patches/Linux_CVEs/CVE-2014-0972/ANY/0002.patch
Normal file
31
Patches/Linux_CVEs/CVE-2014-0972/ANY/0002.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From d7d07936a166e7421a6308eec443b707a9678580 Mon Sep 17 00:00:00 2001
|
||||
From: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
Date: Thu, 17 Apr 2014 10:05:21 -0600
|
||||
Subject: msm: kgsl: Mark the IOMMU setstate memory as read only
|
||||
|
||||
Mark the IOMMU setstate memory as read only in the pagetable.
|
||||
|
||||
Change-Id: Ic0dedbadb19e499c749cd744c3e89be3bcb4c2a2
|
||||
Signed-off-by: Jordan Crouse <jcrouse@codeaurora.org>
|
||||
---
|
||||
drivers/gpu/msm/kgsl_mmu.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/gpu/msm/kgsl_mmu.c b/drivers/gpu/msm/kgsl_mmu.c
|
||||
index 95aac09..eb6d76f 100644
|
||||
--- a/drivers/gpu/msm/kgsl_mmu.c
|
||||
+++ b/drivers/gpu/msm/kgsl_mmu.c
|
||||
@@ -377,6 +377,10 @@ int kgsl_mmu_init(struct kgsl_device *device)
|
||||
PAGE_SIZE);
|
||||
if (status)
|
||||
return status;
|
||||
+
|
||||
+ /* Mark the setstate memory as read only */
|
||||
+ mmu->setstate_memory.flags |= KGSL_MEMFLAGS_GPUREADONLY;
|
||||
+
|
||||
kgsl_sharedmem_set(device, &mmu->setstate_memory, 0, 0,
|
||||
mmu->setstate_memory.size);
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
35
Patches/Linux_CVEs/CVE-2014-0975/ANY/0001.patch
Normal file
35
Patches/Linux_CVEs/CVE-2014-0975/ANY/0001.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From 832666bda9606623c3cff5b14873553f82ec1281 Mon Sep 17 00:00:00 2001
|
||||
From: Suman Mukherjee <sumam@codeaurora.org>
|
||||
Date: Tue, 9 Dec 2014 13:25:36 +0530
|
||||
Subject: msm: camera: add check for csid_cid to prevent of overwrite memory
|
||||
|
||||
add sanity check for csid cid to ensute that we never read or write
|
||||
outside csid_dev->mem buffer
|
||||
|
||||
Change-Id: Ic8f0d689fa176720ae3a3316f2ad27556ae7bde5
|
||||
Signed-off-by: Suman Mukherjee <sumam@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
index 3596a12..53a5ed3 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
@@ -50,6 +50,13 @@ static int msm_csid_cid_lut(
|
||||
return -EINVAL;
|
||||
}
|
||||
for (i = 0; i < csid_lut_params->num_cid && i < 16; i++) {
|
||||
+ if (csid_lut_params->vc_cfg[i]->cid >=
|
||||
+ csid_lut_params->num_cid ||
|
||||
+ csid_lut_params->vc_cfg[i]->cid < 0) {
|
||||
+ pr_err("%s: cid outside range %d\n",
|
||||
+ __func__, csid_lut_params->vc_cfg[i]->cid);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
CDBG("%s lut params num_cid = %d, cid = %d, dt = %x, df = %d\n",
|
||||
__func__,
|
||||
csid_lut_params->num_cid,
|
||||
--
|
||||
cgit v1.1
|
||||
|
31
Patches/Linux_CVEs/CVE-2014-0976/ANY/0001.patch
Normal file
31
Patches/Linux_CVEs/CVE-2014-0976/ANY/0001.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From ee37138b8ceee6035c93756043eaac7eaa1c0948 Mon Sep 17 00:00:00 2001
|
||||
From: Suman Mukherjee <sumam@codeaurora.org>
|
||||
Date: Wed, 17 Dec 2014 10:00:49 +0530
|
||||
Subject: msm: camera: ispif: Validate vfe_intf parameter
|
||||
|
||||
Validate vfe_intf parameter to avoid invalid register access.
|
||||
|
||||
Change-Id: Ie0b57071cc5fca1c48d3a5e2e7819f9af9ff544c
|
||||
Signed-off-by: Suman Mukherjee <sumam@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
|
||||
index 8f99ff6..d044c1d 100755
|
||||
--- a/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/ispif/msm_ispif.c
|
||||
@@ -60,8 +60,8 @@ static void msm_ispif_io_dump_reg(struct ispif_device *ispif)
|
||||
static inline int msm_ispif_is_intf_valid(uint32_t csid_version,
|
||||
uint8_t intf_type)
|
||||
{
|
||||
- return (csid_version <= CSID_VERSION_V22 && intf_type != VFE0) ?
|
||||
- false : true;
|
||||
+ return ((csid_version <= CSID_VERSION_V22 && intf_type != VFE0) ||
|
||||
+ (intf_type >= VFE_MAX)) ? false : true;
|
||||
}
|
||||
|
||||
static struct msm_cam_clk_info ispif_8626_reset_clk_info[] = {
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,92 +0,0 @@
|
||||
From d41eb74e53d94aba656ffda647d106808e636cd6 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Krause <minipli@googlemail.com>
|
||||
Date: Sun, 13 Apr 2014 18:23:33 +0200
|
||||
Subject: filter: prevent nla extensions to peek beyond the end of the message
|
||||
|
||||
[ Upstream commit 05ab8f2647e4221cbdb3856dd7d32bd5407316b3 ]
|
||||
|
||||
The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check
|
||||
for a minimal message length before testing the supplied offset to be
|
||||
within the bounds of the message. This allows the subtraction of the nla
|
||||
header to underflow and therefore -- as the data type is unsigned --
|
||||
allowing far to big offset and length values for the search of the
|
||||
netlink attribute.
|
||||
|
||||
The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is
|
||||
also wrong. It has the minuend and subtrahend mixed up, therefore
|
||||
calculates a huge length value, allowing to overrun the end of the
|
||||
message while looking for the netlink attribute.
|
||||
|
||||
The following three BPF snippets will trigger the bugs when attached to
|
||||
a UNIX datagram socket and parsing a message with length 1, 2 or 3.
|
||||
|
||||
,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nla
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ; (needs a fake netlink header at offset 0)
|
||||
| ld #0
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
Fix the first issue by ensuring the message length fulfills the minimal
|
||||
size constrains of a nla header. Fix the second bug by getting the math
|
||||
for the remainder calculation right.
|
||||
|
||||
Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction")
|
||||
Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..")
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Mathias Krause <minipli@googlemail.com>
|
||||
Acked-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
[bwh: Fix misplacement of the first check due to a bug in the patch program]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/core/filter.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/core/filter.c b/net/core/filter.c
|
||||
index 5dea452..9c88080 100644
|
||||
--- a/net/core/filter.c
|
||||
+++ b/net/core/filter.c
|
||||
@@ -320,6 +320,8 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
@@ -336,11 +338,13 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
nla = (struct nlattr *)&skb->data[A];
|
||||
- if (nla->nla_len > A - skb->len)
|
||||
+ if (nla->nla_len > skb->len - A)
|
||||
return 0;
|
||||
|
||||
nla = nla_find_nested(nla, X);
|
||||
--
|
||||
cgit v1.1
|
||||
|
66
Patches/Linux_CVEs/CVE-2014-4321/ANY/0001.patch
Normal file
66
Patches/Linux_CVEs/CVE-2014-4321/ANY/0001.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 68c459daa22a26d6ca8f169baef6605ca8a285f2 Mon Sep 17 00:00:00 2001
|
||||
From: Alok Kediya <kediya@codeaurora.org>
|
||||
Date: Tue, 9 Dec 2014 12:53:29 +0530
|
||||
Subject: msm: camera: isp: Validate reg_offset and len parameters
|
||||
|
||||
Validate reg_offset and len parameters before consuming to
|
||||
avoid invalid register access.
|
||||
|
||||
Change-Id: I07676a6d10a9945fb0b99ebfd147075f896fbfab
|
||||
Signed-off-by: Alok Kediya <kediya@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/isp/msm_isp_util.c | 36 +++++++++++++++++++---
|
||||
1 file changed, 31 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
index 12fd081..620c01a 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
@@ -495,13 +495,39 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t *cfg_data, uint32_t cmd_len)
|
||||
{
|
||||
switch (reg_cfg_cmd->cmd_type) {
|
||||
- case VFE_WRITE: {
|
||||
- if (resource_size(vfe_dev->vfe_mem) <
|
||||
- (reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
- reg_cfg_cmd->u.rw_info.len)) {
|
||||
- pr_err("%s: VFE_WRITE: Invalid length\n", __func__);
|
||||
+ case VFE_WRITE:
|
||||
+ case VFE_READ: {
|
||||
+ if ((reg_cfg_cmd->u.rw_info.reg_offset >
|
||||
+ (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
|
||||
+ ((reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
+ reg_cfg_cmd->u.rw_info.len) >
|
||||
+ resource_size(vfe_dev->vfe_mem))) {
|
||||
+ pr_err("%s:%d reg_offset %d len %d res %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.rw_info.reg_offset,
|
||||
+ reg_cfg_cmd->u.rw_info.len,
|
||||
+ (uint32_t)resource_size(vfe_dev->vfe_mem));
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ if ((reg_cfg_cmd->u.rw_info.cmd_data_offset >
|
||||
+ (UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
|
||||
+ ((reg_cfg_cmd->u.rw_info.cmd_data_offset +
|
||||
+ reg_cfg_cmd->u.rw_info.len) > cmd_len)) {
|
||||
+ pr_err("%s:%d cmd_data_offset %d len %d cmd_len %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.rw_info.cmd_data_offset,
|
||||
+ reg_cfg_cmd->u.rw_info.len, cmd_len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+ default:
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ switch (reg_cfg_cmd->cmd_type) {
|
||||
+ case VFE_WRITE: {
|
||||
msm_camera_io_memcpy(vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.rw_info.reg_offset,
|
||||
cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
|
||||
--
|
||||
cgit v1.1
|
||||
|
94
Patches/Linux_CVEs/CVE-2014-4322/ANY/0001.patch
Normal file
94
Patches/Linux_CVEs/CVE-2014-4322/ANY/0001.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From b9470692c228608ef0ec60747ac2732ad7ffedf0 Mon Sep 17 00:00:00 2001
|
||||
From: Mona Hossain <mhossain@codeaurora.org>
|
||||
Date: Thu, 9 Oct 2014 12:00:03 -0700
|
||||
Subject: qseecom: Add boundary checks for offset within message.
|
||||
|
||||
Qseecom driver does not have boundary checks for offset within the
|
||||
message. So this patch add checks to validate the offsets sent by
|
||||
client to modify data within the command request message and it
|
||||
should not exceed the memory allocated for that message.
|
||||
|
||||
Change-Id: I29bfbdc154eebb4f3f4bfbb31789562e37fa5886
|
||||
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
|
||||
Signed-off-by: Mallikarjuna Reddy Amireddy <mamire@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 49 insertions(+)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 3a93469..b091acd 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -1525,6 +1525,30 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int boundary_checks_offset(struct qseecom_send_modfd_cmd_req *cmd_req,
|
||||
+ struct qseecom_send_modfd_listener_resp *lstnr_resp,
|
||||
+ struct qseecom_dev_handle *data, bool listener_svc,
|
||||
+ int i) {
|
||||
+ int ret = 0;
|
||||
+
|
||||
+ if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
|
||||
+ if (cmd_req->ifd_data[i].cmd_buf_offset >
|
||||
+ cmd_req->cmd_req_len - sizeof(uint32_t)) {
|
||||
+ pr_err("Invalid offset 0x%x\n",
|
||||
+ cmd_req->ifd_data[i].cmd_buf_offset);
|
||||
+ return ++ret;
|
||||
+ }
|
||||
+ } else if ((listener_svc) && (lstnr_resp->ifd_data[i].fd > 0)) {
|
||||
+ if (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
+ lstnr_resp->resp_len - sizeof(uint32_t)) {
|
||||
+ pr_err("Invalid offset 0x%x\n",
|
||||
+ lstnr_resp->ifd_data[i].cmd_buf_offset);
|
||||
+ return ++ret;
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
struct qseecom_dev_handle *data,
|
||||
bool listener_svc)
|
||||
@@ -1598,6 +1622,10 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
if (sg_ptr->nents == 1) {
|
||||
uint32_t *update;
|
||||
update = (uint32_t *) field;
|
||||
+
|
||||
+ if (boundary_checks_offset(cmd_req, lstnr_resp, data,
|
||||
+ listener_svc, i))
|
||||
+ goto err;
|
||||
if (cleanup)
|
||||
*update = 0;
|
||||
else
|
||||
@@ -1607,6 +1635,27 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
} else {
|
||||
struct qseecom_sg_entry *update;
|
||||
int j = 0;
|
||||
+
|
||||
+ if ((!listener_svc) && (cmd_req->ifd_data[i].fd > 0)) {
|
||||
+ if (cmd_req->ifd_data[i].cmd_buf_offset >
|
||||
+ cmd_req->cmd_req_len -
|
||||
+ sizeof(struct qseecom_sg_entry)) {
|
||||
+ pr_err("Invalid offset = 0x%x\n",
|
||||
+ cmd_req->ifd_data[i].
|
||||
+ cmd_buf_offset);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ } else if ((listener_svc) &&
|
||||
+ (lstnr_resp->ifd_data[i].fd > 0)) {
|
||||
+ if (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
+ lstnr_resp->resp_len -
|
||||
+ sizeof(struct qseecom_sg_entry)) {
|
||||
+ pr_err("Invalid offset = 0x%x\n",
|
||||
+ lstnr_resp->ifd_data[i].
|
||||
+ cmd_buf_offset);
|
||||
+ goto err;
|
||||
+ }
|
||||
+ }
|
||||
update = (struct qseecom_sg_entry *) field;
|
||||
for (j = 0; j < sg_ptr->nents; j++) {
|
||||
if (cleanup) {
|
||||
--
|
||||
cgit v1.1
|
||||
|
383
Patches/Linux_CVEs/CVE-2014-4322/ANY/0002.patch
Normal file
383
Patches/Linux_CVEs/CVE-2014-4322/ANY/0002.patch
Normal file
@ -0,0 +1,383 @@
|
||||
From e909d95e6bded328e388d5b8d123297bbbb70728 Mon Sep 17 00:00:00 2001
|
||||
From: Mona Hossain <mhossain@codeaurora.org>
|
||||
Date: Mon, 3 Nov 2014 17:05:48 -0800
|
||||
Subject: qseecom: Add checks for send_cmd inputs
|
||||
|
||||
Improve user input validation across send cmd APIs. Add new
|
||||
API __validate_send_cmd_inputs() to validate all user provided
|
||||
inputs.
|
||||
|
||||
Change-Id: Ibbb0c0e7e5483f653bd59b927562b63c1e43c365
|
||||
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 221 ++++++++++++++++++++++++++++++-------------------
|
||||
1 file changed, 134 insertions(+), 87 deletions(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 65001c5..244f1bf 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -981,7 +981,7 @@ static int qseecom_scale_bus_bandwidth(struct qseecom_dev_handle *data,
|
||||
}
|
||||
if (req_mode > HIGH) {
|
||||
pr_err("Invalid bandwidth mode (%d)\n", req_mode);
|
||||
- return ret;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1834,24 +1834,16 @@ exit:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
+static int __validate_send_cmd_inputs(struct qseecom_dev_handle *data,
|
||||
struct qseecom_send_cmd_req *req)
|
||||
-{
|
||||
- int ret = 0;
|
||||
- u32 reqd_len_sb_in = 0;
|
||||
- struct qseecom_client_send_data_ireq send_data_req;
|
||||
- struct qseecom_command_scm_resp resp;
|
||||
- unsigned long flags;
|
||||
- struct qseecom_registered_app_list *ptr_app;
|
||||
- bool found_app = false;
|
||||
- int name_len = 0;
|
||||
|
||||
+{
|
||||
if (!data || !data->client.ihandle) {
|
||||
pr_err("Client or client handle is not initialized\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
-
|
||||
- if (req->cmd_req_buf == NULL || req->resp_buf == NULL) {
|
||||
+ if (((req->resp_buf == NULL) && (req->resp_len != 0)) ||
|
||||
+ (req->cmd_req_buf == NULL)) {
|
||||
pr_err("cmd buffer or response buffer is null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -1862,8 +1854,6 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
pr_err("cmd buffer address not within shared bufffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
-
|
||||
-
|
||||
if (((uintptr_t)req->resp_buf <
|
||||
data->client.user_virt_sb_base) ||
|
||||
((uintptr_t)req->resp_buf >=
|
||||
@@ -1871,27 +1861,62 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
pr_err("response buffer address not within shared bufffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
-
|
||||
- if ((req->cmd_req_len == 0) || (req->resp_len == 0) ||
|
||||
- req->cmd_req_len > data->client.sb_length ||
|
||||
- req->resp_len > data->client.sb_length) {
|
||||
- pr_err("cmd buffer length or response buffer length not valid\n");
|
||||
+ if ((req->cmd_req_len == 0) ||
|
||||
+ (req->cmd_req_len > data->client.sb_length) ||
|
||||
+ (req->resp_len > data->client.sb_length)) {
|
||||
+ pr_err("cmd buf length or response buf length not valid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
-
|
||||
if (req->cmd_req_len > UINT_MAX - req->resp_len) {
|
||||
- pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n");
|
||||
+ pr_err("Integer overflow detected in req_len & rsp_len\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- reqd_len_sb_in = req->cmd_req_len + req->resp_len;
|
||||
- if (reqd_len_sb_in > data->client.sb_length) {
|
||||
+ if ((req->cmd_req_len + req->resp_len) > data->client.sb_length) {
|
||||
pr_debug("Not enough memory to fit cmd_buf.\n");
|
||||
pr_debug("resp_buf. Required: %u, Available: %zu\n",
|
||||
- reqd_len_sb_in, data->client.sb_length);
|
||||
+ (req->cmd_req_len + req->resp_len),
|
||||
+ data->client.sb_length);
|
||||
return -ENOMEM;
|
||||
}
|
||||
+ if ((uintptr_t)req->cmd_req_buf > (ULONG_MAX - req->cmd_req_len)) {
|
||||
+ pr_err("Integer overflow in req_len & cmd_req_buf\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if ((uintptr_t)req->resp_buf > (ULONG_MAX - req->resp_len)) {
|
||||
+ pr_err("Integer overflow in resp_len & resp_buf\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (data->client.user_virt_sb_base >
|
||||
+ (ULONG_MAX - data->client.sb_length)) {
|
||||
+ pr_err("Integer overflow in user_virt_sb_base & sb_length\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if ((((uintptr_t)req->cmd_req_buf + req->cmd_req_len) >
|
||||
+ ((uintptr_t)data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length)) ||
|
||||
+ (((uintptr_t)req->resp_buf + req->resp_len) >
|
||||
+ ((uintptr_t)data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))) {
|
||||
+ pr_err("cmd buf or resp buf is out of shared buffer region\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
|
||||
+static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
+ struct qseecom_send_cmd_req *req)
|
||||
+{
|
||||
+ int ret = 0;
|
||||
+ u32 reqd_len_sb_in = 0;
|
||||
+ struct qseecom_client_send_data_ireq send_data_req;
|
||||
+ struct qseecom_command_scm_resp resp;
|
||||
+ unsigned long flags;
|
||||
+ struct qseecom_registered_app_list *ptr_app;
|
||||
+ bool found_app = false;
|
||||
+ int name_len = 0;
|
||||
+
|
||||
+ reqd_len_sb_in = req->cmd_req_len + req->resp_len;
|
||||
/* find app_id & img_name from list */
|
||||
spin_lock_irqsave(&qseecom.registered_app_list_lock, flags);
|
||||
list_for_each_entry(ptr_app, &qseecom.registered_app_list_head,
|
||||
@@ -1965,6 +1990,10 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
|
||||
pr_err("copy_from_user failed\n");
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+ if (__validate_send_cmd_inputs(data, &req))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
ret = __qseecom_send_cmd(data, &req);
|
||||
|
||||
if (ret)
|
||||
@@ -1973,50 +2002,54 @@ static int qseecom_send_cmd(struct qseecom_dev_handle *data, void __user *argp)
|
||||
return ret;
|
||||
}
|
||||
|
||||
-int boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req,
|
||||
+int __boundary_checks_offset(struct qseecom_send_modfd_cmd_req *req,
|
||||
struct qseecom_send_modfd_listener_resp *lstnr_resp,
|
||||
struct qseecom_dev_handle *data, bool qteec,
|
||||
int i) {
|
||||
- int ret = 0;
|
||||
|
||||
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
|
||||
(req->ifd_data[i].fd > 0)) {
|
||||
if (qteec) {
|
||||
- if (req->ifd_data[i].cmd_buf_offset >
|
||||
- req->cmd_req_len - TWO * sizeof(uint32_t)) {
|
||||
- pr_err("Invalid offset 0x%x\n",
|
||||
+ if ((req->cmd_req_len < (TWO * sizeof(uint32_t))) ||
|
||||
+ (req->ifd_data[i].cmd_buf_offset >
|
||||
+ req->cmd_req_len - (TWO * sizeof(uint32_t)))) {
|
||||
+ pr_err("Invalid offset (QTEEC req len) 0x%x\n",
|
||||
req->ifd_data[i].cmd_buf_offset);
|
||||
- return ++ret;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
- if (req->ifd_data[i].cmd_buf_offset >
|
||||
- req->cmd_req_len - sizeof(uint32_t)) {
|
||||
- pr_err("Invalid offset 0x%x\n",
|
||||
+ if ((req->cmd_req_len < sizeof(uint32_t)) ||
|
||||
+ (req->ifd_data[i].cmd_buf_offset >
|
||||
+ req->cmd_req_len - sizeof(uint32_t))) {
|
||||
+ pr_err("Invalid offset (req len) 0x%x\n",
|
||||
req->ifd_data[i].cmd_buf_offset);
|
||||
- return ++ret;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
}
|
||||
} else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
|
||||
(lstnr_resp->ifd_data[i].fd > 0)) {
|
||||
if (qteec) {
|
||||
- if (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
- lstnr_resp->resp_len - TWO * sizeof(uint32_t)) {
|
||||
- pr_err("Invalid offset 0x%x\n",
|
||||
+ if ((lstnr_resp->resp_len < TWO * sizeof(uint32_t)) ||
|
||||
+ (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
+ lstnr_resp->resp_len - TWO*sizeof(uint32_t))) {
|
||||
+ pr_err("Invalid offset (QTEEC resp len) 0x%x\n",
|
||||
lstnr_resp->ifd_data[i].cmd_buf_offset);
|
||||
- return ++ret;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
- if (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
- lstnr_resp->resp_len - sizeof(uint32_t)) {
|
||||
- pr_err("Invalid offset 0x%x\n",
|
||||
+ if ((lstnr_resp->resp_len < sizeof(uint32_t)) ||
|
||||
+ (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
+ lstnr_resp->resp_len - sizeof(uint32_t))) {
|
||||
+ pr_err("Invalid offset (lstnr resp len) 0x%x\n",
|
||||
lstnr_resp->ifd_data[i].cmd_buf_offset);
|
||||
- return ++ret;
|
||||
+ return -EINVAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
- return ret;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
+#define SG_ENTRY_SZ sizeof(struct qseecom_sg_entry)
|
||||
static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
struct qseecom_dev_handle *data, bool qteec)
|
||||
{
|
||||
@@ -2095,7 +2128,7 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
uint32_t *update;
|
||||
update = (uint32_t *) field;
|
||||
|
||||
- if (boundary_checks_offset(req, lstnr_resp, data,
|
||||
+ if (__boundary_checks_offset(req, lstnr_resp, data,
|
||||
qteec, i))
|
||||
goto err;
|
||||
if (cleanup)
|
||||
@@ -2112,22 +2145,25 @@ static int __qseecom_update_cmd_buf(void *msg, bool cleanup,
|
||||
|
||||
if ((data->type != QSEECOM_LISTENER_SERVICE) &&
|
||||
(req->ifd_data[i].fd > 0)) {
|
||||
- if (req->ifd_data[i].cmd_buf_offset >
|
||||
- req->cmd_req_len -
|
||||
- sizeof(struct qseecom_sg_entry)) {
|
||||
+
|
||||
+ if ((req->cmd_req_len <
|
||||
+ SG_ENTRY_SZ * sg_ptr->nents) ||
|
||||
+ (req->ifd_data[i].cmd_buf_offset >
|
||||
+ (req->cmd_req_len -
|
||||
+ SG_ENTRY_SZ * sg_ptr->nents))) {
|
||||
pr_err("Invalid offset = 0x%x\n",
|
||||
- req->ifd_data[i].
|
||||
- cmd_buf_offset);
|
||||
+ req->ifd_data[i].cmd_buf_offset);
|
||||
goto err;
|
||||
}
|
||||
+
|
||||
} else if ((data->type == QSEECOM_LISTENER_SERVICE) &&
|
||||
(lstnr_resp->ifd_data[i].fd > 0)) {
|
||||
- if (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
- lstnr_resp->resp_len -
|
||||
- sizeof(struct qseecom_sg_entry)) {
|
||||
- pr_err("Invalid offset = 0x%x\n",
|
||||
- lstnr_resp->ifd_data[i].
|
||||
- cmd_buf_offset);
|
||||
+
|
||||
+ if ((lstnr_resp->resp_len <
|
||||
+ SG_ENTRY_SZ * sg_ptr->nents) ||
|
||||
+ (lstnr_resp->ifd_data[i].cmd_buf_offset >
|
||||
+ (lstnr_resp->resp_len -
|
||||
+ SG_ENTRY_SZ * sg_ptr->nents))) {
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
@@ -2179,37 +2215,14 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
return ret;
|
||||
}
|
||||
|
||||
- if (req.cmd_req_buf == NULL || req.resp_buf == NULL) {
|
||||
- pr_err("cmd buffer or response buffer is null\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- if (((uintptr_t)req.cmd_req_buf <
|
||||
- data->client.user_virt_sb_base) ||
|
||||
- ((uintptr_t)req.cmd_req_buf >=
|
||||
- (data->client.user_virt_sb_base + data->client.sb_length))) {
|
||||
- pr_err("cmd buffer address not within shared bufffer\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (((uintptr_t)req.resp_buf <
|
||||
- data->client.user_virt_sb_base) ||
|
||||
- ((uintptr_t)req.resp_buf >=
|
||||
- (data->client.user_virt_sb_base + data->client.sb_length))) {
|
||||
- pr_err("response buffer address not within shared bufffer\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
- if (req.cmd_req_len == 0 || req.cmd_req_len > data->client.sb_length ||
|
||||
- req.resp_len > data->client.sb_length) {
|
||||
- pr_err("cmd or response buffer length not valid\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
-
|
||||
send_cmd_req.cmd_req_buf = req.cmd_req_buf;
|
||||
send_cmd_req.cmd_req_len = req.cmd_req_len;
|
||||
send_cmd_req.resp_buf = req.resp_buf;
|
||||
send_cmd_req.resp_len = req.resp_len;
|
||||
|
||||
+ if (__validate_send_cmd_inputs(data, &send_cmd_req))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
/* validate offsets */
|
||||
for (i = 0; i < MAX_ION_FD; i++) {
|
||||
if (req.ifd_data[i].cmd_buf_offset >= req.cmd_req_len) {
|
||||
@@ -2897,6 +2910,9 @@ int qseecom_send_command(struct qseecom_handle *handle, void *send_buf,
|
||||
req.cmd_req_buf = send_buf;
|
||||
req.resp_buf = resp_buf;
|
||||
|
||||
+ if (__validate_send_cmd_inputs(data, &req))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
if (qseecom.support_bus_scaling) {
|
||||
@@ -4111,6 +4127,19 @@ static int qseecom_save_partition_hash(void __user *argp)
|
||||
static int __qseecom_qteec_validate_msg(struct qseecom_dev_handle *data,
|
||||
struct qseecom_qteec_req *req)
|
||||
{
|
||||
+
|
||||
+ if (req->req_len > UINT_MAX - req->resp_len) {
|
||||
+ pr_err("Integer overflow detected in req_len & rsp_len\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (req->req_len + req->resp_len > data->client.sb_length) {
|
||||
+ pr_debug("Not enough memory to fit cmd_buf.\n");
|
||||
+ pr_debug("resp_buf. Required: %u, Available: %zu\n",
|
||||
+ (req->req_len + req->resp_len), data->client.sb_length);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
+
|
||||
if (req->req_ptr == NULL || req->resp_ptr == NULL) {
|
||||
pr_err("cmd buffer or response buffer is null\n");
|
||||
return -EINVAL;
|
||||
@@ -4131,15 +4160,33 @@ static int __qseecom_qteec_validate_msg(struct qseecom_dev_handle *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if ((req->req_len == 0) || (req->resp_len == 0) ||
|
||||
- req->req_len > data->client.sb_length ||
|
||||
- req->resp_len > data->client.sb_length) {
|
||||
+ if ((req->req_len == 0) || (req->resp_len == 0)) {
|
||||
pr_err("cmd buf lengtgh/response buf length not valid\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
- if (req->req_len > UINT_MAX - req->resp_len) {
|
||||
- pr_err("Integer overflow detected in req_len/rsp_len, exit\n");
|
||||
+ if ((uintptr_t)req->req_ptr > (ULONG_MAX - req->req_len)) {
|
||||
+ pr_err("Integer overflow in req_len & req_ptr\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if ((uintptr_t)req->resp_ptr > (ULONG_MAX - req->resp_len)) {
|
||||
+ pr_err("Integer overflow in resp_len & resp_ptr\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (data->client.user_virt_sb_base >
|
||||
+ (ULONG_MAX - data->client.sb_length)) {
|
||||
+ pr_err("Integer overflow in user_virt_sb_base & sb_length\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if ((((uintptr_t)req->req_ptr + req->req_len) >
|
||||
+ ((uintptr_t)data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length)) ||
|
||||
+ (((uintptr_t)req->resp_ptr + req->resp_len) >
|
||||
+ ((uintptr_t)data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))) {
|
||||
+ pr_err("cmd buf or resp buf is out of shared buffer region\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
return 0;
|
||||
--
|
||||
cgit v1.1
|
||||
|
308
Patches/Linux_CVEs/CVE-2014-4324/ANY/0001.patch
Normal file
308
Patches/Linux_CVEs/CVE-2014-4324/ANY/0001.patch
Normal file
@ -0,0 +1,308 @@
|
||||
From 8ad163e831a2b2c30551edb360f168a604cdb0bb Mon Sep 17 00:00:00 2001
|
||||
From: Alok Kediya <kediya@codeaurora.org>
|
||||
Date: Fri, 12 Dec 2014 04:20:59 -0800
|
||||
Subject: msm: camera: isp: Validate input parameter for vfe_write and vfe_read
|
||||
|
||||
Validate input parameters for read and write operations in vfe to
|
||||
ensure operations are performed within vfe register boundary and
|
||||
within structure limits passed by caller.
|
||||
|
||||
Change-Id: If3719de65b32773c2b6ff904da76a951dbfb11eb
|
||||
Signed-off-by: Alok Kediya <kediya@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/isp/msm_isp_util.c | 162 ++++++++++++++-------
|
||||
.../msm/camera_v2/sensor/io/msm_camera_io_util.c | 11 ++
|
||||
.../msm/camera_v2/sensor/io/msm_camera_io_util.h | 2 +
|
||||
3 files changed, 119 insertions(+), 56 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
index 620c01a..e1b79ce 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
@@ -494,9 +494,24 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd,
|
||||
uint32_t *cfg_data, uint32_t cmd_len)
|
||||
{
|
||||
+ if (!vfe_dev || !reg_cfg_cmd) {
|
||||
+ pr_err("%s:%d failed: vfe_dev %p reg_cfg_cmd %p\n", __func__,
|
||||
+ __LINE__, vfe_dev, reg_cfg_cmd);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if ((reg_cfg_cmd->cmd_type != VFE_CFG_MASK) &&
|
||||
+ (!cfg_data || !cmd_len)) {
|
||||
+ pr_err("%s:%d failed: cmd type %d cfg_data %p cmd_len %d\n",
|
||||
+ __func__, __LINE__, reg_cfg_cmd->cmd_type, cfg_data,
|
||||
+ cmd_len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ /* Validate input parameters */
|
||||
switch (reg_cfg_cmd->cmd_type) {
|
||||
case VFE_WRITE:
|
||||
- case VFE_READ: {
|
||||
+ case VFE_READ:
|
||||
+ case VFE_WRITE_MB: {
|
||||
if ((reg_cfg_cmd->u.rw_info.reg_offset >
|
||||
(UINT_MAX - reg_cfg_cmd->u.rw_info.len)) ||
|
||||
((reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
@@ -522,6 +537,58 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
}
|
||||
break;
|
||||
}
|
||||
+
|
||||
+ case VFE_WRITE_DMI_16BIT:
|
||||
+ case VFE_WRITE_DMI_32BIT:
|
||||
+ case VFE_WRITE_DMI_64BIT:
|
||||
+ case VFE_READ_DMI_16BIT:
|
||||
+ case VFE_READ_DMI_32BIT:
|
||||
+ case VFE_READ_DMI_64BIT: {
|
||||
+ if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
|
||||
+ if ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset <=
|
||||
+ reg_cfg_cmd->u.dmi_info.lo_tbl_offset) ||
|
||||
+ (reg_cfg_cmd->u.dmi_info.hi_tbl_offset -
|
||||
+ reg_cfg_cmd->u.dmi_info.lo_tbl_offset !=
|
||||
+ (sizeof(uint32_t)))) {
|
||||
+ pr_err("%s:%d hi %d lo %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
|
||||
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (reg_cfg_cmd->u.dmi_info.len <= sizeof(uint32_t)) {
|
||||
+ pr_err("%s:%d len %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.dmi_info.len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (((UINT_MAX -
|
||||
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset) <
|
||||
+ (reg_cfg_cmd->u.dmi_info.len -
|
||||
+ sizeof(uint32_t))) ||
|
||||
+ ((reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||||
+ reg_cfg_cmd->u.dmi_info.len -
|
||||
+ sizeof(uint32_t)) > cmd_len)) {
|
||||
+ pr_err("%s:%d hi_tbl_offset %d len %d cmd %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.dmi_info.hi_tbl_offset,
|
||||
+ reg_cfg_cmd->u.dmi_info.len, cmd_len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
+ if ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset >
|
||||
+ (UINT_MAX - reg_cfg_cmd->u.dmi_info.len)) ||
|
||||
+ ((reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||||
+ reg_cfg_cmd->u.dmi_info.len) > cmd_len)) {
|
||||
+ pr_err("%s:%d lo_tbl_offset %d len %d cmd_len %d\n",
|
||||
+ __func__, __LINE__,
|
||||
+ reg_cfg_cmd->u.dmi_info.lo_tbl_offset,
|
||||
+ reg_cfg_cmd->u.dmi_info.len, cmd_len);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -535,39 +602,27 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
break;
|
||||
}
|
||||
case VFE_WRITE_MB: {
|
||||
- uint32_t *data_ptr = cfg_data +
|
||||
- reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
|
||||
-
|
||||
- if ((UINT_MAX - sizeof(*data_ptr) <
|
||||
- reg_cfg_cmd->u.rw_info.reg_offset) ||
|
||||
- (resource_size(vfe_dev->vfe_mem) <
|
||||
- reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
- sizeof(*data_ptr))) {
|
||||
- pr_err("%s: VFE_WRITE_MB: Invalid length\n", __func__);
|
||||
- return -EINVAL;
|
||||
- }
|
||||
- msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base +
|
||||
- reg_cfg_cmd->u.rw_info.reg_offset);
|
||||
+ msm_camera_io_memcpy_mb(vfe_dev->vfe_base +
|
||||
+ reg_cfg_cmd->u.rw_info.reg_offset,
|
||||
+ cfg_data + reg_cfg_cmd->u.rw_info.cmd_data_offset/4,
|
||||
+ reg_cfg_cmd->u.rw_info.len);
|
||||
break;
|
||||
}
|
||||
case VFE_CFG_MASK: {
|
||||
uint32_t temp;
|
||||
- if (resource_size(vfe_dev->vfe_mem) <
|
||||
- reg_cfg_cmd->u.mask_info.reg_offset)
|
||||
- return -EINVAL;
|
||||
- temp = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
- reg_cfg_cmd->u.mask_info.reg_offset);
|
||||
-
|
||||
- temp &= ~reg_cfg_cmd->u.mask_info.mask;
|
||||
- temp |= reg_cfg_cmd->u.mask_info.val;
|
||||
if ((UINT_MAX - sizeof(temp) <
|
||||
- reg_cfg_cmd->u.mask_info.reg_offset) ||
|
||||
+ reg_cfg_cmd->u.mask_info.reg_offset) ||
|
||||
(resource_size(vfe_dev->vfe_mem) <
|
||||
reg_cfg_cmd->u.mask_info.reg_offset +
|
||||
sizeof(temp))) {
|
||||
pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
+ temp = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
+ reg_cfg_cmd->u.mask_info.reg_offset);
|
||||
+
|
||||
+ temp &= ~reg_cfg_cmd->u.mask_info.mask;
|
||||
+ temp |= reg_cfg_cmd->u.mask_info.val;
|
||||
msm_camera_io_w(temp, vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.mask_info.reg_offset);
|
||||
break;
|
||||
@@ -579,22 +634,9 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
|
||||
uint32_t hi_val, lo_val, lo_val1;
|
||||
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
|
||||
- if ((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset <
|
||||
- reg_cfg_cmd->u.dmi_info.len) ||
|
||||
- (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||||
- reg_cfg_cmd->u.dmi_info.len > cmd_len)) {
|
||||
- pr_err("Invalid Hi Table out of bounds\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
hi_tbl_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
|
||||
}
|
||||
-
|
||||
- if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||||
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||||
- pr_err("Invalid Lo Table out of bounds\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
lo_tbl_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
|
||||
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT)
|
||||
@@ -627,30 +669,18 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
|
||||
uint32_t hi_val, lo_val, lo_val1;
|
||||
if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
|
||||
- if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||||
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||||
- pr_err("Invalid Hi Table out of bounds\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
hi_tbl_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.dmi_info.hi_tbl_offset/4;
|
||||
}
|
||||
|
||||
- if (reg_cfg_cmd->u.dmi_info.lo_tbl_offset +
|
||||
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||||
- pr_err("Invalid Lo Table out of bounds\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
lo_tbl_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.dmi_info.lo_tbl_offset/4;
|
||||
|
||||
- for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
|
||||
- if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
|
||||
- hi_val = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
- vfe_dev->hw_info->dmi_reg_offset);
|
||||
- *hi_tbl_ptr++ = hi_val;
|
||||
- }
|
||||
+ if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT)
|
||||
+ reg_cfg_cmd->u.dmi_info.len =
|
||||
+ reg_cfg_cmd->u.dmi_info.len / 2;
|
||||
|
||||
+ for (i = 0; i < reg_cfg_cmd->u.dmi_info.len/4; i++) {
|
||||
lo_val = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
vfe_dev->hw_info->dmi_reg_offset + 0x4);
|
||||
|
||||
@@ -660,6 +690,13 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
lo_val |= lo_val1 << 16;
|
||||
}
|
||||
*lo_tbl_ptr++ = lo_val;
|
||||
+ if (reg_cfg_cmd->cmd_type == VFE_READ_DMI_64BIT) {
|
||||
+ hi_val = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
+ vfe_dev->hw_info->dmi_reg_offset);
|
||||
+ *hi_tbl_ptr = hi_val;
|
||||
+ hi_tbl_ptr += 2;
|
||||
+ lo_tbl_ptr++;
|
||||
+ }
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -698,7 +735,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
if ((data_ptr < cfg_data) ||
|
||||
(UINT_MAX / sizeof(*data_ptr) <
|
||||
(data_ptr - cfg_data)) ||
|
||||
- (sizeof(*data_ptr) * (data_ptr - cfg_data) >
|
||||
+ (sizeof(*data_ptr) * (data_ptr - cfg_data) >=
|
||||
cmd_len))
|
||||
return -EINVAL;
|
||||
*data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
@@ -707,9 +744,16 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
}
|
||||
break;
|
||||
}
|
||||
- case GET_SOC_HW_VER:
|
||||
- *cfg_data = vfe_dev->soc_hw_version;
|
||||
- break;
|
||||
+ case GET_SOC_HW_VER: {
|
||||
+ if (cmd_len < sizeof(uint32_t)) {
|
||||
+ pr_err("%s:%d failed: invalid cmd len %u exp %zu\n",
|
||||
+ __func__, __LINE__, cmd_len,
|
||||
+ sizeof(uint32_t));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ *cfg_data = vfe_dev->soc_hw_version;
|
||||
+ break;
|
||||
+ }
|
||||
case GET_MAX_CLK_RATE: {
|
||||
int rc = 0;
|
||||
|
||||
@@ -728,6 +772,12 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
break;
|
||||
}
|
||||
case SET_WM_UB_SIZE: {
|
||||
+ if (cmd_len < sizeof(uint32_t)) {
|
||||
+ pr_err("%s:%d failed: invalid cmd len %u exp %zu\n",
|
||||
+ __func__, __LINE__, cmd_len,
|
||||
+ sizeof(uint32_t));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
vfe_dev->vfe_ub_size = *cfg_data;
|
||||
break;
|
||||
}
|
||||
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 46a0542..7d369ff 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
|
||||
@@ -107,6 +107,17 @@ void msm_camera_io_memcpy(void __iomem *dest_addr,
|
||||
msm_camera_io_dump(dest_addr, len);
|
||||
}
|
||||
|
||||
+void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
|
||||
+ void __iomem *src_addr, u32 len)
|
||||
+{
|
||||
+ int i;
|
||||
+ u32 *d = (u32 *) dest_addr;
|
||||
+ u32 *s = (u32 *) src_addr;
|
||||
+
|
||||
+ for (i = 0; i < (len / 4); i++)
|
||||
+ msm_camera_io_w_mb(*s++, d++);
|
||||
+}
|
||||
+
|
||||
int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||||
struct msm_cam_clk_info *clk_src_info, int num_clk)
|
||||
{
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||||
index 2e6f809..90925a9 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/io/msm_camera_io_util.h
|
||||
@@ -28,6 +28,8 @@ u32 msm_camera_io_r_mb(void __iomem *addr);
|
||||
void msm_camera_io_dump(void __iomem *addr, int size);
|
||||
void msm_camera_io_memcpy(void __iomem *dest_addr,
|
||||
void __iomem *src_addr, u32 len);
|
||||
+void msm_camera_io_memcpy_mb(void __iomem *dest_addr,
|
||||
+ void __iomem *src_addr, u32 len);
|
||||
int msm_cam_clk_sel_src(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||||
struct msm_cam_clk_info *clk_src_info, int num_clk);
|
||||
int msm_cam_clk_enable(struct device *dev, struct msm_cam_clk_info *clk_info,
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,90 +0,0 @@
|
||||
From 0e2e43eca302b31f64ebfe4734fd2cc7358c4555 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:32 +0200
|
||||
Subject: ALSA: control: Fix replacing user controls
|
||||
|
||||
commit 82262a46627bebb0febcc26664746c25cef08563 upstream.
|
||||
|
||||
There are two issues with the current implementation for replacing user
|
||||
controls. The first is that the code does not check if the control is actually a
|
||||
user control and neither does it check if the control is owned by the process
|
||||
that tries to remove it. That allows userspace applications to remove arbitrary
|
||||
controls, which can cause a user after free if a for example a driver does not
|
||||
expect a control to be removed from under its feed.
|
||||
|
||||
The second issue is that on one hand when a control is replaced the
|
||||
user_ctl_count limit is not checked and on the other hand the user_ctl_count is
|
||||
increased (even though the number of user controls does not change). This allows
|
||||
userspace, once the user_ctl_count limit as been reached, to repeatedly replace
|
||||
a control until user_ctl_count overflows. Once that happens new controls can be
|
||||
added effectively bypassing the user_ctl_count limit.
|
||||
|
||||
Both issues can be fixed by instead of open-coding the removal of the control
|
||||
that is to be replaced to use snd_ctl_remove_user_ctl(). This function does
|
||||
proper permission checks as well as decrements user_ctl_count after the control
|
||||
has been removed.
|
||||
|
||||
Note that by using snd_ctl_remove_user_ctl() the check which returns -EBUSY at
|
||||
beginning of the function if the control already exists is removed. This is not
|
||||
a problem though since the check is quite useless, because the lock that is
|
||||
protecting the control list is released between the check and before adding the
|
||||
new control to the list, which means that it is possible that a different
|
||||
control with the same settings is added to the list after the check. Luckily
|
||||
there is another check that is done while holding the lock in snd_ctl_add(), so
|
||||
we'll rely on that to make sure that the same control is not added twice.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
sound/core/control.c | 25 +++++++++----------------
|
||||
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 920ea56..caa949e 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1151,8 +1151,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
- if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
- return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||
@@ -1161,21 +1159,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
|
||||
info->id.numid = 0;
|
||||
memset(&kctl, 0, sizeof(kctl));
|
||||
- down_write(&card->controls_rwsem);
|
||||
- _kctl = snd_ctl_find_id(card, &info->id);
|
||||
- err = 0;
|
||||
- if (_kctl) {
|
||||
- if (replace)
|
||||
- err = snd_ctl_remove(card, _kctl);
|
||||
- else
|
||||
- err = -EBUSY;
|
||||
- } else {
|
||||
- if (replace)
|
||||
- err = -ENOENT;
|
||||
+
|
||||
+ if (replace) {
|
||||
+ err = snd_ctl_remove_user_ctl(file, &info->id);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
}
|
||||
- up_write(&card->controls_rwsem);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+
|
||||
+ if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,27 +0,0 @@
|
||||
From 08ede038a738f22c1b3425051175e1d627d8dd43 Mon Sep 17 00:00:00 2001
|
||||
From: Lu Guanqun <guanqun.lu@intel.com>
|
||||
Date: Wed, 24 Aug 2011 14:45:10 +0800
|
||||
Subject: [PATCH] ALSA: core: release the constraint check for replace ops
|
||||
|
||||
Suppose the ALSA card already has a number of MAX_USER_CONTROLS controls, and
|
||||
the user wants to replace one, it should not fail at this condition check.
|
||||
|
||||
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/control.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 7f2b3a7eabb2b..dc2a44048c850 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1073,7 +1073,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
- if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
+ if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
@ -1,7 +1,7 @@
|
||||
From 82262a46627bebb0febcc26664746c25cef08563 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:32 +0200
|
||||
Subject: [PATCH] ALSA: control: Fix replacing user controls
|
||||
Subject: ALSA: control: Fix replacing user controls
|
||||
|
||||
There are two issues with the current implementation for replacing user
|
||||
controls. The first is that the code does not check if the control is actually a
|
||||
@ -40,7 +40,7 @@ Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 00ab034f5fcbe..1f413c2865113 100644
|
||||
index 00ab034..1f413c2 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1154,8 +1154,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
@ -83,3 +83,6 @@ index 00ab034f5fcbe..1f413c2865113 100644
|
||||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,39 +0,0 @@
|
||||
From f7500568b7633324e7c4282bb8baa3ff3f17fd7a Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:35 +0200
|
||||
Subject: ALSA: control: Make sure that id->index does not overflow
|
||||
|
||||
commit 883a1d49f0d77d30012f114b2e19fc141beb3e8e upstream.
|
||||
|
||||
The ALSA control code expects that the range of assigned indices to a control is
|
||||
continuous and does not overflow. Currently there are no checks to enforce this.
|
||||
If a control with a overflowing index range is created that control becomes
|
||||
effectively inaccessible and unremovable since snd_ctl_find_id() will not be
|
||||
able to find it. This patch adds a check that makes sure that controls with a
|
||||
overflowing index range can not be created.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
sound/core/control.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index d3f17de..9210594 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -341,6 +341,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
+ if (id.index > UINT_MAX - kcontrol->count)
|
||||
+ goto error;
|
||||
+
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,56 +0,0 @@
|
||||
From c7b18cdf1887e8ce91e04342cfd2d8fe1630be92 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sat, 1 Feb 2014 00:16:23 +0100
|
||||
Subject: mac80211: fix fragmentation code, particularly for encryption
|
||||
|
||||
commit 338f977f4eb441e69bb9a46eaa0ac715c931a67f upstream.
|
||||
|
||||
The "new" fragmentation code (since my rewrite almost 5 years ago)
|
||||
erroneously sets skb->len rather than using skb_trim() to adjust
|
||||
the length of the first fragment after copying out all the others.
|
||||
This leaves the skb tail pointer pointing to after where the data
|
||||
originally ended, and thus causes the encryption MIC to be written
|
||||
at that point, rather than where it belongs: immediately after the
|
||||
data.
|
||||
|
||||
The impact of this is that if software encryption is done, then
|
||||
a) encryption doesn't work for the first fragment, the connection
|
||||
becomes unusable as the first fragment will never be properly
|
||||
verified at the receiver, the MIC is practically guaranteed to
|
||||
be wrong
|
||||
b) we leak up to 8 bytes of plaintext (!) of the packet out into
|
||||
the air
|
||||
|
||||
This is only mitigated by the fact that many devices are capable
|
||||
of doing encryption in hardware, in which case this can't happen
|
||||
as the tail pointer is irrelevant in that case. Additionally,
|
||||
fragmentation is not used very frequently and would normally have
|
||||
to be configured manually.
|
||||
|
||||
Fix this by using skb_trim() properly.
|
||||
|
||||
Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
|
||||
Reported-by: Jouni Malinen <j@w1.fi>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
[bwh: Backported to 3.2: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/mac80211/tx.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 4ff35bf..5186f8b 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -884,7 +884,7 @@ static int ieee80211_fragment(struct ieee80211_local *local,
|
||||
pos += fraglen;
|
||||
}
|
||||
|
||||
- skb->len = hdrlen + per_fragm;
|
||||
+ skb_trim(skb, hdrlen + per_fragm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
16
Patches/Linux_CVEs/CVE-2014-9322/ANY/0001.patch
Normal file
16
Patches/Linux_CVEs/CVE-2014-9322/ANY/0001.patch
Normal file
@ -0,0 +1,16 @@
|
||||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
|
||||
index 8f3e2de..41baa1f 100644
|
||||
--- a/arch/x86/kernel/entry_32.S
|
||||
+++ b/arch/x86/kernel/entry_32.S
|
||||
@@ -554,11 +554,6 @@
|
||||
|
||||
CFI_RESTORE_STATE
|
||||
ldt_ss:
|
||||
- larl PT_OLDSS(%esp), %eax
|
||||
- jnz restore_nocheck
|
||||
- testl $0x00400000, %eax # returning to 32bit stack?
|
||||
- jnz restore_nocheck # allright, normal return
|
||||
-
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
/*
|
||||
* The kernel can't run on a non-flat stack if paravirt mode
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0001.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0001.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC9lbnRyeV8zMi5TIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzMyLlMKaW5kZXggOGYzZTJkZS4uNDFiYWExZiAxMDA2NDQKLS0tIGEvYXJjaC94ODYva2VybmVsL2VudHJ5XzMyLlMKKysrIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzMyLlMKQEAgLTU1NCwxMSArNTU0LDYgQEAKIAogCUNGSV9SRVNUT1JFX1NUQVRFCiBsZHRfc3M6Ci0JbGFybCBQVF9PTERTUyglZXNwKSwgJWVheAotCWpueiByZXN0b3JlX25vY2hlY2sKLQl0ZXN0bCAkMHgwMDQwMDAwMCwgJWVheAkJIyByZXR1cm5pbmcgdG8gMzJiaXQgc3RhY2s/Ci0Jam56IHJlc3RvcmVfbm9jaGVjawkJIyBhbGxyaWdodCwgbm9ybWFsIHJldHVybgotCiAjaWZkZWYgQ09ORklHX1BBUkFWSVJUCiAJLyoKIAkgKiBUaGUga2VybmVsIGNhbid0IHJ1biBvbiBhIG5vbi1mbGF0IHN0YWNrIGlmIHBhcmF2aXJ0IG1vZGUK
|
519
Patches/Linux_CVEs/CVE-2014-9322/ANY/0002.patch
Normal file
519
Patches/Linux_CVEs/CVE-2014-9322/ANY/0002.patch
Normal file
@ -0,0 +1,519 @@
|
||||
diff --git a/Documentation/x86/x86_64/mm.txt b/Documentation/x86/x86_64/mm.txt
|
||||
index 881582f..bd43704 100644
|
||||
--- a/Documentation/x86/x86_64/mm.txt
|
||||
+++ b/Documentation/x86/x86_64/mm.txt
|
||||
@@ -12,6 +12,8 @@
|
||||
ffffe90000000000 - ffffe9ffffffffff (=40 bits) hole
|
||||
ffffea0000000000 - ffffeaffffffffff (=40 bits) virtual memory map (1TB)
|
||||
... unused hole ...
|
||||
+ffffff0000000000 - ffffff7fffffffff (=39 bits) %esp fixup stacks
|
||||
+... unused hole ...
|
||||
ffffffff80000000 - ffffffffa0000000 (=512 MB) kernel text mapping, from phys 0
|
||||
ffffffffa0000000 - ffffffffff5fffff (=1525 MB) module mapping space
|
||||
ffffffffff600000 - ffffffffffdfffff (=8 MB) vsyscalls
|
||||
diff --git a/arch/x86/include/asm/pgtable_64_types.h b/arch/x86/include/asm/pgtable_64_types.h
|
||||
index 2d88344..b1609f2 100644
|
||||
--- a/arch/x86/include/asm/pgtable_64_types.h
|
||||
+++ b/arch/x86/include/asm/pgtable_64_types.h
|
||||
@@ -61,6 +61,8 @@
|
||||
#define MODULES_VADDR _AC(0xffffffffa0000000, UL)
|
||||
#define MODULES_END _AC(0xffffffffff000000, UL)
|
||||
#define MODULES_LEN (MODULES_END - MODULES_VADDR)
|
||||
+#define ESPFIX_PGD_ENTRY _AC(-2, UL)
|
||||
+#define ESPFIX_BASE_ADDR (ESPFIX_PGD_ENTRY << PGDIR_SHIFT)
|
||||
|
||||
#define EARLY_DYNAMIC_PAGE_TABLES 64
|
||||
|
||||
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
|
||||
index b7bf350..93797d1 100644
|
||||
--- a/arch/x86/include/asm/setup.h
|
||||
+++ b/arch/x86/include/asm/setup.h
|
||||
@@ -60,6 +60,9 @@
|
||||
static inline void x86_ce4100_early_setup(void) { }
|
||||
#endif
|
||||
|
||||
+extern void init_espfix_bsp(void);
|
||||
+extern void init_espfix_ap(void);
|
||||
+
|
||||
#ifndef _SETUP
|
||||
|
||||
/*
|
||||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
|
||||
index 7bd3bd3..0fde293 100644
|
||||
--- a/arch/x86/kernel/Makefile
|
||||
+++ b/arch/x86/kernel/Makefile
|
||||
@@ -27,6 +27,7 @@
|
||||
obj-y += syscall_$(BITS).o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_64.o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
|
||||
+obj-$(CONFIG_X86_64) += espfix_64.o
|
||||
obj-y += bootflag.o e820.o
|
||||
obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
|
||||
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
|
||||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
|
||||
index 7272089..75ccdc1 100644
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -58,6 +58,7 @@
|
||||
#include <asm/asm.h>
|
||||
#include <asm/context_tracking.h>
|
||||
#include <asm/smap.h>
|
||||
+#include <asm/pgtable_types.h>
|
||||
#include <linux/err.h>
|
||||
|
||||
/* Avoid __ASSEMBLER__'ifying <linux/audit.h> just for this. */
|
||||
@@ -1055,8 +1056,16 @@
|
||||
RESTORE_ARGS 1,8,1
|
||||
|
||||
irq_return:
|
||||
+ /*
|
||||
+ * Are we returning to a stack segment from the LDT? Note: in
|
||||
+ * 64-bit mode SS:RSP on the exception stack is always valid.
|
||||
+ */
|
||||
+ testb $4,(SS-RIP)(%rsp)
|
||||
+ jnz irq_return_ldt
|
||||
+
|
||||
+irq_return_iret:
|
||||
INTERRUPT_RETURN
|
||||
- _ASM_EXTABLE(irq_return, bad_iret)
|
||||
+ _ASM_EXTABLE(irq_return_iret, bad_iret)
|
||||
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
ENTRY(native_iret)
|
||||
@@ -1064,6 +1073,30 @@
|
||||
_ASM_EXTABLE(native_iret, bad_iret)
|
||||
#endif
|
||||
|
||||
+irq_return_ldt:
|
||||
+ pushq_cfi %rax
|
||||
+ pushq_cfi %rdi
|
||||
+ SWAPGS
|
||||
+ movq PER_CPU_VAR(espfix_waddr),%rdi
|
||||
+ movq %rax,(0*8)(%rdi) /* RAX */
|
||||
+ movq (2*8)(%rsp),%rax /* RIP */
|
||||
+ movq %rax,(1*8)(%rdi)
|
||||
+ movq (3*8)(%rsp),%rax /* CS */
|
||||
+ movq %rax,(2*8)(%rdi)
|
||||
+ movq (4*8)(%rsp),%rax /* RFLAGS */
|
||||
+ movq %rax,(3*8)(%rdi)
|
||||
+ movq (6*8)(%rsp),%rax /* SS */
|
||||
+ movq %rax,(5*8)(%rdi)
|
||||
+ movq (5*8)(%rsp),%rax /* RSP */
|
||||
+ movq %rax,(4*8)(%rdi)
|
||||
+ andl $0xffff0000,%eax
|
||||
+ popq_cfi %rdi
|
||||
+ orq PER_CPU_VAR(espfix_stack),%rax
|
||||
+ SWAPGS
|
||||
+ movq %rax,%rsp
|
||||
+ popq_cfi %rax
|
||||
+ jmp irq_return_iret
|
||||
+
|
||||
.section .fixup,"ax"
|
||||
bad_iret:
|
||||
/*
|
||||
@@ -1127,9 +1160,41 @@
|
||||
call preempt_schedule_irq
|
||||
jmp exit_intr
|
||||
#endif
|
||||
-
|
||||
CFI_ENDPROC
|
||||
END(common_interrupt)
|
||||
+
|
||||
+ /*
|
||||
+ * If IRET takes a fault on the espfix stack, then we
|
||||
+ * end up promoting it to a doublefault. In that case,
|
||||
+ * modify the stack to make it look like we just entered
|
||||
+ * the #GP handler from user space, similar to bad_iret.
|
||||
+ */
|
||||
+ ALIGN
|
||||
+__do_double_fault:
|
||||
+ XCPT_FRAME 1 RDI+8
|
||||
+ movq RSP(%rdi),%rax /* Trap on the espfix stack? */
|
||||
+ sarq $PGDIR_SHIFT,%rax
|
||||
+ cmpl $ESPFIX_PGD_ENTRY,%eax
|
||||
+ jne do_double_fault /* No, just deliver the fault */
|
||||
+ cmpl $__KERNEL_CS,CS(%rdi)
|
||||
+ jne do_double_fault
|
||||
+ movq RIP(%rdi),%rax
|
||||
+ cmpq $irq_return_iret,%rax
|
||||
+#ifdef CONFIG_PARAVIRT
|
||||
+ je 1f
|
||||
+ cmpq $native_iret,%rax
|
||||
+#endif
|
||||
+ jne do_double_fault /* This shouldn't happen... */
|
||||
+1:
|
||||
+ movq PER_CPU_VAR(kernel_stack),%rax
|
||||
+ subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */
|
||||
+ movq %rax,RSP(%rdi)
|
||||
+ movq $0,(%rax) /* Missing (lost) #GP error code */
|
||||
+ movq $general_protection,RIP(%rdi)
|
||||
+ retq
|
||||
+ CFI_ENDPROC
|
||||
+END(__do_double_fault)
|
||||
+
|
||||
/*
|
||||
* End of kprobes section
|
||||
*/
|
||||
@@ -1298,7 +1363,7 @@
|
||||
zeroentry bounds do_bounds
|
||||
zeroentry invalid_op do_invalid_op
|
||||
zeroentry device_not_available do_device_not_available
|
||||
-paranoiderrorentry double_fault do_double_fault
|
||||
+paranoiderrorentry double_fault __do_double_fault
|
||||
zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun
|
||||
errorentry invalid_TSS do_invalid_TSS
|
||||
errorentry segment_not_present do_segment_not_present
|
||||
@@ -1585,7 +1650,7 @@
|
||||
*/
|
||||
error_kernelspace:
|
||||
incl %ebx
|
||||
- leaq irq_return(%rip),%rcx
|
||||
+ leaq irq_return_iret(%rip),%rcx
|
||||
cmpq %rcx,RIP+8(%rsp)
|
||||
je error_swapgs
|
||||
movl %ecx,%eax /* zero extend */
|
||||
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
|
||||
new file mode 100644
|
||||
index 0000000..8a64da3
|
||||
--- /dev/null
|
||||
+++ b/arch/x86/kernel/espfix_64.c
|
||||
@@ -0,0 +1,208 @@
|
||||
+/* ----------------------------------------------------------------------- *
|
||||
+ *
|
||||
+ * Copyright 2014 Intel Corporation; author: H. Peter Anvin
|
||||
+ *
|
||||
+ * This program is free software; you can redistribute it and/or modify it
|
||||
+ * under the terms and conditions of the GNU General Public License,
|
||||
+ * version 2, as published by the Free Software Foundation.
|
||||
+ *
|
||||
+ * This program is distributed in the hope 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.
|
||||
+ *
|
||||
+ * ----------------------------------------------------------------------- */
|
||||
+
|
||||
+/*
|
||||
+ * The IRET instruction, when returning to a 16-bit segment, only
|
||||
+ * restores the bottom 16 bits of the user space stack pointer. This
|
||||
+ * causes some 16-bit software to break, but it also leaks kernel state
|
||||
+ * to user space.
|
||||
+ *
|
||||
+ * This works around this by creating percpu "ministacks", each of which
|
||||
+ * is mapped 2^16 times 64K apart. When we detect that the return SS is
|
||||
+ * on the LDT, we copy the IRET frame to the ministack and use the
|
||||
+ * relevant alias to return to userspace. The ministacks are mapped
|
||||
+ * readonly, so if the IRET fault we promote #GP to #DF which is an IST
|
||||
+ * vector and thus has its own stack; we then do the fixup in the #DF
|
||||
+ * handler.
|
||||
+ *
|
||||
+ * This file sets up the ministacks and the related page tables. The
|
||||
+ * actual ministack invocation is in entry_64.S.
|
||||
+ */
|
||||
+
|
||||
+#include <linux/init.h>
|
||||
+#include <linux/init_task.h>
|
||||
+#include <linux/kernel.h>
|
||||
+#include <linux/percpu.h>
|
||||
+#include <linux/gfp.h>
|
||||
+#include <linux/random.h>
|
||||
+#include <asm/pgtable.h>
|
||||
+#include <asm/pgalloc.h>
|
||||
+#include <asm/setup.h>
|
||||
+
|
||||
+/*
|
||||
+ * Note: we only need 6*8 = 48 bytes for the espfix stack, but round
|
||||
+ * it up to a cache line to avoid unnecessary sharing.
|
||||
+ */
|
||||
+#define ESPFIX_STACK_SIZE (8*8UL)
|
||||
+#define ESPFIX_STACKS_PER_PAGE (PAGE_SIZE/ESPFIX_STACK_SIZE)
|
||||
+
|
||||
+/* There is address space for how many espfix pages? */
|
||||
+#define ESPFIX_PAGE_SPACE (1UL << (PGDIR_SHIFT-PAGE_SHIFT-16))
|
||||
+
|
||||
+#define ESPFIX_MAX_CPUS (ESPFIX_STACKS_PER_PAGE * ESPFIX_PAGE_SPACE)
|
||||
+#if CONFIG_NR_CPUS > ESPFIX_MAX_CPUS
|
||||
+# error "Need more than one PGD for the ESPFIX hack"
|
||||
+#endif
|
||||
+
|
||||
+#define PGALLOC_GFP (GFP_KERNEL | __GFP_NOTRACK | __GFP_REPEAT | __GFP_ZERO)
|
||||
+
|
||||
+/* This contains the *bottom* address of the espfix stack */
|
||||
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
|
||||
+DEFINE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
|
||||
+
|
||||
+/* Initialization mutex - should this be a spinlock? */
|
||||
+static DEFINE_MUTEX(espfix_init_mutex);
|
||||
+
|
||||
+/* Page allocation bitmap - each page serves ESPFIX_STACKS_PER_PAGE CPUs */
|
||||
+#define ESPFIX_MAX_PAGES DIV_ROUND_UP(CONFIG_NR_CPUS, ESPFIX_STACKS_PER_PAGE)
|
||||
+static void *espfix_pages[ESPFIX_MAX_PAGES];
|
||||
+
|
||||
+static __page_aligned_bss pud_t espfix_pud_page[PTRS_PER_PUD]
|
||||
+ __aligned(PAGE_SIZE);
|
||||
+
|
||||
+static unsigned int page_random, slot_random;
|
||||
+
|
||||
+/*
|
||||
+ * This returns the bottom address of the espfix stack for a specific CPU.
|
||||
+ * The math allows for a non-power-of-two ESPFIX_STACK_SIZE, in which case
|
||||
+ * we have to account for some amount of padding at the end of each page.
|
||||
+ */
|
||||
+static inline unsigned long espfix_base_addr(unsigned int cpu)
|
||||
+{
|
||||
+ unsigned long page, slot;
|
||||
+ unsigned long addr;
|
||||
+
|
||||
+ page = (cpu / ESPFIX_STACKS_PER_PAGE) ^ page_random;
|
||||
+ slot = (cpu + slot_random) % ESPFIX_STACKS_PER_PAGE;
|
||||
+ addr = (page << PAGE_SHIFT) + (slot * ESPFIX_STACK_SIZE);
|
||||
+ addr = (addr & 0xffffUL) | ((addr & ~0xffffUL) << 16);
|
||||
+ addr += ESPFIX_BASE_ADDR;
|
||||
+ return addr;
|
||||
+}
|
||||
+
|
||||
+#define PTE_STRIDE (65536/PAGE_SIZE)
|
||||
+#define ESPFIX_PTE_CLONES (PTRS_PER_PTE/PTE_STRIDE)
|
||||
+#define ESPFIX_PMD_CLONES PTRS_PER_PMD
|
||||
+#define ESPFIX_PUD_CLONES (65536/(ESPFIX_PTE_CLONES*ESPFIX_PMD_CLONES))
|
||||
+
|
||||
+#define PGTABLE_PROT ((_KERNPG_TABLE & ~_PAGE_RW) | _PAGE_NX)
|
||||
+
|
||||
+static void init_espfix_random(void)
|
||||
+{
|
||||
+ unsigned long rand;
|
||||
+
|
||||
+ /*
|
||||
+ * This is run before the entropy pools are initialized,
|
||||
+ * but this is hopefully better than nothing.
|
||||
+ */
|
||||
+ if (!arch_get_random_long(&rand)) {
|
||||
+ /* The constant is an arbitrary large prime */
|
||||
+ rdtscll(rand);
|
||||
+ rand *= 0xc345c6b72fd16123UL;
|
||||
+ }
|
||||
+
|
||||
+ slot_random = rand % ESPFIX_STACKS_PER_PAGE;
|
||||
+ page_random = (rand / ESPFIX_STACKS_PER_PAGE)
|
||||
+ & (ESPFIX_PAGE_SPACE - 1);
|
||||
+}
|
||||
+
|
||||
+void __init init_espfix_bsp(void)
|
||||
+{
|
||||
+ pgd_t *pgd_p;
|
||||
+ pteval_t ptemask;
|
||||
+
|
||||
+ ptemask = __supported_pte_mask;
|
||||
+
|
||||
+ /* Install the espfix pud into the kernel page directory */
|
||||
+ pgd_p = &init_level4_pgt[pgd_index(ESPFIX_BASE_ADDR)];
|
||||
+ pgd_populate(&init_mm, pgd_p, (pud_t *)espfix_pud_page);
|
||||
+
|
||||
+ /* Randomize the locations */
|
||||
+ init_espfix_random();
|
||||
+
|
||||
+ /* The rest is the same as for any other processor */
|
||||
+ init_espfix_ap();
|
||||
+}
|
||||
+
|
||||
+void init_espfix_ap(void)
|
||||
+{
|
||||
+ unsigned int cpu, page;
|
||||
+ unsigned long addr;
|
||||
+ pud_t pud, *pud_p;
|
||||
+ pmd_t pmd, *pmd_p;
|
||||
+ pte_t pte, *pte_p;
|
||||
+ int n;
|
||||
+ void *stack_page;
|
||||
+ pteval_t ptemask;
|
||||
+
|
||||
+ /* We only have to do this once... */
|
||||
+ if (likely(this_cpu_read(espfix_stack)))
|
||||
+ return; /* Already initialized */
|
||||
+
|
||||
+ cpu = smp_processor_id();
|
||||
+ addr = espfix_base_addr(cpu);
|
||||
+ page = cpu/ESPFIX_STACKS_PER_PAGE;
|
||||
+
|
||||
+ /* Did another CPU already set this up? */
|
||||
+ stack_page = ACCESS_ONCE(espfix_pages[page]);
|
||||
+ if (likely(stack_page))
|
||||
+ goto done;
|
||||
+
|
||||
+ mutex_lock(&espfix_init_mutex);
|
||||
+
|
||||
+ /* Did we race on the lock? */
|
||||
+ stack_page = ACCESS_ONCE(espfix_pages[page]);
|
||||
+ if (stack_page)
|
||||
+ goto unlock_done;
|
||||
+
|
||||
+ ptemask = __supported_pte_mask;
|
||||
+
|
||||
+ pud_p = &espfix_pud_page[pud_index(addr)];
|
||||
+ pud = *pud_p;
|
||||
+ if (!pud_present(pud)) {
|
||||
+ pmd_p = (pmd_t *)__get_free_page(PGALLOC_GFP);
|
||||
+ pud = __pud(__pa(pmd_p) | (PGTABLE_PROT & ptemask));
|
||||
+ paravirt_alloc_pud(&init_mm, __pa(pmd_p) >> PAGE_SHIFT);
|
||||
+ for (n = 0; n < ESPFIX_PUD_CLONES; n++)
|
||||
+ set_pud(&pud_p[n], pud);
|
||||
+ }
|
||||
+
|
||||
+ pmd_p = pmd_offset(&pud, addr);
|
||||
+ pmd = *pmd_p;
|
||||
+ if (!pmd_present(pmd)) {
|
||||
+ pte_p = (pte_t *)__get_free_page(PGALLOC_GFP);
|
||||
+ pmd = __pmd(__pa(pte_p) | (PGTABLE_PROT & ptemask));
|
||||
+ paravirt_alloc_pmd(&init_mm, __pa(pte_p) >> PAGE_SHIFT);
|
||||
+ for (n = 0; n < ESPFIX_PMD_CLONES; n++)
|
||||
+ set_pmd(&pmd_p[n], pmd);
|
||||
+ }
|
||||
+
|
||||
+ pte_p = pte_offset_kernel(&pmd, addr);
|
||||
+ stack_page = (void *)__get_free_page(GFP_KERNEL);
|
||||
+ pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask));
|
||||
+ paravirt_alloc_pte(&init_mm, __pa(stack_page) >> PAGE_SHIFT);
|
||||
+ for (n = 0; n < ESPFIX_PTE_CLONES; n++)
|
||||
+ set_pte(&pte_p[n*PTE_STRIDE], pte);
|
||||
+
|
||||
+ /* Job is done for this CPU and any CPU which shares this page */
|
||||
+ ACCESS_ONCE(espfix_pages[page]) = stack_page;
|
||||
+
|
||||
+unlock_done:
|
||||
+ mutex_unlock(&espfix_init_mutex);
|
||||
+done:
|
||||
+ this_cpu_write(espfix_stack, addr);
|
||||
+ this_cpu_write(espfix_waddr, (unsigned long)stack_page
|
||||
+ + (addr & ~PAGE_MASK));
|
||||
+}
|
||||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
|
||||
index bfd348e..9f009cc 100644
|
||||
--- a/arch/x86/kernel/smpboot.c
|
||||
+++ b/arch/x86/kernel/smpboot.c
|
||||
@@ -265,6 +265,13 @@
|
||||
check_tsc_sync_target();
|
||||
|
||||
/*
|
||||
+ * Enable the espfix hack for this CPU
|
||||
+ */
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ init_espfix_ap();
|
||||
+#endif
|
||||
+
|
||||
+ /*
|
||||
* We need to hold vector_lock so there the set of online cpus
|
||||
* does not change while we are assigning vectors to cpus. Holding
|
||||
* this lock ensures we don't half assign or remove an irq from a cpu.
|
||||
diff --git a/arch/x86/mm/dump_pagetables.c b/arch/x86/mm/dump_pagetables.c
|
||||
index 0002a3a..e04e677 100644
|
||||
--- a/arch/x86/mm/dump_pagetables.c
|
||||
+++ b/arch/x86/mm/dump_pagetables.c
|
||||
@@ -30,11 +30,13 @@
|
||||
unsigned long start_address;
|
||||
unsigned long current_address;
|
||||
const struct addr_marker *marker;
|
||||
+ unsigned long lines;
|
||||
};
|
||||
|
||||
struct addr_marker {
|
||||
unsigned long start_address;
|
||||
const char *name;
|
||||
+ unsigned long max_lines;
|
||||
};
|
||||
|
||||
/* indices for address_markers; keep sync'd w/ address_markers below */
|
||||
@@ -45,6 +47,7 @@
|
||||
LOW_KERNEL_NR,
|
||||
VMALLOC_START_NR,
|
||||
VMEMMAP_START_NR,
|
||||
+ ESPFIX_START_NR,
|
||||
HIGH_KERNEL_NR,
|
||||
MODULES_VADDR_NR,
|
||||
MODULES_END_NR,
|
||||
@@ -67,6 +70,7 @@
|
||||
{ PAGE_OFFSET, "Low Kernel Mapping" },
|
||||
{ VMALLOC_START, "vmalloc() Area" },
|
||||
{ VMEMMAP_START, "Vmemmap" },
|
||||
+ { ESPFIX_BASE_ADDR, "ESPfix Area", 16 },
|
||||
{ __START_KERNEL_map, "High Kernel Mapping" },
|
||||
{ MODULES_VADDR, "Modules" },
|
||||
{ MODULES_END, "End Modules" },
|
||||
@@ -163,7 +167,7 @@
|
||||
pgprot_t new_prot, int level)
|
||||
{
|
||||
pgprotval_t prot, cur;
|
||||
- static const char units[] = "KMGTPE";
|
||||
+ static const char units[] = "BKMGTPE";
|
||||
|
||||
/*
|
||||
* If we have a "break" in the series, we need to flush the state that
|
||||
@@ -178,6 +182,7 @@
|
||||
st->current_prot = new_prot;
|
||||
st->level = level;
|
||||
st->marker = address_markers;
|
||||
+ st->lines = 0;
|
||||
seq_printf(m, "---[ %s ]---\n", st->marker->name);
|
||||
} else if (prot != cur || level != st->level ||
|
||||
st->current_address >= st->marker[1].start_address) {
|
||||
@@ -188,17 +193,21 @@
|
||||
/*
|
||||
* Now print the actual finished series
|
||||
*/
|
||||
- seq_printf(m, "0x%0*lx-0x%0*lx ",
|
||||
- width, st->start_address,
|
||||
- width, st->current_address);
|
||||
+ if (!st->marker->max_lines ||
|
||||
+ st->lines < st->marker->max_lines) {
|
||||
+ seq_printf(m, "0x%0*lx-0x%0*lx ",
|
||||
+ width, st->start_address,
|
||||
+ width, st->current_address);
|
||||
|
||||
- delta = (st->current_address - st->start_address) >> 10;
|
||||
- while (!(delta & 1023) && unit[1]) {
|
||||
- delta >>= 10;
|
||||
- unit++;
|
||||
+ delta = (st->current_address - st->start_address);
|
||||
+ while (!(delta & 1023) && unit[1]) {
|
||||
+ delta >>= 10;
|
||||
+ unit++;
|
||||
+ }
|
||||
+ seq_printf(m, "%9lu%c ", delta, *unit);
|
||||
+ printk_prot(m, st->current_prot, st->level);
|
||||
}
|
||||
- seq_printf(m, "%9lu%c ", delta, *unit);
|
||||
- printk_prot(m, st->current_prot, st->level);
|
||||
+ st->lines++;
|
||||
|
||||
/*
|
||||
* We print markers for special areas of address space,
|
||||
@@ -206,7 +215,15 @@
|
||||
* This helps in the interpretation.
|
||||
*/
|
||||
if (st->current_address >= st->marker[1].start_address) {
|
||||
+ if (st->marker->max_lines &&
|
||||
+ st->lines > st->marker->max_lines) {
|
||||
+ unsigned long nskip =
|
||||
+ st->lines - st->marker->max_lines;
|
||||
+ seq_printf(m, "... %lu entr%s skipped ... \n",
|
||||
+ nskip, nskip == 1 ? "y" : "ies");
|
||||
+ }
|
||||
st->marker++;
|
||||
+ st->lines = 0;
|
||||
seq_printf(m, "---[ %s ]---\n", st->marker->name);
|
||||
}
|
||||
|
||||
diff --git a/init/main.c b/init/main.c
|
||||
index 9484f4b..a9e4a76 100644
|
||||
--- a/init/main.c
|
||||
+++ b/init/main.c
|
||||
@@ -605,6 +605,10 @@
|
||||
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
efi_enter_virtual_mode();
|
||||
#endif
|
||||
+#ifdef CONFIG_X86_64
|
||||
+ /* Should be run before the first non-init thread is created */
|
||||
+ init_espfix_bsp();
|
||||
+#endif
|
||||
thread_info_cache_init();
|
||||
cred_init();
|
||||
fork_init(totalram_pages);
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0002.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0002.patch.base64
Normal file
File diff suppressed because one or more lines are too long
52
Patches/Linux_CVEs/CVE-2014-9322/ANY/0003.patch
Normal file
52
Patches/Linux_CVEs/CVE-2014-9322/ANY/0003.patch
Normal file
@ -0,0 +1,52 @@
|
||||
diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h
|
||||
new file mode 100644
|
||||
index 0000000..729051c
|
||||
--- /dev/null
|
||||
+++ b/arch/x86/include/asm/espfix.h
|
||||
@@ -0,0 +1,16 @@
|
||||
+#ifdef _ASM_X86_ESPFIX_H
|
||||
+#define _ASM_X86_ESPFIX_H
|
||||
+
|
||||
+#ifdef CONFIG_X86_64
|
||||
+
|
||||
+#include <asm/percpu.h>
|
||||
+
|
||||
+DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_stack);
|
||||
+DECLARE_PER_CPU_READ_MOSTLY(unsigned long, espfix_waddr);
|
||||
+
|
||||
+extern void init_espfix_bsp(void);
|
||||
+extern void init_espfix_ap(void);
|
||||
+
|
||||
+#endif /* CONFIG_X86_64 */
|
||||
+
|
||||
+#endif /* _ASM_X86_ESPFIX_H */
|
||||
diff --git a/arch/x86/include/asm/setup.h b/arch/x86/include/asm/setup.h
|
||||
index 93797d1..2e327f1 100644
|
||||
--- a/arch/x86/include/asm/setup.h
|
||||
+++ b/arch/x86/include/asm/setup.h
|
||||
@@ -60,11 +60,10 @@
|
||||
static inline void x86_ce4100_early_setup(void) { }
|
||||
#endif
|
||||
|
||||
-extern void init_espfix_bsp(void);
|
||||
-extern void init_espfix_ap(void);
|
||||
-
|
||||
#ifndef _SETUP
|
||||
|
||||
+#include <asm/espfix.h>
|
||||
+
|
||||
/*
|
||||
* This is set up by the setup-routine at boot-time
|
||||
*/
|
||||
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
|
||||
index 8a64da3..6afbb16 100644
|
||||
--- a/arch/x86/kernel/espfix_64.c
|
||||
+++ b/arch/x86/kernel/espfix_64.c
|
||||
@@ -40,6 +40,7 @@
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/pgalloc.h>
|
||||
#include <asm/setup.h>
|
||||
+#include <asm/espfix.h>
|
||||
|
||||
/*
|
||||
* Note: we only need 6*8 = 48 bytes for the espfix stack, but round
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0003.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0003.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL2VzcGZpeC5oIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vZXNwZml4LmgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzI5MDUxYwotLS0gL2Rldi9udWxsCisrKyBiL2FyY2gveDg2L2luY2x1ZGUvYXNtL2VzcGZpeC5oCkBAIC0wLDAgKzEsMTYgQEAKKyNpZmRlZiBfQVNNX1g4Nl9FU1BGSVhfSAorI2RlZmluZSBfQVNNX1g4Nl9FU1BGSVhfSAorCisjaWZkZWYgQ09ORklHX1g4Nl82NAorCisjaW5jbHVkZSA8YXNtL3BlcmNwdS5oPgorCitERUNMQVJFX1BFUl9DUFVfUkVBRF9NT1NUTFkodW5zaWduZWQgbG9uZywgZXNwZml4X3N0YWNrKTsKK0RFQ0xBUkVfUEVSX0NQVV9SRUFEX01PU1RMWSh1bnNpZ25lZCBsb25nLCBlc3BmaXhfd2FkZHIpOworCitleHRlcm4gdm9pZCBpbml0X2VzcGZpeF9ic3Aodm9pZCk7CitleHRlcm4gdm9pZCBpbml0X2VzcGZpeF9hcCh2b2lkKTsKKworI2VuZGlmIC8qIENPTkZJR19YODZfNjQgKi8KKworI2VuZGlmIC8qIF9BU01fWDg2X0VTUEZJWF9IICovCmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9zZXR1cC5oIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vc2V0dXAuaAppbmRleCA5Mzc5N2QxLi4yZTMyN2YxIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9zZXR1cC5oCisrKyBiL2FyY2gveDg2L2luY2x1ZGUvYXNtL3NldHVwLmgKQEAgLTYwLDExICs2MCwxMCBAQAogc3RhdGljIGlubGluZSB2b2lkIHg4Nl9jZTQxMDBfZWFybHlfc2V0dXAodm9pZCkgeyB9CiAjZW5kaWYKIAotZXh0ZXJuIHZvaWQgaW5pdF9lc3BmaXhfYnNwKHZvaWQpOwotZXh0ZXJuIHZvaWQgaW5pdF9lc3BmaXhfYXAodm9pZCk7Ci0KICNpZm5kZWYgX1NFVFVQCiAKKyNpbmNsdWRlIDxhc20vZXNwZml4Lmg+CisKIC8qCiAgKiBUaGlzIGlzIHNldCB1cCBieSB0aGUgc2V0dXAtcm91dGluZSBhdCBib290LXRpbWUKICAqLwpkaWZmIC0tZ2l0IGEvYXJjaC94ODYva2VybmVsL2VzcGZpeF82NC5jIGIvYXJjaC94ODYva2VybmVsL2VzcGZpeF82NC5jCmluZGV4IDhhNjRkYTMuLjZhZmJiMTYgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2tlcm5lbC9lc3BmaXhfNjQuYworKysgYi9hcmNoL3g4Ni9rZXJuZWwvZXNwZml4XzY0LmMKQEAgLTQwLDYgKzQwLDcgQEAKICNpbmNsdWRlIDxhc20vcGd0YWJsZS5oPgogI2luY2x1ZGUgPGFzbS9wZ2FsbG9jLmg+CiAjaW5jbHVkZSA8YXNtL3NldHVwLmg+CisjaW5jbHVkZSA8YXNtL2VzcGZpeC5oPgogCiAvKgogICogTm90ZTogd2Ugb25seSBuZWVkIDYqOCA9IDQ4IGJ5dGVzIGZvciB0aGUgZXNwZml4IHN0YWNrLCBidXQgcm91bmQK
|
10
Patches/Linux_CVEs/CVE-2014-9322/ANY/0004.patch
Normal file
10
Patches/Linux_CVEs/CVE-2014-9322/ANY/0004.patch
Normal file
@ -0,0 +1,10 @@
|
||||
diff --git a/arch/x86/include/asm/espfix.h b/arch/x86/include/asm/espfix.h
|
||||
index 729051c..99efebb 100644
|
||||
--- a/arch/x86/include/asm/espfix.h
|
||||
+++ b/arch/x86/include/asm/espfix.h
|
||||
@@ -1,4 +1,4 @@
|
||||
-#ifdef _ASM_X86_ESPFIX_H
|
||||
+#ifndef _ASM_X86_ESPFIX_H
|
||||
#define _ASM_X86_ESPFIX_H
|
||||
|
||||
#ifdef CONFIG_X86_64
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0004.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0004.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL2VzcGZpeC5oIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vZXNwZml4LmgKaW5kZXggNzI5MDUxYy4uOTllZmViYiAxMDA2NDQKLS0tIGEvYXJjaC94ODYvaW5jbHVkZS9hc20vZXNwZml4LmgKKysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vZXNwZml4LmgKQEAgLTEsNCArMSw0IEBACi0jaWZkZWYgX0FTTV9YODZfRVNQRklYX0gKKyNpZm5kZWYgX0FTTV9YODZfRVNQRklYX0gKICNkZWZpbmUgX0FTTV9YODZfRVNQRklYX0gKIAogI2lmZGVmIENPTkZJR19YODZfNjQK
|
54
Patches/Linux_CVEs/CVE-2014-9322/ANY/0005.patch
Normal file
54
Patches/Linux_CVEs/CVE-2014-9322/ANY/0005.patch
Normal file
@ -0,0 +1,54 @@
|
||||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
||||
index 4b20846..520cde8 100644
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -972,6 +972,10 @@
|
||||
XFree86 to initialize some video cards via BIOS. Disabling this
|
||||
option saves about 6k.
|
||||
|
||||
+config X86_ESPFIX64
|
||||
+ def_bool y
|
||||
+ depends on X86_64
|
||||
+
|
||||
config TOSHIBA
|
||||
tristate "Toshiba Laptop support"
|
||||
depends on X86_32
|
||||
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile
|
||||
index 0fde293..111eb35 100644
|
||||
--- a/arch/x86/kernel/Makefile
|
||||
+++ b/arch/x86/kernel/Makefile
|
||||
@@ -27,7 +27,7 @@
|
||||
obj-y += syscall_$(BITS).o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_64.o
|
||||
obj-$(CONFIG_X86_64) += vsyscall_emu_64.o
|
||||
-obj-$(CONFIG_X86_64) += espfix_64.o
|
||||
+obj-$(CONFIG_X86_ESPFIX64) += espfix_64.o
|
||||
obj-y += bootflag.o e820.o
|
||||
obj-y += pci-dma.o quirks.o topology.o kdebugfs.o
|
||||
obj-y += alternative.o i8253.o pci-nommu.o hw_breakpoint.o
|
||||
diff --git a/arch/x86/kernel/smpboot.c b/arch/x86/kernel/smpboot.c
|
||||
index 9f009cc..fe86275 100644
|
||||
--- a/arch/x86/kernel/smpboot.c
|
||||
+++ b/arch/x86/kernel/smpboot.c
|
||||
@@ -267,7 +267,7 @@
|
||||
/*
|
||||
* Enable the espfix hack for this CPU
|
||||
*/
|
||||
-#ifdef CONFIG_X86_64
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
init_espfix_ap();
|
||||
#endif
|
||||
|
||||
diff --git a/init/main.c b/init/main.c
|
||||
index a9e4a76..544cccf 100644
|
||||
--- a/init/main.c
|
||||
+++ b/init/main.c
|
||||
@@ -605,7 +605,7 @@
|
||||
if (efi_enabled(EFI_RUNTIME_SERVICES))
|
||||
efi_enter_virtual_mode();
|
||||
#endif
|
||||
-#ifdef CONFIG_X86_64
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
/* Should be run before the first non-init thread is created */
|
||||
init_espfix_bsp();
|
||||
#endif
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0005.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0005.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L0tjb25maWcgYi9hcmNoL3g4Ni9LY29uZmlnCmluZGV4IDRiMjA4NDYuLjUyMGNkZTggMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L0tjb25maWcKKysrIGIvYXJjaC94ODYvS2NvbmZpZwpAQCAtOTcyLDYgKzk3MiwxMCBAQAogCSAgWEZyZWU4NiB0byBpbml0aWFsaXplIHNvbWUgdmlkZW8gY2FyZHMgdmlhIEJJT1MuIERpc2FibGluZyB0aGlzCiAJICBvcHRpb24gc2F2ZXMgYWJvdXQgNmsuCiAKK2NvbmZpZyBYODZfRVNQRklYNjQKKwlkZWZfYm9vbCB5CisJZGVwZW5kcyBvbiBYODZfNjQKKwogY29uZmlnIFRPU0hJQkEKIAl0cmlzdGF0ZSAiVG9zaGliYSBMYXB0b3Agc3VwcG9ydCIKIAlkZXBlbmRzIG9uIFg4Nl8zMgpkaWZmIC0tZ2l0IGEvYXJjaC94ODYva2VybmVsL01ha2VmaWxlIGIvYXJjaC94ODYva2VybmVsL01ha2VmaWxlCmluZGV4IDBmZGUyOTMuLjExMWViMzUgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2tlcm5lbC9NYWtlZmlsZQorKysgYi9hcmNoL3g4Ni9rZXJuZWwvTWFrZWZpbGUKQEAgLTI3LDcgKzI3LDcgQEAKIG9iai15CQkJKz0gc3lzY2FsbF8kKEJJVFMpLm8KIG9iai0kKENPTkZJR19YODZfNjQpCSs9IHZzeXNjYWxsXzY0Lm8KIG9iai0kKENPTkZJR19YODZfNjQpCSs9IHZzeXNjYWxsX2VtdV82NC5vCi1vYmotJChDT05GSUdfWDg2XzY0KQkrPSBlc3BmaXhfNjQubworb2JqLSQoQ09ORklHX1g4Nl9FU1BGSVg2NCkJKz0gZXNwZml4XzY0Lm8KIG9iai15CQkJKz0gYm9vdGZsYWcubyBlODIwLm8KIG9iai15CQkJKz0gcGNpLWRtYS5vIHF1aXJrcy5vIHRvcG9sb2d5Lm8ga2RlYnVnZnMubwogb2JqLXkJCQkrPSBhbHRlcm5hdGl2ZS5vIGk4MjUzLm8gcGNpLW5vbW11Lm8gaHdfYnJlYWtwb2ludC5vCmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9rZXJuZWwvc21wYm9vdC5jIGIvYXJjaC94ODYva2VybmVsL3NtcGJvb3QuYwppbmRleCA5ZjAwOWNjLi5mZTg2Mjc1IDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9rZXJuZWwvc21wYm9vdC5jCisrKyBiL2FyY2gveDg2L2tlcm5lbC9zbXBib290LmMKQEAgLTI2Nyw3ICsyNjcsNyBAQAogCS8qCiAJICogRW5hYmxlIHRoZSBlc3BmaXggaGFjayBmb3IgdGhpcyBDUFUKIAkgKi8KLSNpZmRlZiBDT05GSUdfWDg2XzY0CisjaWZkZWYgQ09ORklHX1g4Nl9FU1BGSVg2NAogCWluaXRfZXNwZml4X2FwKCk7CiAjZW5kaWYKIApkaWZmIC0tZ2l0IGEvaW5pdC9tYWluLmMgYi9pbml0L21haW4uYwppbmRleCBhOWU0YTc2Li41NDRjY2NmIDEwMDY0NAotLS0gYS9pbml0L21haW4uYworKysgYi9pbml0L21haW4uYwpAQCAtNjA1LDcgKzYwNSw3IEBACiAJaWYgKGVmaV9lbmFibGVkKEVGSV9SVU5USU1FX1NFUlZJQ0VTKSkKIAkJZWZpX2VudGVyX3ZpcnR1YWxfbW9kZSgpOwogI2VuZGlmCi0jaWZkZWYgQ09ORklHX1g4Nl82NAorI2lmZGVmIENPTkZJR19YODZfRVNQRklYNjQKIAkvKiBTaG91bGQgYmUgcnVuIGJlZm9yZSB0aGUgZmlyc3Qgbm9uLWluaXQgdGhyZWFkIGlzIGNyZWF0ZWQgKi8KIAlpbml0X2VzcGZpeF9ic3AoKTsKICNlbmRpZgo=
|
195
Patches/Linux_CVEs/CVE-2014-9322/ANY/0006.patch
Normal file
195
Patches/Linux_CVEs/CVE-2014-9322/ANY/0006.patch
Normal file
@ -0,0 +1,195 @@
|
||||
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
|
||||
index 520cde8..2b6c572 100644
|
||||
--- a/arch/x86/Kconfig
|
||||
+++ b/arch/x86/Kconfig
|
||||
@@ -967,14 +967,27 @@
|
||||
default y
|
||||
depends on X86_32
|
||||
---help---
|
||||
- This option is required by programs like DOSEMU to run 16-bit legacy
|
||||
- code on X86 processors. It also may be needed by software like
|
||||
- XFree86 to initialize some video cards via BIOS. Disabling this
|
||||
- option saves about 6k.
|
||||
+ This option is required by programs like DOSEMU to run
|
||||
+ 16-bit real mode legacy code on x86 processors. It also may
|
||||
+ be needed by software like XFree86 to initialize some video
|
||||
+ cards via BIOS. Disabling this option saves about 6K.
|
||||
+
|
||||
+config X86_16BIT
|
||||
+ bool "Enable support for 16-bit segments" if EXPERT
|
||||
+ default y
|
||||
+ ---help---
|
||||
+ This option is required by programs like Wine to run 16-bit
|
||||
+ protected mode legacy code on x86 processors. Disabling
|
||||
+ this option saves about 300 bytes on i386, or around 6K text
|
||||
+ plus 16K runtime memory on x86-64,
|
||||
+
|
||||
+config X86_ESPFIX32
|
||||
+ def_bool y
|
||||
+ depends on X86_16BIT && X86_32
|
||||
|
||||
config X86_ESPFIX64
|
||||
def_bool y
|
||||
- depends on X86_64
|
||||
+ depends on X86_16BIT && X86_64
|
||||
|
||||
config TOSHIBA
|
||||
tristate "Toshiba Laptop support"
|
||||
diff --git a/arch/x86/kernel/entry_32.S b/arch/x86/kernel/entry_32.S
|
||||
index 41baa1f..e758e2f 100644
|
||||
--- a/arch/x86/kernel/entry_32.S
|
||||
+++ b/arch/x86/kernel/entry_32.S
|
||||
@@ -530,6 +530,7 @@
|
||||
restore_all:
|
||||
TRACE_IRQS_IRET
|
||||
restore_all_notrace:
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
|
||||
# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
|
||||
# are returning to the kernel.
|
||||
@@ -540,6 +541,7 @@
|
||||
cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
|
||||
CFI_REMEMBER_STATE
|
||||
je ldt_ss # returning to user-space with LDT SS
|
||||
+#endif
|
||||
restore_nocheck:
|
||||
RESTORE_REGS 4 # skip orig_eax/error_code
|
||||
irq_return:
|
||||
@@ -552,6 +554,7 @@
|
||||
.previous
|
||||
_ASM_EXTABLE(irq_return,iret_exc)
|
||||
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
CFI_RESTORE_STATE
|
||||
ldt_ss:
|
||||
#ifdef CONFIG_PARAVIRT
|
||||
@@ -595,6 +598,7 @@
|
||||
lss (%esp), %esp /* switch to espfix segment */
|
||||
CFI_ADJUST_CFA_OFFSET -8
|
||||
jmp restore_nocheck
|
||||
+#endif
|
||||
CFI_ENDPROC
|
||||
ENDPROC(system_call)
|
||||
|
||||
@@ -702,6 +706,7 @@
|
||||
* the high word of the segment base from the GDT and swiches to the
|
||||
* normal stack and adjusts ESP with the matching offset.
|
||||
*/
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
/* fixup the stack */
|
||||
mov GDT_ESPFIX_SS + 4, %al /* bits 16..23 */
|
||||
mov GDT_ESPFIX_SS + 7, %ah /* bits 24..31 */
|
||||
@@ -711,8 +716,10 @@
|
||||
pushl_cfi %eax
|
||||
lss (%esp), %esp /* switch to the normal stack segment */
|
||||
CFI_ADJUST_CFA_OFFSET -8
|
||||
+#endif
|
||||
.endm
|
||||
.macro UNWIND_ESPFIX_STACK
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
movl %ss, %eax
|
||||
/* see if on espfix stack */
|
||||
cmpw $__ESPFIX_SS, %ax
|
||||
@@ -723,6 +730,7 @@
|
||||
/* switch to normal stack */
|
||||
FIXUP_ESPFIX_STACK
|
||||
27:
|
||||
+#endif
|
||||
.endm
|
||||
|
||||
/*
|
||||
@@ -1330,11 +1338,13 @@
|
||||
ENTRY(nmi)
|
||||
RING0_INT_FRAME
|
||||
ASM_CLAC
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
pushl_cfi %eax
|
||||
movl %ss, %eax
|
||||
cmpw $__ESPFIX_SS, %ax
|
||||
popl_cfi %eax
|
||||
je nmi_espfix_stack
|
||||
+#endif
|
||||
cmpl $ia32_sysenter_target,(%esp)
|
||||
je nmi_stack_fixup
|
||||
pushl_cfi %eax
|
||||
@@ -1374,6 +1384,7 @@
|
||||
FIX_STACK 24, nmi_stack_correct, 1
|
||||
jmp nmi_stack_correct
|
||||
|
||||
+#ifdef CONFIG_X86_ESPFIX32
|
||||
nmi_espfix_stack:
|
||||
/* We have a RING0_INT_FRAME here.
|
||||
*
|
||||
@@ -1395,6 +1406,7 @@
|
||||
lss 12+4(%esp), %esp # back to espfix stack
|
||||
CFI_ADJUST_CFA_OFFSET -24
|
||||
jmp irq_return
|
||||
+#endif
|
||||
CFI_ENDPROC
|
||||
END(nmi)
|
||||
|
||||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
|
||||
index 75ccdc1..f9315d9 100644
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -1060,8 +1060,10 @@
|
||||
* Are we returning to a stack segment from the LDT? Note: in
|
||||
* 64-bit mode SS:RSP on the exception stack is always valid.
|
||||
*/
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
testb $4,(SS-RIP)(%rsp)
|
||||
jnz irq_return_ldt
|
||||
+#endif
|
||||
|
||||
irq_return_iret:
|
||||
INTERRUPT_RETURN
|
||||
@@ -1073,6 +1075,7 @@
|
||||
_ASM_EXTABLE(native_iret, bad_iret)
|
||||
#endif
|
||||
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
irq_return_ldt:
|
||||
pushq_cfi %rax
|
||||
pushq_cfi %rdi
|
||||
@@ -1096,6 +1099,7 @@
|
||||
movq %rax,%rsp
|
||||
popq_cfi %rax
|
||||
jmp irq_return_iret
|
||||
+#endif
|
||||
|
||||
.section .fixup,"ax"
|
||||
bad_iret:
|
||||
@@ -1169,6 +1173,7 @@
|
||||
* modify the stack to make it look like we just entered
|
||||
* the #GP handler from user space, similar to bad_iret.
|
||||
*/
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
ALIGN
|
||||
__do_double_fault:
|
||||
XCPT_FRAME 1 RDI+8
|
||||
@@ -1194,6 +1199,9 @@
|
||||
retq
|
||||
CFI_ENDPROC
|
||||
END(__do_double_fault)
|
||||
+#else
|
||||
+# define __do_double_fault do_double_fault
|
||||
+#endif
|
||||
|
||||
/*
|
||||
* End of kprobes section
|
||||
diff --git a/arch/x86/kernel/ldt.c b/arch/x86/kernel/ldt.c
|
||||
index ebc9873..c37886d 100644
|
||||
--- a/arch/x86/kernel/ldt.c
|
||||
+++ b/arch/x86/kernel/ldt.c
|
||||
@@ -229,6 +229,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
+ if (!IS_ENABLED(CONFIG_X86_16BIT) && !ldt_info.seg_32bit) {
|
||||
+ error = -EINVAL;
|
||||
+ goto out_unlock;
|
||||
+ }
|
||||
+
|
||||
fill_ldt(&ldt, &ldt_info);
|
||||
if (oldmode)
|
||||
ldt.avl = 0;
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0006.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0006.patch.base64
Normal file
File diff suppressed because one or more lines are too long
105
Patches/Linux_CVEs/CVE-2014-9322/ANY/0007.patch
Normal file
105
Patches/Linux_CVEs/CVE-2014-9322/ANY/0007.patch
Normal file
@ -0,0 +1,105 @@
|
||||
diff --git a/arch/x86/include/asm/irqflags.h b/arch/x86/include/asm/irqflags.h
|
||||
index bba3cf8..0a8b519 100644
|
||||
--- a/arch/x86/include/asm/irqflags.h
|
||||
+++ b/arch/x86/include/asm/irqflags.h
|
||||
@@ -129,7 +129,7 @@
|
||||
|
||||
#define PARAVIRT_ADJUST_EXCEPTION_FRAME /* */
|
||||
|
||||
-#define INTERRUPT_RETURN iretq
|
||||
+#define INTERRUPT_RETURN jmp native_iret
|
||||
#define USERGS_SYSRET64 \
|
||||
swapgs; \
|
||||
sysretq;
|
||||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
|
||||
index f9315d9..db230f8 100644
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -1056,27 +1056,24 @@
|
||||
RESTORE_ARGS 1,8,1
|
||||
|
||||
irq_return:
|
||||
+ INTERRUPT_RETURN
|
||||
+
|
||||
+ENTRY(native_iret)
|
||||
/*
|
||||
* Are we returning to a stack segment from the LDT? Note: in
|
||||
* 64-bit mode SS:RSP on the exception stack is always valid.
|
||||
*/
|
||||
#ifdef CONFIG_X86_ESPFIX64
|
||||
testb $4,(SS-RIP)(%rsp)
|
||||
- jnz irq_return_ldt
|
||||
+ jnz native_irq_return_ldt
|
||||
#endif
|
||||
|
||||
-irq_return_iret:
|
||||
- INTERRUPT_RETURN
|
||||
- _ASM_EXTABLE(irq_return_iret, bad_iret)
|
||||
-
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
-ENTRY(native_iret)
|
||||
+native_irq_return_iret:
|
||||
iretq
|
||||
- _ASM_EXTABLE(native_iret, bad_iret)
|
||||
-#endif
|
||||
+ _ASM_EXTABLE(native_irq_return_iret, bad_iret)
|
||||
|
||||
#ifdef CONFIG_X86_ESPFIX64
|
||||
-irq_return_ldt:
|
||||
+native_irq_return_ldt:
|
||||
pushq_cfi %rax
|
||||
pushq_cfi %rdi
|
||||
SWAPGS
|
||||
@@ -1098,7 +1095,7 @@
|
||||
SWAPGS
|
||||
movq %rax,%rsp
|
||||
popq_cfi %rax
|
||||
- jmp irq_return_iret
|
||||
+ jmp native_irq_return_iret
|
||||
#endif
|
||||
|
||||
.section .fixup,"ax"
|
||||
@@ -1184,13 +1181,8 @@
|
||||
cmpl $__KERNEL_CS,CS(%rdi)
|
||||
jne do_double_fault
|
||||
movq RIP(%rdi),%rax
|
||||
- cmpq $irq_return_iret,%rax
|
||||
-#ifdef CONFIG_PARAVIRT
|
||||
- je 1f
|
||||
- cmpq $native_iret,%rax
|
||||
-#endif
|
||||
+ cmpq $native_irq_return_iret,%rax
|
||||
jne do_double_fault /* This shouldn't happen... */
|
||||
-1:
|
||||
movq PER_CPU_VAR(kernel_stack),%rax
|
||||
subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */
|
||||
movq %rax,RSP(%rdi)
|
||||
@@ -1658,7 +1650,7 @@
|
||||
*/
|
||||
error_kernelspace:
|
||||
incl %ebx
|
||||
- leaq irq_return_iret(%rip),%rcx
|
||||
+ leaq native_irq_return_iret(%rip),%rcx
|
||||
cmpq %rcx,RIP+8(%rsp)
|
||||
je error_swapgs
|
||||
movl %ecx,%eax /* zero extend */
|
||||
diff --git a/arch/x86/kernel/paravirt_patch_64.c b/arch/x86/kernel/paravirt_patch_64.c
|
||||
index 3f08f34..a1da673 100644
|
||||
--- a/arch/x86/kernel/paravirt_patch_64.c
|
||||
+++ b/arch/x86/kernel/paravirt_patch_64.c
|
||||
@@ -6,7 +6,6 @@
|
||||
DEF_NATIVE(pv_irq_ops, irq_enable, "sti");
|
||||
DEF_NATIVE(pv_irq_ops, restore_fl, "pushq %rdi; popfq");
|
||||
DEF_NATIVE(pv_irq_ops, save_fl, "pushfq; popq %rax");
|
||||
-DEF_NATIVE(pv_cpu_ops, iret, "iretq");
|
||||
DEF_NATIVE(pv_mmu_ops, read_cr2, "movq %cr2, %rax");
|
||||
DEF_NATIVE(pv_mmu_ops, read_cr3, "movq %cr3, %rax");
|
||||
DEF_NATIVE(pv_mmu_ops, write_cr3, "movq %rdi, %cr3");
|
||||
@@ -50,7 +49,6 @@
|
||||
PATCH_SITE(pv_irq_ops, save_fl);
|
||||
PATCH_SITE(pv_irq_ops, irq_enable);
|
||||
PATCH_SITE(pv_irq_ops, irq_disable);
|
||||
- PATCH_SITE(pv_cpu_ops, iret);
|
||||
PATCH_SITE(pv_cpu_ops, irq_enable_sysexit);
|
||||
PATCH_SITE(pv_cpu_ops, usergs_sysret32);
|
||||
PATCH_SITE(pv_cpu_ops, usergs_sysret64);
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0007.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0007.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL2lycWZsYWdzLmggYi9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9pcnFmbGFncy5oCmluZGV4IGJiYTNjZjguLjBhOGI1MTkgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL2lycWZsYWdzLmgKKysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vaXJxZmxhZ3MuaApAQCAtMTI5LDcgKzEyOSw3IEBACiAKICNkZWZpbmUgUEFSQVZJUlRfQURKVVNUX0VYQ0VQVElPTl9GUkFNRQkvKiAgKi8KIAotI2RlZmluZSBJTlRFUlJVUFRfUkVUVVJOCWlyZXRxCisjZGVmaW5lIElOVEVSUlVQVF9SRVRVUk4Jam1wIG5hdGl2ZV9pcmV0CiAjZGVmaW5lIFVTRVJHU19TWVNSRVQ2NAkJCQlcCiAJc3dhcGdzOwkJCQkJXAogCXN5c3JldHE7CmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9rZXJuZWwvZW50cnlfNjQuUyBiL2FyY2gveDg2L2tlcm5lbC9lbnRyeV82NC5TCmluZGV4IGY5MzE1ZDkuLmRiMjMwZjggMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2tlcm5lbC9lbnRyeV82NC5TCisrKyBiL2FyY2gveDg2L2tlcm5lbC9lbnRyeV82NC5TCkBAIC0xMDU2LDI3ICsxMDU2LDI0IEBACiAJUkVTVE9SRV9BUkdTIDEsOCwxCiAKIGlycV9yZXR1cm46CisJSU5URVJSVVBUX1JFVFVSTgorCitFTlRSWShuYXRpdmVfaXJldCkKIAkvKgogCSAqIEFyZSB3ZSByZXR1cm5pbmcgdG8gYSBzdGFjayBzZWdtZW50IGZyb20gdGhlIExEVD8gIE5vdGU6IGluCiAJICogNjQtYml0IG1vZGUgU1M6UlNQIG9uIHRoZSBleGNlcHRpb24gc3RhY2sgaXMgYWx3YXlzIHZhbGlkLgogCSAqLwogI2lmZGVmIENPTkZJR19YODZfRVNQRklYNjQKIAl0ZXN0YiAkNCwoU1MtUklQKSglcnNwKQotCWpueiBpcnFfcmV0dXJuX2xkdAorCWpueiBuYXRpdmVfaXJxX3JldHVybl9sZHQKICNlbmRpZgogCi1pcnFfcmV0dXJuX2lyZXQ6Ci0JSU5URVJSVVBUX1JFVFVSTgotCV9BU01fRVhUQUJMRShpcnFfcmV0dXJuX2lyZXQsIGJhZF9pcmV0KQotCi0jaWZkZWYgQ09ORklHX1BBUkFWSVJUCi1FTlRSWShuYXRpdmVfaXJldCkKK25hdGl2ZV9pcnFfcmV0dXJuX2lyZXQ6CiAJaXJldHEKLQlfQVNNX0VYVEFCTEUobmF0aXZlX2lyZXQsIGJhZF9pcmV0KQotI2VuZGlmCisJX0FTTV9FWFRBQkxFKG5hdGl2ZV9pcnFfcmV0dXJuX2lyZXQsIGJhZF9pcmV0KQogCiAjaWZkZWYgQ09ORklHX1g4Nl9FU1BGSVg2NAotaXJxX3JldHVybl9sZHQ6CituYXRpdmVfaXJxX3JldHVybl9sZHQ6CiAJcHVzaHFfY2ZpICVyYXgKIAlwdXNocV9jZmkgJXJkaQogCVNXQVBHUwpAQCAtMTA5OCw3ICsxMDk1LDcgQEAKIAlTV0FQR1MKIAltb3ZxICVyYXgsJXJzcAogCXBvcHFfY2ZpICVyYXgKLQlqbXAgaXJxX3JldHVybl9pcmV0CisJam1wIG5hdGl2ZV9pcnFfcmV0dXJuX2lyZXQKICNlbmRpZgogCiAJLnNlY3Rpb24gLmZpeHVwLCJheCIKQEAgLTExODQsMTMgKzExODEsOCBAQAogCWNtcGwgJF9fS0VSTkVMX0NTLENTKCVyZGkpCiAJam5lIGRvX2RvdWJsZV9mYXVsdAogCW1vdnEgUklQKCVyZGkpLCVyYXgKLQljbXBxICRpcnFfcmV0dXJuX2lyZXQsJXJheAotI2lmZGVmIENPTkZJR19QQVJBVklSVAotCWplIDFmCi0JY21wcSAkbmF0aXZlX2lyZXQsJXJheAotI2VuZGlmCisJY21wcSAkbmF0aXZlX2lycV9yZXR1cm5faXJldCwlcmF4CiAJam5lIGRvX2RvdWJsZV9mYXVsdAkJLyogVGhpcyBzaG91bGRuJ3QgaGFwcGVuLi4uICovCi0xOgogCW1vdnEgUEVSX0NQVV9WQVIoa2VybmVsX3N0YWNrKSwlcmF4CiAJc3VicSAkKDYqOC1LRVJORUxfU1RBQ0tfT0ZGU0VUKSwlcmF4CS8qIFJlc2V0IHRvIG9yaWdpbmFsIHN0YWNrICovCiAJbW92cSAlcmF4LFJTUCglcmRpKQpAQCAtMTY1OCw3ICsxNjUwLDcgQEAKICAqLwogZXJyb3Jfa2VybmVsc3BhY2U6CiAJaW5jbCAlZWJ4Ci0JbGVhcSBpcnFfcmV0dXJuX2lyZXQoJXJpcCksJXJjeAorCWxlYXEgbmF0aXZlX2lycV9yZXR1cm5faXJldCglcmlwKSwlcmN4CiAJY21wcSAlcmN4LFJJUCs4KCVyc3ApCiAJamUgZXJyb3Jfc3dhcGdzCiAJbW92bCAlZWN4LCVlYXgJLyogemVybyBleHRlbmQgKi8KZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC9wYXJhdmlydF9wYXRjaF82NC5jIGIvYXJjaC94ODYva2VybmVsL3BhcmF2aXJ0X3BhdGNoXzY0LmMKaW5kZXggM2YwOGYzNC4uYTFkYTY3MyAxMDA2NDQKLS0tIGEvYXJjaC94ODYva2VybmVsL3BhcmF2aXJ0X3BhdGNoXzY0LmMKKysrIGIvYXJjaC94ODYva2VybmVsL3BhcmF2aXJ0X3BhdGNoXzY0LmMKQEAgLTYsNyArNiw2IEBACiBERUZfTkFUSVZFKHB2X2lycV9vcHMsIGlycV9lbmFibGUsICJzdGkiKTsKIERFRl9OQVRJVkUocHZfaXJxX29wcywgcmVzdG9yZV9mbCwgInB1c2hxICVyZGk7IHBvcGZxIik7CiBERUZfTkFUSVZFKHB2X2lycV9vcHMsIHNhdmVfZmwsICJwdXNoZnE7IHBvcHEgJXJheCIpOwotREVGX05BVElWRShwdl9jcHVfb3BzLCBpcmV0LCAiaXJldHEiKTsKIERFRl9OQVRJVkUocHZfbW11X29wcywgcmVhZF9jcjIsICJtb3ZxICVjcjIsICVyYXgiKTsKIERFRl9OQVRJVkUocHZfbW11X29wcywgcmVhZF9jcjMsICJtb3ZxICVjcjMsICVyYXgiKTsKIERFRl9OQVRJVkUocHZfbW11X29wcywgd3JpdGVfY3IzLCAibW92cSAlcmRpLCAlY3IzIik7CkBAIC01MCw3ICs0OSw2IEBACiAJCVBBVENIX1NJVEUocHZfaXJxX29wcywgc2F2ZV9mbCk7CiAJCVBBVENIX1NJVEUocHZfaXJxX29wcywgaXJxX2VuYWJsZSk7CiAJCVBBVENIX1NJVEUocHZfaXJxX29wcywgaXJxX2Rpc2FibGUpOwotCQlQQVRDSF9TSVRFKHB2X2NwdV9vcHMsIGlyZXQpOwogCQlQQVRDSF9TSVRFKHB2X2NwdV9vcHMsIGlycV9lbmFibGVfc3lzZXhpdCk7CiAJCVBBVENIX1NJVEUocHZfY3B1X29wcywgdXNlcmdzX3N5c3JldDMyKTsKIAkJUEFUQ0hfU0lURShwdl9jcHVfb3BzLCB1c2VyZ3Nfc3lzcmV0NjQpOwo=
|
30
Patches/Linux_CVEs/CVE-2014-9322/ANY/0008.patch
Normal file
30
Patches/Linux_CVEs/CVE-2014-9322/ANY/0008.patch
Normal file
@ -0,0 +1,30 @@
|
||||
diff --git a/arch/x86/kernel/espfix_64.c b/arch/x86/kernel/espfix_64.c
|
||||
index 6afbb16..94d857f 100644
|
||||
--- a/arch/x86/kernel/espfix_64.c
|
||||
+++ b/arch/x86/kernel/espfix_64.c
|
||||
@@ -175,7 +175,7 @@
|
||||
if (!pud_present(pud)) {
|
||||
pmd_p = (pmd_t *)__get_free_page(PGALLOC_GFP);
|
||||
pud = __pud(__pa(pmd_p) | (PGTABLE_PROT & ptemask));
|
||||
- paravirt_alloc_pud(&init_mm, __pa(pmd_p) >> PAGE_SHIFT);
|
||||
+ paravirt_alloc_pmd(&init_mm, __pa(pmd_p) >> PAGE_SHIFT);
|
||||
for (n = 0; n < ESPFIX_PUD_CLONES; n++)
|
||||
set_pud(&pud_p[n], pud);
|
||||
}
|
||||
@@ -185,7 +185,7 @@
|
||||
if (!pmd_present(pmd)) {
|
||||
pte_p = (pte_t *)__get_free_page(PGALLOC_GFP);
|
||||
pmd = __pmd(__pa(pte_p) | (PGTABLE_PROT & ptemask));
|
||||
- paravirt_alloc_pmd(&init_mm, __pa(pte_p) >> PAGE_SHIFT);
|
||||
+ paravirt_alloc_pte(&init_mm, __pa(pte_p) >> PAGE_SHIFT);
|
||||
for (n = 0; n < ESPFIX_PMD_CLONES; n++)
|
||||
set_pmd(&pmd_p[n], pmd);
|
||||
}
|
||||
@@ -193,7 +193,6 @@
|
||||
pte_p = pte_offset_kernel(&pmd, addr);
|
||||
stack_page = (void *)__get_free_page(GFP_KERNEL);
|
||||
pte = __pte(__pa(stack_page) | (__PAGE_KERNEL_RO & ptemask));
|
||||
- paravirt_alloc_pte(&init_mm, __pa(stack_page) >> PAGE_SHIFT);
|
||||
for (n = 0; n < ESPFIX_PTE_CLONES; n++)
|
||||
set_pte(&pte_p[n*PTE_STRIDE], pte);
|
||||
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0008.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0008.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC9lc3BmaXhfNjQuYyBiL2FyY2gveDg2L2tlcm5lbC9lc3BmaXhfNjQuYwppbmRleCA2YWZiYjE2Li45NGQ4NTdmIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9rZXJuZWwvZXNwZml4XzY0LmMKKysrIGIvYXJjaC94ODYva2VybmVsL2VzcGZpeF82NC5jCkBAIC0xNzUsNyArMTc1LDcgQEAKIAlpZiAoIXB1ZF9wcmVzZW50KHB1ZCkpIHsKIAkJcG1kX3AgPSAocG1kX3QgKilfX2dldF9mcmVlX3BhZ2UoUEdBTExPQ19HRlApOwogCQlwdWQgPSBfX3B1ZChfX3BhKHBtZF9wKSB8IChQR1RBQkxFX1BST1QgJiBwdGVtYXNrKSk7Ci0JCXBhcmF2aXJ0X2FsbG9jX3B1ZCgmaW5pdF9tbSwgX19wYShwbWRfcCkgPj4gUEFHRV9TSElGVCk7CisJCXBhcmF2aXJ0X2FsbG9jX3BtZCgmaW5pdF9tbSwgX19wYShwbWRfcCkgPj4gUEFHRV9TSElGVCk7CiAJCWZvciAobiA9IDA7IG4gPCBFU1BGSVhfUFVEX0NMT05FUzsgbisrKQogCQkJc2V0X3B1ZCgmcHVkX3Bbbl0sIHB1ZCk7CiAJfQpAQCAtMTg1LDcgKzE4NSw3IEBACiAJaWYgKCFwbWRfcHJlc2VudChwbWQpKSB7CiAJCXB0ZV9wID0gKHB0ZV90ICopX19nZXRfZnJlZV9wYWdlKFBHQUxMT0NfR0ZQKTsKIAkJcG1kID0gX19wbWQoX19wYShwdGVfcCkgfCAoUEdUQUJMRV9QUk9UICYgcHRlbWFzaykpOwotCQlwYXJhdmlydF9hbGxvY19wbWQoJmluaXRfbW0sIF9fcGEocHRlX3ApID4+IFBBR0VfU0hJRlQpOworCQlwYXJhdmlydF9hbGxvY19wdGUoJmluaXRfbW0sIF9fcGEocHRlX3ApID4+IFBBR0VfU0hJRlQpOwogCQlmb3IgKG4gPSAwOyBuIDwgRVNQRklYX1BNRF9DTE9ORVM7IG4rKykKIAkJCXNldF9wbWQoJnBtZF9wW25dLCBwbWQpOwogCX0KQEAgLTE5Myw3ICsxOTMsNiBAQAogCXB0ZV9wID0gcHRlX29mZnNldF9rZXJuZWwoJnBtZCwgYWRkcik7CiAJc3RhY2tfcGFnZSA9ICh2b2lkICopX19nZXRfZnJlZV9wYWdlKEdGUF9LRVJORUwpOwogCXB0ZSA9IF9fcHRlKF9fcGEoc3RhY2tfcGFnZSkgfCAoX19QQUdFX0tFUk5FTF9STyAmIHB0ZW1hc2spKTsKLQlwYXJhdmlydF9hbGxvY19wdGUoJmluaXRfbW0sIF9fcGEoc3RhY2tfcGFnZSkgPj4gUEFHRV9TSElGVCk7CiAJZm9yIChuID0gMDsgbiA8IEVTUEZJWF9QVEVfQ0xPTkVTOyBuKyspCiAJCXNldF9wdGUoJnB0ZV9wW24qUFRFX1NUUklERV0sIHB0ZSk7CiAK
|
94
Patches/Linux_CVEs/CVE-2014-9322/ANY/0009.patch
Normal file
94
Patches/Linux_CVEs/CVE-2014-9322/ANY/0009.patch
Normal file
@ -0,0 +1,94 @@
|
||||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
|
||||
index db230f8..1a454d0 100644
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -1068,6 +1068,7 @@
|
||||
jnz native_irq_return_ldt
|
||||
#endif
|
||||
|
||||
+.global native_irq_return_iret
|
||||
native_irq_return_iret:
|
||||
iretq
|
||||
_ASM_EXTABLE(native_irq_return_iret, bad_iret)
|
||||
@@ -1164,37 +1165,6 @@
|
||||
CFI_ENDPROC
|
||||
END(common_interrupt)
|
||||
|
||||
- /*
|
||||
- * If IRET takes a fault on the espfix stack, then we
|
||||
- * end up promoting it to a doublefault. In that case,
|
||||
- * modify the stack to make it look like we just entered
|
||||
- * the #GP handler from user space, similar to bad_iret.
|
||||
- */
|
||||
-#ifdef CONFIG_X86_ESPFIX64
|
||||
- ALIGN
|
||||
-__do_double_fault:
|
||||
- XCPT_FRAME 1 RDI+8
|
||||
- movq RSP(%rdi),%rax /* Trap on the espfix stack? */
|
||||
- sarq $PGDIR_SHIFT,%rax
|
||||
- cmpl $ESPFIX_PGD_ENTRY,%eax
|
||||
- jne do_double_fault /* No, just deliver the fault */
|
||||
- cmpl $__KERNEL_CS,CS(%rdi)
|
||||
- jne do_double_fault
|
||||
- movq RIP(%rdi),%rax
|
||||
- cmpq $native_irq_return_iret,%rax
|
||||
- jne do_double_fault /* This shouldn't happen... */
|
||||
- movq PER_CPU_VAR(kernel_stack),%rax
|
||||
- subq $(6*8-KERNEL_STACK_OFFSET),%rax /* Reset to original stack */
|
||||
- movq %rax,RSP(%rdi)
|
||||
- movq $0,(%rax) /* Missing (lost) #GP error code */
|
||||
- movq $general_protection,RIP(%rdi)
|
||||
- retq
|
||||
- CFI_ENDPROC
|
||||
-END(__do_double_fault)
|
||||
-#else
|
||||
-# define __do_double_fault do_double_fault
|
||||
-#endif
|
||||
-
|
||||
/*
|
||||
* End of kprobes section
|
||||
*/
|
||||
@@ -1363,7 +1333,7 @@
|
||||
zeroentry bounds do_bounds
|
||||
zeroentry invalid_op do_invalid_op
|
||||
zeroentry device_not_available do_device_not_available
|
||||
-paranoiderrorentry double_fault __do_double_fault
|
||||
+paranoiderrorentry double_fault do_double_fault
|
||||
zeroentry coprocessor_segment_overrun do_coprocessor_segment_overrun
|
||||
errorentry invalid_TSS do_invalid_TSS
|
||||
errorentry segment_not_present do_segment_not_present
|
||||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
|
||||
index 772e2a8..74e0801 100644
|
||||
--- a/arch/x86/kernel/traps.c
|
||||
+++ b/arch/x86/kernel/traps.c
|
||||
@@ -247,6 +247,30 @@
|
||||
static const char str[] = "double fault";
|
||||
struct task_struct *tsk = current;
|
||||
|
||||
+#ifdef CONFIG_X86_ESPFIX64
|
||||
+ extern unsigned char native_irq_return_iret[];
|
||||
+
|
||||
+ /*
|
||||
+ * If IRET takes a non-IST fault on the espfix64 stack, then we
|
||||
+ * end up promoting it to a doublefault. In that case, modify
|
||||
+ * the stack to make it look like we just entered the #GP
|
||||
+ * handler from user space, similar to bad_iret.
|
||||
+ */
|
||||
+ if (((long)regs->sp >> PGDIR_SHIFT) == ESPFIX_PGD_ENTRY &&
|
||||
+ regs->cs == __KERNEL_CS &&
|
||||
+ regs->ip == (unsigned long)native_irq_return_iret)
|
||||
+ {
|
||||
+ struct pt_regs *normal_regs = task_pt_regs(current);
|
||||
+
|
||||
+ /* Fake a #GP(0) from userspace. */
|
||||
+ memmove(&normal_regs->ip, (void *)regs->sp, 5*8);
|
||||
+ normal_regs->orig_ax = 0; /* Missing (lost) #GP error code */
|
||||
+ regs->ip = (unsigned long)general_protection;
|
||||
+ regs->sp = (unsigned long)&normal_regs->orig_ax;
|
||||
+ return;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
exception_enter();
|
||||
/* Return not checked because double check cannot be ignored */
|
||||
notify_die(DIE_TRAP, str, regs, error_code, X86_TRAP_DF, SIGSEGV);
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0009.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0009.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC9lbnRyeV82NC5TIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKaW5kZXggZGIyMzBmOC4uMWE0NTRkMCAxMDA2NDQKLS0tIGEvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKKysrIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKQEAgLTEwNjgsNiArMTA2OCw3IEBACiAJam56IG5hdGl2ZV9pcnFfcmV0dXJuX2xkdAogI2VuZGlmCiAKKy5nbG9iYWwgbmF0aXZlX2lycV9yZXR1cm5faXJldAogbmF0aXZlX2lycV9yZXR1cm5faXJldDoKIAlpcmV0cQogCV9BU01fRVhUQUJMRShuYXRpdmVfaXJxX3JldHVybl9pcmV0LCBiYWRfaXJldCkKQEAgLTExNjQsMzcgKzExNjUsNiBAQAogCUNGSV9FTkRQUk9DCiBFTkQoY29tbW9uX2ludGVycnVwdCkKIAotCS8qCi0JICogSWYgSVJFVCB0YWtlcyBhIGZhdWx0IG9uIHRoZSBlc3BmaXggc3RhY2ssIHRoZW4gd2UKLQkgKiBlbmQgdXAgcHJvbW90aW5nIGl0IHRvIGEgZG91YmxlZmF1bHQuICBJbiB0aGF0IGNhc2UsCi0JICogbW9kaWZ5IHRoZSBzdGFjayB0byBtYWtlIGl0IGxvb2sgbGlrZSB3ZSBqdXN0IGVudGVyZWQKLQkgKiB0aGUgI0dQIGhhbmRsZXIgZnJvbSB1c2VyIHNwYWNlLCBzaW1pbGFyIHRvIGJhZF9pcmV0LgotCSAqLwotI2lmZGVmIENPTkZJR19YODZfRVNQRklYNjQKLQlBTElHTgotX19kb19kb3VibGVfZmF1bHQ6Ci0JWENQVF9GUkFNRSAxIFJESSs4Ci0JbW92cSBSU1AoJXJkaSksJXJheAkJLyogVHJhcCBvbiB0aGUgZXNwZml4IHN0YWNrPyAqLwotCXNhcnEgJFBHRElSX1NISUZULCVyYXgKLQljbXBsICRFU1BGSVhfUEdEX0VOVFJZLCVlYXgKLQlqbmUgZG9fZG91YmxlX2ZhdWx0CQkvKiBObywganVzdCBkZWxpdmVyIHRoZSBmYXVsdCAqLwotCWNtcGwgJF9fS0VSTkVMX0NTLENTKCVyZGkpCi0Jam5lIGRvX2RvdWJsZV9mYXVsdAotCW1vdnEgUklQKCVyZGkpLCVyYXgKLQljbXBxICRuYXRpdmVfaXJxX3JldHVybl9pcmV0LCVyYXgKLQlqbmUgZG9fZG91YmxlX2ZhdWx0CQkvKiBUaGlzIHNob3VsZG4ndCBoYXBwZW4uLi4gKi8KLQltb3ZxIFBFUl9DUFVfVkFSKGtlcm5lbF9zdGFjayksJXJheAotCXN1YnEgJCg2KjgtS0VSTkVMX1NUQUNLX09GRlNFVCksJXJheAkvKiBSZXNldCB0byBvcmlnaW5hbCBzdGFjayAqLwotCW1vdnEgJXJheCxSU1AoJXJkaSkKLQltb3ZxICQwLCglcmF4KQkJCS8qIE1pc3NpbmcgKGxvc3QpICNHUCBlcnJvciBjb2RlICovCi0JbW92cSAkZ2VuZXJhbF9wcm90ZWN0aW9uLFJJUCglcmRpKQotCXJldHEKLQlDRklfRU5EUFJPQwotRU5EKF9fZG9fZG91YmxlX2ZhdWx0KQotI2Vsc2UKLSMgZGVmaW5lIF9fZG9fZG91YmxlX2ZhdWx0IGRvX2RvdWJsZV9mYXVsdAotI2VuZGlmCi0KIC8qCiAgKiBFbmQgb2Yga3Byb2JlcyBzZWN0aW9uCiAgKi8KQEAgLTEzNjMsNyArMTMzMyw3IEBACiB6ZXJvZW50cnkgYm91bmRzIGRvX2JvdW5kcwogemVyb2VudHJ5IGludmFsaWRfb3AgZG9faW52YWxpZF9vcAogemVyb2VudHJ5IGRldmljZV9ub3RfYXZhaWxhYmxlIGRvX2RldmljZV9ub3RfYXZhaWxhYmxlCi1wYXJhbm9pZGVycm9yZW50cnkgZG91YmxlX2ZhdWx0IF9fZG9fZG91YmxlX2ZhdWx0CitwYXJhbm9pZGVycm9yZW50cnkgZG91YmxlX2ZhdWx0IGRvX2RvdWJsZV9mYXVsdAogemVyb2VudHJ5IGNvcHJvY2Vzc29yX3NlZ21lbnRfb3ZlcnJ1biBkb19jb3Byb2Nlc3Nvcl9zZWdtZW50X292ZXJydW4KIGVycm9yZW50cnkgaW52YWxpZF9UU1MgZG9faW52YWxpZF9UU1MKIGVycm9yZW50cnkgc2VnbWVudF9ub3RfcHJlc2VudCBkb19zZWdtZW50X25vdF9wcmVzZW50CmRpZmYgLS1naXQgYS9hcmNoL3g4Ni9rZXJuZWwvdHJhcHMuYyBiL2FyY2gveDg2L2tlcm5lbC90cmFwcy5jCmluZGV4IDc3MmUyYTguLjc0ZTA4MDEgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2tlcm5lbC90cmFwcy5jCisrKyBiL2FyY2gveDg2L2tlcm5lbC90cmFwcy5jCkBAIC0yNDcsNiArMjQ3LDMwIEBACiAJc3RhdGljIGNvbnN0IGNoYXIgc3RyW10gPSAiZG91YmxlIGZhdWx0IjsKIAlzdHJ1Y3QgdGFza19zdHJ1Y3QgKnRzayA9IGN1cnJlbnQ7CiAKKyNpZmRlZiBDT05GSUdfWDg2X0VTUEZJWDY0CisJZXh0ZXJuIHVuc2lnbmVkIGNoYXIgbmF0aXZlX2lycV9yZXR1cm5faXJldFtdOworCisJLyoKKwkgKiBJZiBJUkVUIHRha2VzIGEgbm9uLUlTVCBmYXVsdCBvbiB0aGUgZXNwZml4NjQgc3RhY2ssIHRoZW4gd2UKKwkgKiBlbmQgdXAgcHJvbW90aW5nIGl0IHRvIGEgZG91YmxlZmF1bHQuICBJbiB0aGF0IGNhc2UsIG1vZGlmeQorCSAqIHRoZSBzdGFjayB0byBtYWtlIGl0IGxvb2sgbGlrZSB3ZSBqdXN0IGVudGVyZWQgdGhlICNHUAorCSAqIGhhbmRsZXIgZnJvbSB1c2VyIHNwYWNlLCBzaW1pbGFyIHRvIGJhZF9pcmV0LgorCSAqLworCWlmICgoKGxvbmcpcmVncy0+c3AgPj4gUEdESVJfU0hJRlQpID09IEVTUEZJWF9QR0RfRU5UUlkgJiYKKwkJcmVncy0+Y3MgPT0gX19LRVJORUxfQ1MgJiYKKwkJcmVncy0+aXAgPT0gKHVuc2lnbmVkIGxvbmcpbmF0aXZlX2lycV9yZXR1cm5faXJldCkKKwl7CisJCXN0cnVjdCBwdF9yZWdzICpub3JtYWxfcmVncyA9IHRhc2tfcHRfcmVncyhjdXJyZW50KTsKKworCQkvKiBGYWtlIGEgI0dQKDApIGZyb20gdXNlcnNwYWNlLiAqLworCQltZW1tb3ZlKCZub3JtYWxfcmVncy0+aXAsICh2b2lkICopcmVncy0+c3AsIDUqOCk7CisJCW5vcm1hbF9yZWdzLT5vcmlnX2F4ID0gMDsgIC8qIE1pc3NpbmcgKGxvc3QpICNHUCBlcnJvciBjb2RlICovCisJCXJlZ3MtPmlwID0gKHVuc2lnbmVkIGxvbmcpZ2VuZXJhbF9wcm90ZWN0aW9uOworCQlyZWdzLT5zcCA9ICh1bnNpZ25lZCBsb25nKSZub3JtYWxfcmVncy0+b3JpZ19heDsKKwkJcmV0dXJuOworCX0KKyNlbmRpZgorCiAJZXhjZXB0aW9uX2VudGVyKCk7CiAJLyogUmV0dXJuIG5vdCBjaGVja2VkIGJlY2F1c2UgZG91YmxlIGNoZWNrIGNhbm5vdCBiZSBpZ25vcmVkICovCiAJbm90aWZ5X2RpZShESUVfVFJBUCwgc3RyLCByZWdzLCBlcnJvcl9jb2RlLCBYODZfVFJBUF9ERiwgU0lHU0VHVik7Cg==
|
101
Patches/Linux_CVEs/CVE-2014-9322/ANY/0010.patch
Normal file
101
Patches/Linux_CVEs/CVE-2014-9322/ANY/0010.patch
Normal file
@ -0,0 +1,101 @@
|
||||
diff --git a/arch/x86/include/asm/page_32_types.h b/arch/x86/include/asm/page_32_types.h
|
||||
index ef17af0..4376b45 100644
|
||||
--- a/arch/x86/include/asm/page_32_types.h
|
||||
+++ b/arch/x86/include/asm/page_32_types.h
|
||||
@@ -18,7 +18,6 @@
|
||||
#define THREAD_SIZE_ORDER 1
|
||||
#define THREAD_SIZE (PAGE_SIZE << THREAD_SIZE_ORDER)
|
||||
|
||||
-#define STACKFAULT_STACK 0
|
||||
#define DOUBLEFAULT_STACK 1
|
||||
#define NMI_STACK 0
|
||||
#define DEBUG_STACK 0
|
||||
diff --git a/arch/x86/include/asm/page_64_types.h b/arch/x86/include/asm/page_64_types.h
|
||||
index 6c896fb..970f309 100644
|
||||
--- a/arch/x86/include/asm/page_64_types.h
|
||||
+++ b/arch/x86/include/asm/page_64_types.h
|
||||
@@ -14,12 +14,11 @@
|
||||
#define IRQ_STACK_ORDER 2
|
||||
#define IRQ_STACK_SIZE (PAGE_SIZE << IRQ_STACK_ORDER)
|
||||
|
||||
-#define STACKFAULT_STACK 1
|
||||
-#define DOUBLEFAULT_STACK 2
|
||||
-#define NMI_STACK 3
|
||||
-#define DEBUG_STACK 4
|
||||
-#define MCE_STACK 5
|
||||
-#define N_EXCEPTION_STACKS 5 /* hw limit: 7 */
|
||||
+#define DOUBLEFAULT_STACK 1
|
||||
+#define NMI_STACK 2
|
||||
+#define DEBUG_STACK 3
|
||||
+#define MCE_STACK 4
|
||||
+#define N_EXCEPTION_STACKS 4 /* hw limit: 7 */
|
||||
|
||||
#define PUD_PAGE_SIZE (_AC(1, UL) << PUD_SHIFT)
|
||||
#define PUD_PAGE_MASK (~(PUD_PAGE_SIZE-1))
|
||||
diff --git a/arch/x86/kernel/dumpstack_64.c b/arch/x86/kernel/dumpstack_64.c
|
||||
index addb207..66e274a 100644
|
||||
--- a/arch/x86/kernel/dumpstack_64.c
|
||||
+++ b/arch/x86/kernel/dumpstack_64.c
|
||||
@@ -24,7 +24,6 @@
|
||||
[ DEBUG_STACK-1 ] = "#DB",
|
||||
[ NMI_STACK-1 ] = "NMI",
|
||||
[ DOUBLEFAULT_STACK-1 ] = "#DF",
|
||||
- [ STACKFAULT_STACK-1 ] = "#SS",
|
||||
[ MCE_STACK-1 ] = "#MC",
|
||||
#if DEBUG_STKSZ > EXCEPTION_STKSZ
|
||||
[ N_EXCEPTION_STACKS ...
|
||||
diff --git a/arch/x86/kernel/entry_64.S b/arch/x86/kernel/entry_64.S
|
||||
index 1a454d0..50e5e59 100644
|
||||
--- a/arch/x86/kernel/entry_64.S
|
||||
+++ b/arch/x86/kernel/entry_64.S
|
||||
@@ -1503,7 +1503,7 @@
|
||||
|
||||
paranoidzeroentry_ist debug do_debug DEBUG_STACK
|
||||
paranoidzeroentry_ist int3 do_int3 DEBUG_STACK
|
||||
-paranoiderrorentry stack_segment do_stack_segment
|
||||
+errorentry stack_segment do_stack_segment
|
||||
#ifdef CONFIG_XEN
|
||||
zeroentry xen_debug do_debug
|
||||
zeroentry xen_int3 do_int3
|
||||
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c
|
||||
index 74e0801..00a2873 100644
|
||||
--- a/arch/x86/kernel/traps.c
|
||||
+++ b/arch/x86/kernel/traps.c
|
||||
@@ -220,28 +220,12 @@
|
||||
coprocessor_segment_overrun)
|
||||
DO_ERROR(X86_TRAP_TS, SIGSEGV, "invalid TSS", invalid_TSS)
|
||||
DO_ERROR(X86_TRAP_NP, SIGBUS, "segment not present", segment_not_present)
|
||||
-#ifdef CONFIG_X86_32
|
||||
DO_ERROR(X86_TRAP_SS, SIGBUS, "stack segment", stack_segment)
|
||||
-#endif
|
||||
DO_ERROR_INFO(X86_TRAP_AC, SIGBUS, "alignment check", alignment_check,
|
||||
BUS_ADRALN, 0)
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
/* Runs on IST stack */
|
||||
-dotraplinkage void do_stack_segment(struct pt_regs *regs, long error_code)
|
||||
-{
|
||||
- enum ctx_state prev_state;
|
||||
-
|
||||
- prev_state = exception_enter();
|
||||
- if (notify_die(DIE_TRAP, "stack segment", regs, error_code,
|
||||
- X86_TRAP_SS, SIGBUS) != NOTIFY_STOP) {
|
||||
- preempt_conditional_sti(regs);
|
||||
- do_trap(X86_TRAP_SS, SIGBUS, "stack segment", regs, error_code, NULL);
|
||||
- preempt_conditional_cli(regs);
|
||||
- }
|
||||
- exception_exit(prev_state);
|
||||
-}
|
||||
-
|
||||
dotraplinkage void do_double_fault(struct pt_regs *regs, long error_code)
|
||||
{
|
||||
static const char str[] = "double fault";
|
||||
@@ -769,7 +753,7 @@
|
||||
set_intr_gate(X86_TRAP_OLD_MF, &coprocessor_segment_overrun);
|
||||
set_intr_gate(X86_TRAP_TS, &invalid_TSS);
|
||||
set_intr_gate(X86_TRAP_NP, &segment_not_present);
|
||||
- set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
|
||||
+ set_intr_gate(X86_TRAP_SS, stack_segment);
|
||||
set_intr_gate(X86_TRAP_GP, &general_protection);
|
||||
set_intr_gate(X86_TRAP_SPURIOUS, &spurious_interrupt_bug);
|
||||
set_intr_gate(X86_TRAP_MF, &coprocessor_error);
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0010.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0010.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL3BhZ2VfMzJfdHlwZXMuaCBiL2FyY2gveDg2L2luY2x1ZGUvYXNtL3BhZ2VfMzJfdHlwZXMuaAppbmRleCBlZjE3YWYwLi40Mzc2YjQ1IDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9wYWdlXzMyX3R5cGVzLmgKKysrIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vcGFnZV8zMl90eXBlcy5oCkBAIC0xOCw3ICsxOCw2IEBACiAjZGVmaW5lIFRIUkVBRF9TSVpFX09SREVSCTEKICNkZWZpbmUgVEhSRUFEX1NJWkUJCShQQUdFX1NJWkUgPDwgVEhSRUFEX1NJWkVfT1JERVIpCiAKLSNkZWZpbmUgU1RBQ0tGQVVMVF9TVEFDSyAwCiAjZGVmaW5lIERPVUJMRUZBVUxUX1NUQUNLIDEKICNkZWZpbmUgTk1JX1NUQUNLIDAKICNkZWZpbmUgREVCVUdfU1RBQ0sgMApkaWZmIC0tZ2l0IGEvYXJjaC94ODYvaW5jbHVkZS9hc20vcGFnZV82NF90eXBlcy5oIGIvYXJjaC94ODYvaW5jbHVkZS9hc20vcGFnZV82NF90eXBlcy5oCmluZGV4IDZjODk2ZmIuLjk3MGYzMDkgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2luY2x1ZGUvYXNtL3BhZ2VfNjRfdHlwZXMuaAorKysgYi9hcmNoL3g4Ni9pbmNsdWRlL2FzbS9wYWdlXzY0X3R5cGVzLmgKQEAgLTE0LDEyICsxNCwxMSBAQAogI2RlZmluZSBJUlFfU1RBQ0tfT1JERVIgMgogI2RlZmluZSBJUlFfU1RBQ0tfU0laRSAoUEFHRV9TSVpFIDw8IElSUV9TVEFDS19PUkRFUikKIAotI2RlZmluZSBTVEFDS0ZBVUxUX1NUQUNLIDEKLSNkZWZpbmUgRE9VQkxFRkFVTFRfU1RBQ0sgMgotI2RlZmluZSBOTUlfU1RBQ0sgMwotI2RlZmluZSBERUJVR19TVEFDSyA0Ci0jZGVmaW5lIE1DRV9TVEFDSyA1Ci0jZGVmaW5lIE5fRVhDRVBUSU9OX1NUQUNLUyA1ICAvKiBodyBsaW1pdDogNyAqLworI2RlZmluZSBET1VCTEVGQVVMVF9TVEFDSyAxCisjZGVmaW5lIE5NSV9TVEFDSyAyCisjZGVmaW5lIERFQlVHX1NUQUNLIDMKKyNkZWZpbmUgTUNFX1NUQUNLIDQKKyNkZWZpbmUgTl9FWENFUFRJT05fU1RBQ0tTIDQgIC8qIGh3IGxpbWl0OiA3ICovCiAKICNkZWZpbmUgUFVEX1BBR0VfU0laRQkJKF9BQygxLCBVTCkgPDwgUFVEX1NISUZUKQogI2RlZmluZSBQVURfUEFHRV9NQVNLCQkofihQVURfUEFHRV9TSVpFLTEpKQpkaWZmIC0tZ2l0IGEvYXJjaC94ODYva2VybmVsL2R1bXBzdGFja182NC5jIGIvYXJjaC94ODYva2VybmVsL2R1bXBzdGFja182NC5jCmluZGV4IGFkZGIyMDcuLjY2ZTI3NGEgMTAwNjQ0Ci0tLSBhL2FyY2gveDg2L2tlcm5lbC9kdW1wc3RhY2tfNjQuYworKysgYi9hcmNoL3g4Ni9rZXJuZWwvZHVtcHN0YWNrXzY0LmMKQEAgLTI0LDcgKzI0LDYgQEAKIAkJWyBERUJVR19TVEFDSy0xCQkJXQk9ICIjREIiLAogCQlbIE5NSV9TVEFDSy0xCQkJXQk9ICJOTUkiLAogCQlbIERPVUJMRUZBVUxUX1NUQUNLLTEJCV0JPSAiI0RGIiwKLQkJWyBTVEFDS0ZBVUxUX1NUQUNLLTEJCV0JPSAiI1NTIiwKIAkJWyBNQ0VfU1RBQ0stMQkJCV0JPSAiI01DIiwKICNpZiBERUJVR19TVEtTWiA+IEVYQ0VQVElPTl9TVEtTWgogCQlbIE5fRVhDRVBUSU9OX1NUQUNLUyAuLi4KZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC9lbnRyeV82NC5TIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKaW5kZXggMWE0NTRkMC4uNTBlNWU1OSAxMDA2NDQKLS0tIGEvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKKysrIGIvYXJjaC94ODYva2VybmVsL2VudHJ5XzY0LlMKQEAgLTE1MDMsNyArMTUwMyw3IEBACiAKIHBhcmFub2lkemVyb2VudHJ5X2lzdCBkZWJ1ZyBkb19kZWJ1ZyBERUJVR19TVEFDSwogcGFyYW5vaWR6ZXJvZW50cnlfaXN0IGludDMgZG9faW50MyBERUJVR19TVEFDSwotcGFyYW5vaWRlcnJvcmVudHJ5IHN0YWNrX3NlZ21lbnQgZG9fc3RhY2tfc2VnbWVudAorZXJyb3JlbnRyeSBzdGFja19zZWdtZW50IGRvX3N0YWNrX3NlZ21lbnQKICNpZmRlZiBDT05GSUdfWEVOCiB6ZXJvZW50cnkgeGVuX2RlYnVnIGRvX2RlYnVnCiB6ZXJvZW50cnkgeGVuX2ludDMgZG9faW50MwpkaWZmIC0tZ2l0IGEvYXJjaC94ODYva2VybmVsL3RyYXBzLmMgYi9hcmNoL3g4Ni9rZXJuZWwvdHJhcHMuYwppbmRleCA3NGUwODAxLi4wMGEyODczIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9rZXJuZWwvdHJhcHMuYworKysgYi9hcmNoL3g4Ni9rZXJuZWwvdHJhcHMuYwpAQCAtMjIwLDI4ICsyMjAsMTIgQEAKIAkJY29wcm9jZXNzb3Jfc2VnbWVudF9vdmVycnVuKQogRE9fRVJST1IoWDg2X1RSQVBfVFMsIFNJR1NFR1YsICJpbnZhbGlkIFRTUyIsIGludmFsaWRfVFNTKQogRE9fRVJST1IoWDg2X1RSQVBfTlAsIFNJR0JVUywgInNlZ21lbnQgbm90IHByZXNlbnQiLCBzZWdtZW50X25vdF9wcmVzZW50KQotI2lmZGVmIENPTkZJR19YODZfMzIKIERPX0VSUk9SKFg4Nl9UUkFQX1NTLCBTSUdCVVMsICJzdGFjayBzZWdtZW50Iiwgc3RhY2tfc2VnbWVudCkKLSNlbmRpZgogRE9fRVJST1JfSU5GTyhYODZfVFJBUF9BQywgU0lHQlVTLCAiYWxpZ25tZW50IGNoZWNrIiwgYWxpZ25tZW50X2NoZWNrLAogCQlCVVNfQURSQUxOLCAwKQogCiAjaWZkZWYgQ09ORklHX1g4Nl82NAogLyogUnVucyBvbiBJU1Qgc3RhY2sgKi8KLWRvdHJhcGxpbmthZ2Ugdm9pZCBkb19zdGFja19zZWdtZW50KHN0cnVjdCBwdF9yZWdzICpyZWdzLCBsb25nIGVycm9yX2NvZGUpCi17Ci0JZW51bSBjdHhfc3RhdGUgcHJldl9zdGF0ZTsKLQotCXByZXZfc3RhdGUgPSBleGNlcHRpb25fZW50ZXIoKTsKLQlpZiAobm90aWZ5X2RpZShESUVfVFJBUCwgInN0YWNrIHNlZ21lbnQiLCByZWdzLCBlcnJvcl9jb2RlLAotCQkgICAgICAgWDg2X1RSQVBfU1MsIFNJR0JVUykgIT0gTk9USUZZX1NUT1ApIHsKLQkJcHJlZW1wdF9jb25kaXRpb25hbF9zdGkocmVncyk7Ci0JCWRvX3RyYXAoWDg2X1RSQVBfU1MsIFNJR0JVUywgInN0YWNrIHNlZ21lbnQiLCByZWdzLCBlcnJvcl9jb2RlLCBOVUxMKTsKLQkJcHJlZW1wdF9jb25kaXRpb25hbF9jbGkocmVncyk7Ci0JfQotCWV4Y2VwdGlvbl9leGl0KHByZXZfc3RhdGUpOwotfQotCiBkb3RyYXBsaW5rYWdlIHZvaWQgZG9fZG91YmxlX2ZhdWx0KHN0cnVjdCBwdF9yZWdzICpyZWdzLCBsb25nIGVycm9yX2NvZGUpCiB7CiAJc3RhdGljIGNvbnN0IGNoYXIgc3RyW10gPSAiZG91YmxlIGZhdWx0IjsKQEAgLTc2OSw3ICs3NTMsNyBAQAogCXNldF9pbnRyX2dhdGUoWDg2X1RSQVBfT0xEX01GLCAmY29wcm9jZXNzb3Jfc2VnbWVudF9vdmVycnVuKTsKIAlzZXRfaW50cl9nYXRlKFg4Nl9UUkFQX1RTLCAmaW52YWxpZF9UU1MpOwogCXNldF9pbnRyX2dhdGUoWDg2X1RSQVBfTlAsICZzZWdtZW50X25vdF9wcmVzZW50KTsKLQlzZXRfaW50cl9nYXRlX2lzdChYODZfVFJBUF9TUywgJnN0YWNrX3NlZ21lbnQsIFNUQUNLRkFVTFRfU1RBQ0spOworCXNldF9pbnRyX2dhdGUoWDg2X1RSQVBfU1MsIHN0YWNrX3NlZ21lbnQpOwogCXNldF9pbnRyX2dhdGUoWDg2X1RSQVBfR1AsICZnZW5lcmFsX3Byb3RlY3Rpb24pOwogCXNldF9pbnRyX2dhdGUoWDg2X1RSQVBfU1BVUklPVVMsICZzcHVyaW91c19pbnRlcnJ1cHRfYnVnKTsKIAlzZXRfaW50cl9nYXRlKFg4Nl9UUkFQX01GLCAmY29wcm9jZXNzb3JfZXJyb3IpOwo=
|
55
Patches/Linux_CVEs/CVE-2014-9322/ANY/0011.patch
Normal file
55
Patches/Linux_CVEs/CVE-2014-9322/ANY/0011.patch
Normal file
@ -0,0 +1,55 @@
|
||||
diff --git a/arch/x86/kernel/tls.c b/arch/x86/kernel/tls.c
|
||||
index f7fec09..e7650bd 100644
|
||||
--- a/arch/x86/kernel/tls.c
|
||||
+++ b/arch/x86/kernel/tls.c
|
||||
@@ -27,6 +27,21 @@
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
+static bool tls_desc_okay(const struct user_desc *info)
|
||||
+{
|
||||
+ if (LDT_empty(info))
|
||||
+ return true;
|
||||
+
|
||||
+ /*
|
||||
+ * espfix is required for 16-bit data segments, but espfix
|
||||
+ * only works for LDT segments.
|
||||
+ */
|
||||
+ if (!info->seg_32bit)
|
||||
+ return false;
|
||||
+
|
||||
+ return true;
|
||||
+}
|
||||
+
|
||||
static void set_tls_desc(struct task_struct *p, int idx,
|
||||
const struct user_desc *info, int n)
|
||||
{
|
||||
@@ -66,6 +81,9 @@
|
||||
if (copy_from_user(&info, u_info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
|
||||
+ if (!tls_desc_okay(&info))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
if (idx == -1)
|
||||
idx = info.entry_number;
|
||||
|
||||
@@ -192,6 +210,7 @@
|
||||
{
|
||||
struct user_desc infobuf[GDT_ENTRY_TLS_ENTRIES];
|
||||
const struct user_desc *info;
|
||||
+ int i;
|
||||
|
||||
if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
|
||||
(pos % sizeof(struct user_desc)) != 0 ||
|
||||
@@ -205,6 +224,10 @@
|
||||
else
|
||||
info = infobuf;
|
||||
|
||||
+ for (i = 0; i < count / sizeof(struct user_desc); i++)
|
||||
+ if (!tls_desc_okay(info + i))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
set_tls_desc(target,
|
||||
GDT_ENTRY_TLS_MIN + (pos / sizeof(struct user_desc)),
|
||||
info, count / sizeof(struct user_desc));
|
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0011.patch.base64
Normal file
1
Patches/Linux_CVEs/CVE-2014-9322/ANY/0011.patch.base64
Normal file
@ -0,0 +1 @@
|
||||
ZGlmZiAtLWdpdCBhL2FyY2gveDg2L2tlcm5lbC90bHMuYyBiL2FyY2gveDg2L2tlcm5lbC90bHMuYwppbmRleCBmN2ZlYzA5Li5lNzY1MGJkIDEwMDY0NAotLS0gYS9hcmNoL3g4Ni9rZXJuZWwvdGxzLmMKKysrIGIvYXJjaC94ODYva2VybmVsL3Rscy5jCkBAIC0yNyw2ICsyNywyMSBAQAogCXJldHVybiAtRVNSQ0g7CiB9CiAKK3N0YXRpYyBib29sIHRsc19kZXNjX29rYXkoY29uc3Qgc3RydWN0IHVzZXJfZGVzYyAqaW5mbykKK3sKKwlpZiAoTERUX2VtcHR5KGluZm8pKQorCQlyZXR1cm4gdHJ1ZTsKKworCS8qCisJICogZXNwZml4IGlzIHJlcXVpcmVkIGZvciAxNi1iaXQgZGF0YSBzZWdtZW50cywgYnV0IGVzcGZpeAorCSAqIG9ubHkgd29ya3MgZm9yIExEVCBzZWdtZW50cy4KKwkgKi8KKwlpZiAoIWluZm8tPnNlZ18zMmJpdCkKKwkJcmV0dXJuIGZhbHNlOworCisJcmV0dXJuIHRydWU7Cit9CisKIHN0YXRpYyB2b2lkIHNldF90bHNfZGVzYyhzdHJ1Y3QgdGFza19zdHJ1Y3QgKnAsIGludCBpZHgsCiAJCQkgY29uc3Qgc3RydWN0IHVzZXJfZGVzYyAqaW5mbywgaW50IG4pCiB7CkBAIC02Niw2ICs4MSw5IEBACiAJaWYgKGNvcHlfZnJvbV91c2VyKCZpbmZvLCB1X2luZm8sIHNpemVvZihpbmZvKSkpCiAJCXJldHVybiAtRUZBVUxUOwogCisJaWYgKCF0bHNfZGVzY19va2F5KCZpbmZvKSkKKwkJcmV0dXJuIC1FSU5WQUw7CisKIAlpZiAoaWR4ID09IC0xKQogCQlpZHggPSBpbmZvLmVudHJ5X251bWJlcjsKIApAQCAtMTkyLDYgKzIxMCw3IEBACiB7CiAJc3RydWN0IHVzZXJfZGVzYyBpbmZvYnVmW0dEVF9FTlRSWV9UTFNfRU5UUklFU107CiAJY29uc3Qgc3RydWN0IHVzZXJfZGVzYyAqaW5mbzsKKwlpbnQgaTsKIAogCWlmIChwb3MgPj0gR0RUX0VOVFJZX1RMU19FTlRSSUVTICogc2l6ZW9mKHN0cnVjdCB1c2VyX2Rlc2MpIHx8CiAJICAgIChwb3MgJSBzaXplb2Yoc3RydWN0IHVzZXJfZGVzYykpICE9IDAgfHwKQEAgLTIwNSw2ICsyMjQsMTAgQEAKIAllbHNlCiAJCWluZm8gPSBpbmZvYnVmOwogCisJZm9yIChpID0gMDsgaSA8IGNvdW50IC8gc2l6ZW9mKHN0cnVjdCB1c2VyX2Rlc2MpOyBpKyspCisJCWlmICghdGxzX2Rlc2Nfb2theShpbmZvICsgaSkpCisJCQlyZXR1cm4gLUVJTlZBTDsKKwogCXNldF90bHNfZGVzYyh0YXJnZXQsCiAJCSAgICAgR0RUX0VOVFJZX1RMU19NSU4gKyAocG9zIC8gc2l6ZW9mKHN0cnVjdCB1c2VyX2Rlc2MpKSwKIAkJICAgICBpbmZvLCBjb3VudCAvIHNpemVvZihzdHJ1Y3QgdXNlcl9kZXNjKSk7Cg==
|
@ -1,57 +0,0 @@
|
||||
From 212c4d33ca83e2144064fe9c2911607fbed5386f Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
||||
Subject: isofs: Fix infinite looping over CE entries
|
||||
|
||||
commit f54e18f1b831c92f6512d2eedb224cd63d607d3d upstream.
|
||||
|
||||
Rock Ridge extensions define so called Continuation Entries (CE) which
|
||||
define where is further space with Rock Ridge data. Corrupted isofs
|
||||
image can contain arbitrarily long chain of these, including a one
|
||||
containing loop and thus causing kernel to end in an infinite loop when
|
||||
traversing these entries.
|
||||
|
||||
Limit the traversal to 32 entries which should be more than enough space
|
||||
to store all the Rock Ridge data.
|
||||
|
||||
Reported-by: P J P <ppandit@redhat.com>
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
fs/isofs/rock.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
||||
index ee62cc0..26859de 100644
|
||||
--- a/fs/isofs/rock.c
|
||||
+++ b/fs/isofs/rock.c
|
||||
@@ -30,6 +30,7 @@ struct rock_state {
|
||||
int cont_size;
|
||||
int cont_extent;
|
||||
int cont_offset;
|
||||
+ int cont_loops;
|
||||
struct inode *inode;
|
||||
};
|
||||
|
||||
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
||||
rs->inode = inode;
|
||||
}
|
||||
|
||||
+/* Maximum number of Rock Ridge continuation entries */
|
||||
+#define RR_MAX_CE_ENTRIES 32
|
||||
+
|
||||
/*
|
||||
* Returns 0 if the caller should continue scanning, 1 if the scan must end
|
||||
* and -ve on error.
|
||||
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
|
||||
goto out;
|
||||
}
|
||||
ret = -EIO;
|
||||
+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
|
||||
+ goto out;
|
||||
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
||||
if (bh) {
|
||||
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From f54e18f1b831c92f6512d2eedb224cd63d607d3d Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
||||
Subject: [PATCH] isofs: Fix infinite looping over CE entries
|
||||
Subject: isofs: Fix infinite looping over CE entries
|
||||
|
||||
Rock Ridge extensions define so called Continuation Entries (CE) which
|
||||
define where is further space with Rock Ridge data. Corrupted isofs
|
||||
@ -20,7 +20,7 @@ Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
||||
index f488bbae541ac..bb63254ed8486 100644
|
||||
index f488bba..bb63254 100644
|
||||
--- a/fs/isofs/rock.c
|
||||
+++ b/fs/isofs/rock.c
|
||||
@@ -30,6 +30,7 @@ struct rock_state {
|
||||
@ -50,3 +50,6 @@ index f488bbae541ac..bb63254ed8486 100644
|
||||
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
||||
if (bh) {
|
||||
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,51 +0,0 @@
|
||||
From dc4a2f40de419c01b538c87f6bdfc15d574d9f7e Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 29 Dec 2014 09:39:01 -0500
|
||||
Subject: KEYS: close race between key lookup and freeing
|
||||
|
||||
commit a3a8784454692dd72e5d5d34dcdab17b4420e74c upstream.
|
||||
|
||||
When a key is being garbage collected, it's key->user would get put before
|
||||
the ->destroy() callback is called, where the key is removed from it's
|
||||
respective tracking structures.
|
||||
|
||||
This leaves a key hanging in a semi-invalid state which leaves a window open
|
||||
for a different task to try an access key->user. An example is
|
||||
find_keyring_by_name() which would dereference key->user for a key that is
|
||||
in the process of being garbage collected (where key->user was freed but
|
||||
->destroy() wasn't called yet - so it's still present in the linked list).
|
||||
|
||||
This would cause either a panic, or corrupt memory.
|
||||
|
||||
Fixes CVE-2014-9529.
|
||||
|
||||
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
[bwh: Backported to 3.2: adjust indentation]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
security/keys/gc.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/keys/gc.c b/security/keys/gc.c
|
||||
index bf4d8da..2e2395d 100644
|
||||
--- a/security/keys/gc.c
|
||||
+++ b/security/keys/gc.c
|
||||
@@ -186,12 +186,12 @@ static noinline void key_gc_unused_key(struct key *key)
|
||||
if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
|
||||
atomic_dec(&key->user->nikeys);
|
||||
|
||||
- key_user_put(key->user);
|
||||
-
|
||||
/* now throw away the key memory */
|
||||
if (key->type->destroy)
|
||||
key->type->destroy(key);
|
||||
|
||||
+ key_user_put(key->user);
|
||||
+
|
||||
kfree(key->description);
|
||||
|
||||
#ifdef KEY_DEBUGGING
|
||||
--
|
||||
cgit v1.1
|
||||
|
@ -1,7 +1,7 @@
|
||||
From a3a8784454692dd72e5d5d34dcdab17b4420e74c Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 29 Dec 2014 09:39:01 -0500
|
||||
Subject: [PATCH] KEYS: close race between key lookup and freeing
|
||||
Subject: KEYS: close race between key lookup and freeing
|
||||
|
||||
When a key is being garbage collected, it's key->user would get put before
|
||||
the ->destroy() callback is called, where the key is removed from it's
|
||||
@ -24,7 +24,7 @@ Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/keys/gc.c b/security/keys/gc.c
|
||||
index 9609a7f0faea2..c7952375ac532 100644
|
||||
index 9609a7f..c795237 100644
|
||||
--- a/security/keys/gc.c
|
||||
+++ b/security/keys/gc.c
|
||||
@@ -148,12 +148,12 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
|
||||
@ -42,3 +42,6 @@ index 9609a7f0faea2..c7952375ac532 100644
|
||||
kfree(key->description);
|
||||
|
||||
#ifdef KEY_DEBUGGING
|
||||
--
|
||||
cgit v1.1
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user