Merge A405FNXXS4CWB5
Change-Id: I50399ecfb64d74d3eb5fbab316aa2fd966cc53c9
diff --git a/Documentation/filesystems/cifs/winucase_convert.pl b/Documentation/filesystems/cifs/winucase_convert.pl
new file mode 100755
index 0000000..322a9c8
--- /dev/null
+++ b/Documentation/filesystems/cifs/winucase_convert.pl
@@ -0,0 +1,62 @@
+#!/usr/bin/perl -w
+#
+# winucase_convert.pl -- convert "Windows 8 Upper Case Mapping Table.txt" to
+# a two-level set of C arrays.
+#
+# Copyright 2013: Jeff Layton <jlayton@redhat.com>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+while(<>) {
+ next if (!/^0x(..)(..)\t0x(....)\t/);
+ $firstchar = hex($1);
+ $secondchar = hex($2);
+ $uppercase = hex($3);
+
+ $top[$firstchar][$secondchar] = $uppercase;
+}
+
+for ($i = 0; $i < 256; $i++) {
+ next if (!$top[$i]);
+
+ printf("static const wchar_t t2_%2.2x[256] = {", $i);
+ for ($j = 0; $j < 256; $j++) {
+ if (($j % 8) == 0) {
+ print "\n\t";
+ } else {
+ print " ";
+ }
+ printf("0x%4.4x,", $top[$i][$j] ? $top[$i][$j] : 0);
+ }
+ print "\n};\n\n";
+}
+
+printf("static const wchar_t *const toplevel[256] = {", $i);
+for ($i = 0; $i < 256; $i++) {
+ if (($i % 8) == 0) {
+ print "\n\t";
+ } elsif ($top[$i]) {
+ print " ";
+ } else {
+ print " ";
+ }
+
+ if ($top[$i]) {
+ printf("t2_%2.2x,", $i);
+ } else {
+ print "NULL,";
+ }
+}
+print "\n};\n\n";
diff --git a/arch/arm64/kernel/armv8_deprecated.c b/arch/arm64/kernel/armv8_deprecated.c
index 185ac13..baf2f2b 100755
--- a/arch/arm64/kernel/armv8_deprecated.c
+++ b/arch/arm64/kernel/armv8_deprecated.c
@@ -63,6 +63,7 @@
static LIST_HEAD(insn_emulation);
static int nr_insn_emulated __initdata;
static DEFINE_RAW_SPINLOCK(insn_emulation_lock);
+static DEFINE_MUTEX(insn_emulation_mutex);
static void register_emulation_hooks(struct insn_emulation_ops *ops)
{
@@ -208,10 +209,10 @@
loff_t *ppos)
{
int ret = 0;
- struct insn_emulation *insn = (struct insn_emulation *) table->data;
+ struct insn_emulation *insn = container_of(table->data, struct insn_emulation, current_mode);
enum insn_emulation_mode prev_mode = insn->current_mode;
- table->data = &insn->current_mode;
+ mutex_lock(&insn_emulation_mutex);
ret = proc_dointvec_minmax(table, write, buffer, lenp, ppos);
if (ret || !write || prev_mode == insn->current_mode)
@@ -224,7 +225,7 @@
update_insn_emulation_mode(insn, INSN_UNDEF);
}
ret:
- table->data = insn;
+ mutex_unlock(&insn_emulation_mutex);
return ret;
}
@@ -254,7 +255,7 @@
sysctl->maxlen = sizeof(int);
sysctl->procname = insn->ops->name;
- sysctl->data = insn;
+ sysctl->data = &insn->current_mode;
sysctl->extra1 = &insn->min;
sysctl->extra2 = &insn->max;
sysctl->proc_handler = emulation_proc_handler;
diff --git a/drivers/android/binder.c b/drivers/android/binder.c
index 66e7b98..7711d17 100755
--- a/drivers/android/binder.c
+++ b/drivers/android/binder.c
@@ -560,6 +560,7 @@
struct task_struct *tsk;
struct files_struct *files;
struct mutex files_lock;
+ const struct cred *cred;
struct hlist_node deferred_work_node;
int deferred_work;
bool is_dead;
@@ -1976,6 +1977,18 @@
}
ret = binder_inc_ref_olocked(ref, strong, target_list);
*rdata = ref->data;
+ if (ret && ref == new_ref) {
+ /*
+ * Cleanup the failed reference here as the target
+ * could now be dead and have already released its
+ * references by now. Calling on the new reference
+ * with strong=0 and a tmp_refs will not decrement
+ * the node. The new_ref gets kfree'd below.
+ */
+ binder_cleanup_ref_olocked(new_ref);
+ ref = NULL;
+ }
+
binder_proc_unlock(proc);
if (new_ref && ref != new_ref)
/*
@@ -2504,7 +2517,7 @@
ret = -EINVAL;
goto done;
}
- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
+ if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
ret = -EPERM;
goto done;
}
@@ -2550,7 +2563,7 @@
proc->pid, thread->pid, fp->handle);
return -EINVAL;
}
- if (security_binder_transfer_binder(proc->tsk, target_proc->tsk)) {
+ if (security_binder_transfer_binder(proc->cred, target_proc->cred)) {
ret = -EPERM;
goto done;
}
@@ -2634,7 +2647,7 @@
ret = -EBADF;
goto err_fget;
}
- ret = security_binder_transfer_file(proc->tsk, target_proc->tsk, file);
+ ret = security_binder_transfer_file(proc->cred, target_proc->cred, file);
if (ret < 0) {
ret = -EPERM;
goto err_security;
@@ -3134,8 +3147,14 @@
freecess_sync_binder_report(proc, target_proc, tr);
#endif
- if (security_binder_transaction(proc->tsk,
- target_proc->tsk) < 0) {
+ if (WARN_ON(proc == target_proc)) {
+ return_error = BR_FAILED_REPLY;
+ return_error_param = -EINVAL;
+ return_error_line = __LINE__;
+ goto err_invalid_target_handle;
+ }
+ if (security_binder_transaction(proc->cred,
+ target_proc->cred) < 0) {
return_error = BR_FAILED_REPLY;
return_error_param = -EPERM;
return_error_line = __LINE__;
@@ -3675,10 +3694,17 @@
struct binder_node *ctx_mgr_node;
mutex_lock(&context->context_mgr_node_lock);
ctx_mgr_node = context->binder_context_mgr_node;
- if (ctx_mgr_node)
+ if (ctx_mgr_node) {
+ if (ctx_mgr_node->proc == proc) {
+ binder_user_error("%d:%d context manager tried to acquire desc 0\n",
+ proc->pid, thread->pid);
+ mutex_unlock(&context->context_mgr_node_lock);
+ return -EINVAL;
+ }
ret = binder_inc_ref_for_node(
proc, ctx_mgr_node,
strong, NULL, &rdata);
+ }
mutex_unlock(&context->context_mgr_node_lock);
}
if (ret)
@@ -4273,7 +4299,7 @@
e->cmd = BR_OK;
ptr += sizeof(uint32_t);
- binder_stat_br(proc, thread, cmd);
+ binder_stat_br(proc, thread, e->cmd);
} break;
case BINDER_WORK_TRANSACTION_COMPLETE: {
binder_inner_proc_unlock(proc);
@@ -4667,6 +4693,7 @@
BUG_ON(!list_empty(&proc->delivered_death));
binder_alloc_deferred_release(&proc->alloc);
put_task_struct(proc->tsk);
+ put_cred(proc->cred);
binder_stats_deleted(BINDER_STAT_PROC);
kfree(proc);
}
@@ -4872,7 +4899,7 @@
ret = -EBUSY;
goto out;
}
- ret = security_binder_set_context_mgr(proc->tsk);
+ ret = security_binder_set_context_mgr(proc->cred);
if (ret < 0)
goto out;
if (uid_valid(context->binder_context_mgr_uid)) {
@@ -5201,6 +5228,7 @@
spin_lock_init(&proc->outer_lock);
get_task_struct(current->group_leader);
proc->tsk = current->group_leader;
+ proc->cred = get_cred(filp->f_cred);
mutex_init(&proc->files_lock);
INIT_LIST_HEAD(&proc->todo);
if (binder_supported_policy(current->policy)) {
diff --git a/drivers/crypto/fmp/fmp_fips_fops.c b/drivers/crypto/fmp/fmp_fips_fops.c
index 7375c40..6f2177b 100755
--- a/drivers/crypto/fmp/fmp_fips_fops.c
+++ b/drivers/crypto/fmp/fmp_fips_fops.c
@@ -461,7 +461,8 @@
if ((ses_ptr->cdata.init != 0) && (cop->len > PAGE_SIZE)) {
dev_err(fmp->dev, "Invalid input length. len = %d\n", cop->len);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unlock;
}
if (ses_ptr->cdata.init != 0) {
@@ -543,7 +544,8 @@
if (cop->len > PAGE_SIZE) {
dev_err(fmp->dev, "Invalid input length. len = %d\n", cop->len);
- return -EINVAL;
+ ret = -EINVAL;
+ goto out_unlock;
}
if (ses_ptr->cdata.init != 0) {
@@ -885,6 +887,7 @@
if (!info || !info->fmp) {
pr_err("%s: Invalid fmp info\n", __func__);
+ mutex_unlock(&fcr->sem);
return -ENODEV;
}
fmp = info->fmp;
diff --git a/drivers/input/Makefile b/drivers/input/Makefile
index 840891d..e3c0577 100755
--- a/drivers/input/Makefile
+++ b/drivers/input/Makefile
@@ -34,4 +34,3 @@
obj-$(CONFIG_INPUT_KEYRESET) += keyreset.o
obj-$(CONFIG_INPUT_KEYCOMBO) += keycombo.o
-
diff --git a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
index 56b1c9b..b7f7eb6 100755
--- a/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
+++ b/drivers/media/platform/exynos/mfc/s5p_mfc_mem.c
@@ -76,16 +76,17 @@
struct s5p_mfc_dev *dev = ctx->dev;
struct dma_buf *dma_buf;
int ret = 0;
+ int fd = handle->fd;
handle->ion_handle =
- ion_import_dma_buf(dev->mfc_ion_client, handle->fd);
+ ion_import_dma_buf(dev->mfc_ion_client, fd);
if (IS_ERR(handle->ion_handle)) {
mfc_err_ctx("Failed to import fd\n");
ret = PTR_ERR(handle->ion_handle);
goto import_dma_fail;
}
- dma_buf = dma_buf_get(handle->fd);
+ dma_buf = dma_buf_get(fd);
if (IS_ERR(dma_buf)) {
mfc_err_ctx("Faiiled to dma_buf_get (err %ld)\n", PTR_ERR(dma_buf));
ret = -EINVAL;
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
index 00584d7..d55b6d8 100755
--- a/drivers/net/ethernet/broadcom/Makefile
+++ b/drivers/net/ethernet/broadcom/Makefile
@@ -9,7 +9,6 @@
obj-$(CONFIG_CNIC) += cnic.o
obj-$(CONFIG_BNX2X) += bnx2x/
obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
-obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BGMAC) += bgmac.o
obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
obj-$(CONFIG_BNXT) += bnxt/
diff --git a/drivers/net/wireless/scsc/cm_if.c b/drivers/net/wireless/scsc/cm_if.c
index 9a95acc..0db4cd5 100755
--- a/drivers/net/wireless/scsc/cm_if.c
+++ b/drivers/net/wireless/scsc/cm_if.c
@@ -392,12 +392,15 @@
/* start/stop wlan service
* =======================
*/
-void slsi_sm_service_failed(struct slsi_dev *sdev, const char *reason)
+void slsi_sm_service_failed(struct slsi_dev *sdev, const char *reason, bool is_work)
{
int state;
mutex_lock(&slsi_start_mutex);
+ if (is_work)
+ complete_all(&sdev->service_fail_started_indication);
+
state = atomic_read(&sdev->cm_if.cm_if_state);
if (state != SCSC_WIFI_CM_IF_STATE_STARTED &&
state != SCSC_WIFI_CM_IF_STATE_STOPPING) {
@@ -418,6 +421,9 @@
sdev->fail_reported = true;
}
+ if (is_work)
+ reinit_completion(&sdev->service_fail_started_indication);
+
mutex_unlock(&slsi_start_mutex);
}
@@ -651,7 +657,7 @@
snprintf(reason, sizeof(reason), "WLAN scsc_mx_service_stop failed");
mutex_unlock(&slsi_start_mutex);
- slsi_sm_service_failed(sdev, reason);
+ slsi_sm_service_failed(sdev, reason, false);
mutex_lock(&slsi_start_mutex);
__slsi_sm_wlan_service_stop_wait_locked(sdev);
diff --git a/drivers/net/wireless/scsc/dev.c b/drivers/net/wireless/scsc/dev.c
index 2511eac..232344a 100755
--- a/drivers/net/wireless/scsc/dev.c
+++ b/drivers/net/wireless/scsc/dev.c
@@ -330,6 +330,7 @@
init_completion(&sdev->recovery_remove_completion);
init_completion(&sdev->recovery_stop_completion);
init_completion(&sdev->recovery_completed);
+ init_completion(&sdev->service_fail_started_indication);
sdev->recovery_status = 0;
sdev->term_udi_users = &term_udi_users;
@@ -456,6 +457,7 @@
#endif
#endif
}
+ INIT_WORK(&sdev->trigger_wlan_fail_work, slsi_trigger_service_failure);
return sdev;
#if CONFIG_SCSC_WLAN_MAX_INTERFACES >= 4
@@ -518,6 +520,7 @@
complete_all(&sdev->recovery_remove_completion);
complete_all(&sdev->recovery_stop_completion);
complete_all(&sdev->recovery_completed);
+ complete_all(&sdev->service_fail_started_indication);
SLSI_DBG2(sdev, SLSI_INIT_DEINIT, "Unregister inetaddr_notifier\n");
unregister_inetaddr_notifier(&sdev->inetaddr_notifier);
diff --git a/drivers/net/wireless/scsc/dev.h b/drivers/net/wireless/scsc/dev.h
index 4e78a9f..7c671068 100755
--- a/drivers/net/wireless/scsc/dev.h
+++ b/drivers/net/wireless/scsc/dev.h
@@ -1128,7 +1128,7 @@
/* BoT */
atomic_t in_pause_state;
-
+ struct work_struct trigger_wlan_fail_work; /* Work on mlme cfm or ind timeout*/
/* Locking used to control Starting and stopping the chip */
#ifdef CONFIG_SCSC_WLAN_MUTEX_DEBUG
struct slsi_mutex start_stop_mutex;
@@ -1219,6 +1219,7 @@
struct completion recovery_remove_completion;
struct completion recovery_stop_completion;
struct completion recovery_completed;
+ struct completion service_fail_started_indication;
int recovery_status;
struct slsi_ssid_map ssid_map[SLSI_SCAN_SSID_MAP_MAX];
bool band_5g_supported;
diff --git a/drivers/net/wireless/scsc/kic.c b/drivers/net/wireless/scsc/kic.c
index a139a93..32d3528 100755
--- a/drivers/net/wireless/scsc/kic.c
+++ b/drivers/net/wireless/scsc/kic.c
@@ -29,7 +29,7 @@
case slsi_kic_test_recovery_type_emulate_firmware_no_response:
SLSI_INFO(sdev, "Trigger Wi-Fi host panic\n");
snprintf(reason, sizeof(reason), "slsi_kic_test_recovery_type_emulate_firmware_no_response");
- slsi_sm_service_failed(sdev, reason);
+ slsi_sm_service_failed(sdev, reason, false);
return 0;
case slsi_kic_test_recovery_type_watch_dog:
case slsi_kic_test_recovery_type_chip_crash:
diff --git a/drivers/net/wireless/scsc/mgt.c b/drivers/net/wireless/scsc/mgt.c
index 43652e0..b4aa2e3 100755
--- a/drivers/net/wireless/scsc/mgt.c
+++ b/drivers/net/wireless/scsc/mgt.c
@@ -6372,3 +6372,13 @@
return ret;
}
+
+void slsi_trigger_service_failure(struct work_struct *work)
+{
+ struct slsi_dev *sdev = container_of(work, struct slsi_dev, trigger_wlan_fail_work);
+ char reason[80];
+
+ snprintf(reason, sizeof(reason), "Service fail - no MLME cfm/ind received");
+ slsi_sm_service_failed(sdev, reason, true);
+}
+
diff --git a/drivers/net/wireless/scsc/mgt.h b/drivers/net/wireless/scsc/mgt.h
index b096282d..ecebc69235 100755
--- a/drivers/net/wireless/scsc/mgt.h
+++ b/drivers/net/wireless/scsc/mgt.h
@@ -607,4 +607,5 @@
int slsi_set_num_antennas(struct net_device *dev, const u16 num_of_antennas);
#endif
int slsi_set_latency_mode(struct net_device *dev, int latency_mode, int cmd_len);
+void slsi_trigger_service_failure(struct work_struct *work);
#endif /*__SLSI_MGT_H__*/
diff --git a/drivers/net/wireless/scsc/mlme.c b/drivers/net/wireless/scsc/mlme.c
index 479bf46..0fed956 100755
--- a/drivers/net/wireless/scsc/mlme.c
+++ b/drivers/net/wireless/scsc/mlme.c
@@ -45,6 +45,7 @@
{
struct sk_buff *cfm = NULL;
int tm;
+ int r;
tm = wait_for_completion_timeout(&sig_wait->completion, msecs_to_jiffies(*sdev->sig_wait_cfm_timeout));
spin_lock_bh(&sig_wait->send_signal_lock);
@@ -61,7 +62,14 @@
sig_wait->cfm_id, sig_wait->req_id);
spin_unlock_bh(&sig_wait->send_signal_lock);
- slsi_sm_service_failed(sdev, reason);
+ /* Stop sending signals down*/
+ sdev->mlme_blocked = true;
+ queue_work(sdev->device_wq, &sdev->trigger_wlan_fail_work);
+ r = wait_for_completion_timeout(&sdev->service_fail_started_indication,
+ msecs_to_jiffies(SLSI_WLAN_FAIL_WORK_TIMEOUT));
+ if (r == 0)
+ SLSI_INFO(sdev, "service_fail_started_indication timeout\n");
+
spin_lock_bh(&sig_wait->send_signal_lock);
}
} else {
@@ -95,6 +103,7 @@
struct netdev_vif *ndev_vif = netdev_priv(dev);
struct sk_buff *ind = NULL;
int tm = 0;
+ int r = 0;
/* The indication and confirm may have been received in the same HIP read.
* The HIP receive buffer processes all received signals in one thread whilst the
@@ -124,7 +133,13 @@
sig_wait->ind_id, sig_wait->req_id);
spin_unlock_bh(&sig_wait->send_signal_lock);
- slsi_sm_service_failed(sdev, reason);
+ /* Stop sending signals down*/
+ sdev->mlme_blocked = true;
+ queue_work(sdev->device_wq, &sdev->trigger_wlan_fail_work);
+ r = wait_for_completion_timeout(&sdev->service_fail_started_indication,
+ msecs_to_jiffies(SLSI_WLAN_FAIL_WORK_TIMEOUT));
+ if (r == 0)
+ SLSI_INFO(sdev, "service_fail_started_indication timeout\n");
spin_lock_bh(&sig_wait->send_signal_lock);
}
} else {
diff --git a/drivers/net/wireless/scsc/mlme.h b/drivers/net/wireless/scsc/mlme.h
index 43b86e4..9d9ff23 100755
--- a/drivers/net/wireless/scsc/mlme.h
+++ b/drivers/net/wireless/scsc/mlme.h
@@ -29,6 +29,9 @@
#define SLSI_WLAN_OUI_TYPE_WFA_HS20_IND 0x10
#define SLSI_WLAN_OUI_TYPE_WFA_OSEN 0x12
#define SLSI_WLAN_OUI_TYPE_WFA_MBO 0x16
+
+#define SLSI_WLAN_FAIL_WORK_TIMEOUT 1500 /* 1.5s timeout */
+
/*Extended capabilities bytes*/
#define SLSI_WLAN_EXT_CAPA2_BSS_TRANSISITION_ENABLED (1 << 3)
#define SLSI_WLAN_EXT_CAPA3_INTERWORKING_ENABLED (1 << 7)
diff --git a/drivers/net/wireless/scsc/nl80211_vendor.c b/drivers/net/wireless/scsc/nl80211_vendor.c
index d6692d2..2b10543 100755
--- a/drivers/net/wireless/scsc/nl80211_vendor.c
+++ b/drivers/net/wireless/scsc/nl80211_vendor.c
@@ -1,6 +1,6 @@
/*****************************************************************************
*
- * Copyright (c) 2014 - 2019 Samsung Electronics Co., Ltd. All rights reserved
+ * Copyright (c) 2014 - 2021 Samsung Electronics Co., Ltd. All rights reserved
*
****************************************************************************/
#include <linux/version.h>
diff --git a/drivers/net/wireless/scsc/rx.c b/drivers/net/wireless/scsc/rx.c
index d1cb99f..ceb1f90 100755
--- a/drivers/net/wireless/scsc/rx.c
+++ b/drivers/net/wireless/scsc/rx.c
@@ -373,7 +373,7 @@
slsi_mbssid_to_ssid_list(sdev, ndev_vif, (u8 *)scan_ssid, ssid_len, new_bssid, current_freq,
current_rssi, akm_type);
}
- ie = ie + ie[1];
+ ie = ie + ie[1] + 2;
}
return 0;
}
@@ -1614,10 +1614,9 @@
ndev_vif->ap.channel_freq = freq; /* updated for GETSTAINFO */
ndev_vif->chan = chandef.chan;
-
cfg80211_ch_switch_notify(dev, &chandef);
- exit:
+exit:
SLSI_MUTEX_UNLOCK(ndev_vif->vif_mutex);
slsi_kfree_skb(skb);
}
diff --git a/drivers/net/wireless/scsc/scsc_wifi_cm_if.h b/drivers/net/wireless/scsc/scsc_wifi_cm_if.h
index a1ee9a1..f7df971 100755
--- a/drivers/net/wireless/scsc/scsc_wifi_cm_if.h
+++ b/drivers/net/wireless/scsc/scsc_wifi_cm_if.h
@@ -78,7 +78,7 @@
*/
int slsi_sm_service_driver_register(void);
void slsi_sm_service_driver_unregister(void);
-void slsi_sm_service_failed(struct slsi_dev *sdev, const char *reason);
+void slsi_sm_service_failed(struct slsi_dev *sdev, const char *reason, bool is_work);
int slsi_sm_wlan_service_open(struct slsi_dev *sdev);
int slsi_sm_wlan_service_start(struct slsi_dev *sdev);
void slsi_sm_wlan_service_stop(struct slsi_dev *sdev);
diff --git a/drivers/net/wireless/scsc/tx.c b/drivers/net/wireless/scsc/tx.c
index f0da3ae..0548b32 100755
--- a/drivers/net/wireless/scsc/tx.c
+++ b/drivers/net/wireless/scsc/tx.c
@@ -599,7 +599,7 @@
if (!in_interrupt()) {
snprintf(reason, sizeof(reason), "Failed to transmit signal 0x%04X (err:%d)", fapi_get_sigid(skb), res);
- slsi_sm_service_failed(sdev, reason);
+ slsi_sm_service_failed(sdev, reason, false);
res = -EIO;
}
diff --git a/drivers/security/samsung/icdrv/test/Makefile b/drivers/security/samsung/icdrv/test/Makefile
index 8c7d1d6..5688e41 100755
--- a/drivers/security/samsung/icdrv/test/Makefile
+++ b/drivers/security/samsung/icdrv/test/Makefile
@@ -1,2 +1 @@
-obj-y += icdrv_kunit_test.o
ccflags-y += -I$(src)/..
\ No newline at end of file
diff --git a/drivers/staging/android/ion/ion.c b/drivers/staging/android/ion/ion.c
index fd5d5eb..affd526 100755
--- a/drivers/staging/android/ion/ion.c
+++ b/drivers/staging/android/ion/ion.c
@@ -124,6 +124,7 @@
*/
struct ion_handle {
struct kref ref;
+ unsigned int user_ref_count;
struct ion_client *client;
struct ion_buffer *buffer;
struct rb_node node;
@@ -665,6 +666,50 @@
return ret;
}
+/* Must hold the client lock */
+static void user_ion_handle_get(struct ion_handle *handle)
+{
+ if (handle->user_ref_count++ == 0) {
+ kref_get(&handle->ref);
+ }
+}
+
+/* Must hold the client lock */
+static struct ion_handle* user_ion_handle_get_check_overflow(struct ion_handle *handle)
+{
+ if (handle->user_ref_count + 1 == 0)
+ return ERR_PTR(-EOVERFLOW);
+ user_ion_handle_get(handle);
+ return handle;
+}
+
+/* passes a kref to the user ref count.
+ * We know we're holding a kref to the object before and
+ * after this call, so no need to reverify handle. */
+static struct ion_handle* pass_to_user(struct ion_handle *handle)
+{
+ struct ion_client *client = handle->client;
+ struct ion_handle *ret;
+
+ mutex_lock(&client->lock);
+ ret = user_ion_handle_get_check_overflow(handle);
+ ion_handle_put_nolock(handle);
+ mutex_unlock(&client->lock);
+ return ret;
+}
+
+/* Must hold the client lock */
+static int user_ion_handle_put_nolock(struct ion_handle *handle)
+{
+ int ret = 0;
+
+ if (--handle->user_ref_count == 0) {
+ ret = ion_handle_put_nolock(handle);
+ }
+
+ return ret;
+}
+
int ion_handle_put(struct ion_handle *handle)
{
struct ion_client *client = handle->client;
@@ -872,6 +917,24 @@
ion_handle_put_nolock(handle);
}
+static void user_ion_free_nolock(struct ion_client *client, struct ion_handle *handle)
+{
+ bool valid_handle;
+
+ BUG_ON(client != handle->client);
+
+ valid_handle = ion_handle_validate(client, handle);
+ if (!valid_handle) {
+ WARN(1, "%s: invalid handle passed to free.\n", __func__);
+ return;
+ }
+ if (!handle->user_ref_count > 0) {
+ WARN(1, "%s: User does not have access!\n", __func__);
+ return;
+ }
+ user_ion_handle_put_nolock(handle);
+}
+
void ion_free(struct ion_client *client, struct ion_handle *handle)
{
BUG_ON(client != handle->client);
@@ -1487,43 +1550,46 @@
static void *ion_dma_buf_kmap(struct dma_buf *dmabuf, unsigned long offset)
{
struct ion_buffer *buffer = dmabuf->priv;
+ void *vaddr;
- return buffer->vaddr + offset * PAGE_SIZE;
+ if (!buffer->heap->ops->map_kernel) {
+ pr_err("%s: map kernel is not implemented by this heap.\n",
+ __func__);
+ return ERR_PTR(-ENOTTY);
+ }
+ mutex_lock(&buffer->lock);
+ vaddr = ion_buffer_kmap_get(buffer);
+ mutex_unlock(&buffer->lock);
+
+ if (IS_ERR(vaddr))
+ return vaddr;
+
+ return vaddr + offset * PAGE_SIZE;
}
static void ion_dma_buf_kunmap(struct dma_buf *dmabuf, unsigned long offset,
void *ptr)
{
+ struct ion_buffer *buffer = dmabuf->priv;
+
+ if (buffer->heap->ops->map_kernel) {
+ mutex_lock(&buffer->lock);
+ ion_buffer_kmap_put(buffer);
+ mutex_unlock(&buffer->lock);
+ }
}
static int ion_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, size_t start,
size_t len,
enum dma_data_direction direction)
{
- struct ion_buffer *buffer = dmabuf->priv;
- void *vaddr;
-
- if (!buffer->heap->ops->map_kernel) {
- pr_err("%s: map kernel is not implemented by this heap.\n",
- __func__);
- return -ENODEV;
- }
-
- mutex_lock(&buffer->lock);
- vaddr = ion_buffer_kmap_get(buffer);
- mutex_unlock(&buffer->lock);
- return PTR_ERR_OR_ZERO(vaddr);
+ return 0;
}
static void ion_dma_buf_end_cpu_access(struct dma_buf *dmabuf, size_t start,
size_t len,
enum dma_data_direction direction)
{
- struct ion_buffer *buffer = dmabuf->priv;
-
- mutex_lock(&buffer->lock);
- ion_buffer_kmap_put(buffer);
- mutex_unlock(&buffer->lock);
}
static void ion_dma_buf_set_privflag(struct dma_buf *dmabuf)
@@ -1903,10 +1969,10 @@
data.allocation.flags, PTR_ERR(handle));
return PTR_ERR(handle);
}
-
data.allocation.handle = handle->id;
cleanup_handle = handle;
+ pass_to_user(handle);
break;
}
case ION_IOC_FREE:
@@ -1919,7 +1985,7 @@
mutex_unlock(&client->lock);
return PTR_ERR(handle);
}
- ion_free_nolock(client, handle);
+ user_ion_free_nolock(client, handle);
ion_handle_put_nolock(handle);
mutex_unlock(&client->lock);
break;
@@ -1947,10 +2013,16 @@
struct ion_handle *handle;
handle = ion_import_dma_buf(client, data.fd.fd);
- if (IS_ERR(handle))
+ if (IS_ERR(handle)) {
ret = PTR_ERR(handle);
- else
+ } else {
data.handle.handle = handle->id;
+ handle = pass_to_user(handle);
+ if (IS_ERR(handle)) {
+ ret = PTR_ERR(handle);
+ data.handle.handle = 0;
+ }
+ }
break;
}
case ION_IOC_SYNC:
@@ -1979,8 +2051,10 @@
if (dir & _IOC_READ) {
if (copy_to_user((void __user *)arg, &data, _IOC_SIZE(cmd))) {
if (cleanup_handle) {
- ion_free(client, cleanup_handle);
- ion_handle_put(cleanup_handle);
+ mutex_lock(&client->lock);
+ user_ion_free_nolock(client, cleanup_handle);
+ ion_handle_put_nolock(cleanup_handle);
+ mutex_unlock(&client->lock);
}
return -EFAULT;
}
diff --git a/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
new file mode 100755
index 0000000..0d3ed87
--- /dev/null
+++ b/drivers/staging/lustre/lustre/include/lustre_dlm_flags.h
@@ -0,0 +1,467 @@
+/* -*- buffer-read-only: t -*- vi: set ro:
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 only,
+ * as published by the Free Software Foundation.
+ *
+ * Lustre is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+/**
+ * \file lustre_dlm_flags.h
+ * The flags and collections of flags (masks) for \see struct ldlm_lock.
+ *
+ * \addtogroup LDLM Lustre Distributed Lock Manager
+ * @{
+ *
+ * \name flags
+ * The flags and collections of flags (masks) for \see struct ldlm_lock.
+ * @{
+ */
+#ifndef LDLM_ALL_FLAGS_MASK
+
+/** l_flags bits marked as "all_flags" bits */
+#define LDLM_FL_ALL_FLAGS_MASK 0x00FFFFFFC08F932FULL
+
+/** l_flags bits marked as "ast" bits */
+#define LDLM_FL_AST_MASK 0x0000000080008000ULL
+
+/** l_flags bits marked as "blocked" bits */
+#define LDLM_FL_BLOCKED_MASK 0x000000000000000EULL
+
+/** l_flags bits marked as "gone" bits */
+#define LDLM_FL_GONE_MASK 0x0006004000000000ULL
+
+/** l_flags bits marked as "hide_lock" bits */
+#define LDLM_FL_HIDE_LOCK_MASK 0x0000206400000000ULL
+
+/** l_flags bits marked as "inherit" bits */
+#define LDLM_FL_INHERIT_MASK 0x0000000000800000ULL
+
+/** l_flags bits marked as "local_only" bits */
+#define LDLM_FL_LOCAL_ONLY_MASK 0x00FFFFFF00000000ULL
+
+/** l_flags bits marked as "on_wire" bits */
+#define LDLM_FL_ON_WIRE_MASK 0x00000000C08F932FULL
+
+/** extent, mode, or resource changed */
+#define LDLM_FL_LOCK_CHANGED 0x0000000000000001ULL /* bit 0 */
+#define ldlm_is_lock_changed(_l) LDLM_TEST_FLAG((_l), 1ULL << 0)
+#define ldlm_set_lock_changed(_l) LDLM_SET_FLAG((_l), 1ULL << 0)
+#define ldlm_clear_lock_changed(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 0)
+
+/**
+ * Server placed lock on granted list, or a recovering client wants the
+ * lock added to the granted list, no questions asked. */
+#define LDLM_FL_BLOCK_GRANTED 0x0000000000000002ULL /* bit 1 */
+#define ldlm_is_block_granted(_l) LDLM_TEST_FLAG((_l), 1ULL << 1)
+#define ldlm_set_block_granted(_l) LDLM_SET_FLAG((_l), 1ULL << 1)
+#define ldlm_clear_block_granted(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 1)
+
+/**
+ * Server placed lock on conv list, or a recovering client wants the lock
+ * added to the conv list, no questions asked. */
+#define LDLM_FL_BLOCK_CONV 0x0000000000000004ULL /* bit 2 */
+#define ldlm_is_block_conv(_l) LDLM_TEST_FLAG((_l), 1ULL << 2)
+#define ldlm_set_block_conv(_l) LDLM_SET_FLAG((_l), 1ULL << 2)
+#define ldlm_clear_block_conv(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 2)
+
+/**
+ * Server placed lock on wait list, or a recovering client wants the lock
+ * added to the wait list, no questions asked. */
+#define LDLM_FL_BLOCK_WAIT 0x0000000000000008ULL /* bit 3 */
+#define ldlm_is_block_wait(_l) LDLM_TEST_FLAG((_l), 1ULL << 3)
+#define ldlm_set_block_wait(_l) LDLM_SET_FLAG((_l), 1ULL << 3)
+#define ldlm_clear_block_wait(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 3)
+
+/** blocking or cancel packet was queued for sending. */
+#define LDLM_FL_AST_SENT 0x0000000000000020ULL /* bit 5 */
+#define ldlm_is_ast_sent(_l) LDLM_TEST_FLAG((_l), 1ULL << 5)
+#define ldlm_set_ast_sent(_l) LDLM_SET_FLAG((_l), 1ULL << 5)
+#define ldlm_clear_ast_sent(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 5)
+
+/**
+ * Lock is being replayed. This could probably be implied by the fact that
+ * one of BLOCK_{GRANTED,CONV,WAIT} is set, but that is pretty dangerous. */
+#define LDLM_FL_REPLAY 0x0000000000000100ULL /* bit 8 */
+#define ldlm_is_replay(_l) LDLM_TEST_FLAG((_l), 1ULL << 8)
+#define ldlm_set_replay(_l) LDLM_SET_FLAG((_l), 1ULL << 8)
+#define ldlm_clear_replay(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 8)
+
+/** Don't grant lock, just do intent. */
+#define LDLM_FL_INTENT_ONLY 0x0000000000000200ULL /* bit 9 */
+#define ldlm_is_intent_only(_l) LDLM_TEST_FLAG((_l), 1ULL << 9)
+#define ldlm_set_intent_only(_l) LDLM_SET_FLAG((_l), 1ULL << 9)
+#define ldlm_clear_intent_only(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 9)
+
+/** lock request has intent */
+#define LDLM_FL_HAS_INTENT 0x0000000000001000ULL /* bit 12 */
+#define ldlm_is_has_intent(_l) LDLM_TEST_FLAG((_l), 1ULL << 12)
+#define ldlm_set_has_intent(_l) LDLM_SET_FLAG((_l), 1ULL << 12)
+#define ldlm_clear_has_intent(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 12)
+
+/** flock deadlock detected */
+#define LDLM_FL_FLOCK_DEADLOCK 0x0000000000008000ULL /* bit 15 */
+#define ldlm_is_flock_deadlock(_l) LDLM_TEST_FLAG((_l), 1ULL << 15)
+#define ldlm_set_flock_deadlock(_l) LDLM_SET_FLAG((_l), 1ULL << 15)
+#define ldlm_clear_flock_deadlock(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 15)
+
+/** discard (no writeback) on cancel */
+#define LDLM_FL_DISCARD_DATA 0x0000000000010000ULL /* bit 16 */
+#define ldlm_is_discard_data(_l) LDLM_TEST_FLAG((_l), 1ULL << 16)
+#define ldlm_set_discard_data(_l) LDLM_SET_FLAG((_l), 1ULL << 16)
+#define ldlm_clear_discard_data(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 16)
+
+/** Blocked by group lock - wait indefinitely */
+#define LDLM_FL_NO_TIMEOUT 0x0000000000020000ULL /* bit 17 */
+#define ldlm_is_no_timeout(_l) LDLM_TEST_FLAG((_l), 1ULL << 17)
+#define ldlm_set_no_timeout(_l) LDLM_SET_FLAG((_l), 1ULL << 17)
+#define ldlm_clear_no_timeout(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 17)
+
+/**
+ * Server told not to wait if blocked. For AGL, OST will not send glimpse
+ * callback. */
+#define LDLM_FL_BLOCK_NOWAIT 0x0000000000040000ULL /* bit 18 */
+#define ldlm_is_block_nowait(_l) LDLM_TEST_FLAG((_l), 1ULL << 18)
+#define ldlm_set_block_nowait(_l) LDLM_SET_FLAG((_l), 1ULL << 18)
+#define ldlm_clear_block_nowait(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 18)
+
+/** return blocking lock */
+#define LDLM_FL_TEST_LOCK 0x0000000000080000ULL /* bit 19 */
+#define ldlm_is_test_lock(_l) LDLM_TEST_FLAG((_l), 1ULL << 19)
+#define ldlm_set_test_lock(_l) LDLM_SET_FLAG((_l), 1ULL << 19)
+#define ldlm_clear_test_lock(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 19)
+
+/**
+ * Immediately cancel such locks when they block some other locks. Send
+ * cancel notification to original lock holder, but expect no reply. This
+ * is for clients (like liblustre) that cannot be expected to reliably
+ * response to blocking AST. */
+#define LDLM_FL_CANCEL_ON_BLOCK 0x0000000000800000ULL /* bit 23 */
+#define ldlm_is_cancel_on_block(_l) LDLM_TEST_FLAG((_l), 1ULL << 23)
+#define ldlm_set_cancel_on_block(_l) LDLM_SET_FLAG((_l), 1ULL << 23)
+#define ldlm_clear_cancel_on_block(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 23)
+
+/**
+ * measure lock contention and return -EUSERS if locking contention is high */
+#define LDLM_FL_DENY_ON_CONTENTION 0x0000000040000000ULL /* bit 30 */
+#define ldlm_is_deny_on_contention(_l) LDLM_TEST_FLAG((_l), 1ULL << 30)
+#define ldlm_set_deny_on_contention(_l) LDLM_SET_FLAG((_l), 1ULL << 30)
+#define ldlm_clear_deny_on_contention(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 30)
+
+/**
+ * These are flags that are mapped into the flags and ASTs of blocking
+ * locks Add FL_DISCARD to blocking ASTs */
+#define LDLM_FL_AST_DISCARD_DATA 0x0000000080000000ULL /* bit 31 */
+#define ldlm_is_ast_discard_data(_l) LDLM_TEST_FLAG((_l), 1ULL << 31)
+#define ldlm_set_ast_discard_data(_l) LDLM_SET_FLAG((_l), 1ULL << 31)
+#define ldlm_clear_ast_discard_data(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 31)
+
+/**
+ * Used for marking lock as a target for -EINTR while cp_ast sleep emulation
+ * + race with upcoming bl_ast. */
+#define LDLM_FL_FAIL_LOC 0x0000000100000000ULL /* bit 32 */
+#define ldlm_is_fail_loc(_l) LDLM_TEST_FLAG((_l), 1ULL << 32)
+#define ldlm_set_fail_loc(_l) LDLM_SET_FLAG((_l), 1ULL << 32)
+#define ldlm_clear_fail_loc(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 32)
+
+/**
+ * Used while processing the unused list to know that we have already
+ * handled this lock and decided to skip it. */
+#define LDLM_FL_SKIPPED 0x0000000200000000ULL /* bit 33 */
+#define ldlm_is_skipped(_l) LDLM_TEST_FLAG((_l), 1ULL << 33)
+#define ldlm_set_skipped(_l) LDLM_SET_FLAG((_l), 1ULL << 33)
+#define ldlm_clear_skipped(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 33)
+
+/** this lock is being destroyed */
+#define LDLM_FL_CBPENDING 0x0000000400000000ULL /* bit 34 */
+#define ldlm_is_cbpending(_l) LDLM_TEST_FLAG((_l), 1ULL << 34)
+#define ldlm_set_cbpending(_l) LDLM_SET_FLAG((_l), 1ULL << 34)
+#define ldlm_clear_cbpending(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 34)
+
+/** not a real flag, not saved in lock */
+#define LDLM_FL_WAIT_NOREPROC 0x0000000800000000ULL /* bit 35 */
+#define ldlm_is_wait_noreproc(_l) LDLM_TEST_FLAG((_l), 1ULL << 35)
+#define ldlm_set_wait_noreproc(_l) LDLM_SET_FLAG((_l), 1ULL << 35)
+#define ldlm_clear_wait_noreproc(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 35)
+
+/** cancellation callback already run */
+#define LDLM_FL_CANCEL 0x0000001000000000ULL /* bit 36 */
+#define ldlm_is_cancel(_l) LDLM_TEST_FLAG((_l), 1ULL << 36)
+#define ldlm_set_cancel(_l) LDLM_SET_FLAG((_l), 1ULL << 36)
+#define ldlm_clear_cancel(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 36)
+
+/** whatever it might mean */
+#define LDLM_FL_LOCAL_ONLY 0x0000002000000000ULL /* bit 37 */
+#define ldlm_is_local_only(_l) LDLM_TEST_FLAG((_l), 1ULL << 37)
+#define ldlm_set_local_only(_l) LDLM_SET_FLAG((_l), 1ULL << 37)
+#define ldlm_clear_local_only(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 37)
+
+/** don't run the cancel callback under ldlm_cli_cancel_unused */
+#define LDLM_FL_FAILED 0x0000004000000000ULL /* bit 38 */
+#define ldlm_is_failed(_l) LDLM_TEST_FLAG((_l), 1ULL << 38)
+#define ldlm_set_failed(_l) LDLM_SET_FLAG((_l), 1ULL << 38)
+#define ldlm_clear_failed(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 38)
+
+/** lock cancel has already been sent */
+#define LDLM_FL_CANCELING 0x0000008000000000ULL /* bit 39 */
+#define ldlm_is_canceling(_l) LDLM_TEST_FLAG((_l), 1ULL << 39)
+#define ldlm_set_canceling(_l) LDLM_SET_FLAG((_l), 1ULL << 39)
+#define ldlm_clear_canceling(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 39)
+
+/** local lock (ie, no srv/cli split) */
+#define LDLM_FL_LOCAL 0x0000010000000000ULL /* bit 40 */
+#define ldlm_is_local(_l) LDLM_TEST_FLAG((_l), 1ULL << 40)
+#define ldlm_set_local(_l) LDLM_SET_FLAG((_l), 1ULL << 40)
+#define ldlm_clear_local(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 40)
+
+/**
+ * XXX FIXME: This is being added to b_size as a low-risk fix to the
+ * fact that the LVB filling happens _after_ the lock has been granted,
+ * so another thread can match it before the LVB has been updated. As a
+ * dirty hack, we set LDLM_FL_LVB_READY only after we've done the LVB poop.
+ * this is only needed on LOV/OSC now, where LVB is actually used and
+ * callers must set it in input flags.
+ *
+ * The proper fix is to do the granting inside of the completion AST,
+ * which can be replaced with a LVB-aware wrapping function for OSC locks.
+ * That change is pretty high-risk, though, and would need a lot more
+ * testing. */
+#define LDLM_FL_LVB_READY 0x0000020000000000ULL /* bit 41 */
+#define ldlm_is_lvb_ready(_l) LDLM_TEST_FLAG((_l), 1ULL << 41)
+#define ldlm_set_lvb_ready(_l) LDLM_SET_FLAG((_l), 1ULL << 41)
+#define ldlm_clear_lvb_ready(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 41)
+
+/**
+ * A lock contributes to the known minimum size (KMS) calculation until it
+ * has finished the part of its cancellation that performs write back on its
+ * dirty pages. It can remain on the granted list during this whole time.
+ * Threads racing to update the KMS after performing their writeback need
+ * to know to exclude each other's locks from the calculation as they walk
+ * the granted list. */
+#define LDLM_FL_KMS_IGNORE 0x0000040000000000ULL /* bit 42 */
+#define ldlm_is_kms_ignore(_l) LDLM_TEST_FLAG((_l), 1ULL << 42)
+#define ldlm_set_kms_ignore(_l) LDLM_SET_FLAG((_l), 1ULL << 42)
+#define ldlm_clear_kms_ignore(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 42)
+
+/** completion AST to be executed */
+#define LDLM_FL_CP_REQD 0x0000080000000000ULL /* bit 43 */
+#define ldlm_is_cp_reqd(_l) LDLM_TEST_FLAG((_l), 1ULL << 43)
+#define ldlm_set_cp_reqd(_l) LDLM_SET_FLAG((_l), 1ULL << 43)
+#define ldlm_clear_cp_reqd(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 43)
+
+/** cleanup_resource has already handled the lock */
+#define LDLM_FL_CLEANED 0x0000100000000000ULL /* bit 44 */
+#define ldlm_is_cleaned(_l) LDLM_TEST_FLAG((_l), 1ULL << 44)
+#define ldlm_set_cleaned(_l) LDLM_SET_FLAG((_l), 1ULL << 44)
+#define ldlm_clear_cleaned(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 44)
+
+/**
+ * optimization hint: LDLM can run blocking callback from current context
+ * w/o involving separate thread. in order to decrease cs rate */
+#define LDLM_FL_ATOMIC_CB 0x0000200000000000ULL /* bit 45 */
+#define ldlm_is_atomic_cb(_l) LDLM_TEST_FLAG((_l), 1ULL << 45)
+#define ldlm_set_atomic_cb(_l) LDLM_SET_FLAG((_l), 1ULL << 45)
+#define ldlm_clear_atomic_cb(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 45)
+
+/**
+ * It may happen that a client initiates two operations, e.g. unlink and
+ * mkdir, such that the server sends a blocking AST for conflicting locks
+ * to this client for the first operation, whereas the second operation
+ * has canceled this lock and is waiting for rpc_lock which is taken by
+ * the first operation. LDLM_FL_BL_AST is set by ldlm_callback_handler() in
+ * the lock to prevent the Early Lock Cancel (ELC) code from cancelling it.
+ *
+ * LDLM_FL_BL_DONE is to be set by ldlm_cancel_callback() when lock cache is
+ * dropped to let ldlm_callback_handler() return EINVAL to the server. It
+ * is used when ELC RPC is already prepared and is waiting for rpc_lock,
+ * too late to send a separate CANCEL RPC. */
+#define LDLM_FL_BL_AST 0x0000400000000000ULL /* bit 46 */
+#define ldlm_is_bl_ast(_l) LDLM_TEST_FLAG((_l), 1ULL << 46)
+#define ldlm_set_bl_ast(_l) LDLM_SET_FLAG((_l), 1ULL << 46)
+#define ldlm_clear_bl_ast(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 46)
+
+/** whatever it might mean */
+#define LDLM_FL_BL_DONE 0x0000800000000000ULL /* bit 47 */
+#define ldlm_is_bl_done(_l) LDLM_TEST_FLAG((_l), 1ULL << 47)
+#define ldlm_set_bl_done(_l) LDLM_SET_FLAG((_l), 1ULL << 47)
+#define ldlm_clear_bl_done(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 47)
+
+/**
+ * Don't put lock into the LRU list, so that it is not canceled due
+ * to aging. Used by MGC locks, they are cancelled only at unmount or
+ * by callback. */
+#define LDLM_FL_NO_LRU 0x0001000000000000ULL /* bit 48 */
+#define ldlm_is_no_lru(_l) LDLM_TEST_FLAG((_l), 1ULL << 48)
+#define ldlm_set_no_lru(_l) LDLM_SET_FLAG((_l), 1ULL << 48)
+#define ldlm_clear_no_lru(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 48)
+
+/**
+ * Set for locks that failed and where the server has been notified.
+ *
+ * Protected by lock and resource locks. */
+#define LDLM_FL_FAIL_NOTIFIED 0x0002000000000000ULL /* bit 49 */
+#define ldlm_is_fail_notified(_l) LDLM_TEST_FLAG((_l), 1ULL << 49)
+#define ldlm_set_fail_notified(_l) LDLM_SET_FLAG((_l), 1ULL << 49)
+#define ldlm_clear_fail_notified(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 49)
+
+/**
+ * Set for locks that were removed from class hash table and will
+ * be destroyed when last reference to them is released. Set by
+ * ldlm_lock_destroy_internal().
+ *
+ * Protected by lock and resource locks. */
+#define LDLM_FL_DESTROYED 0x0004000000000000ULL /* bit 50 */
+#define ldlm_is_destroyed(_l) LDLM_TEST_FLAG((_l), 1ULL << 50)
+#define ldlm_set_destroyed(_l) LDLM_SET_FLAG((_l), 1ULL << 50)
+#define ldlm_clear_destroyed(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 50)
+
+/** flag whether this is a server namespace lock */
+#define LDLM_FL_SERVER_LOCK 0x0008000000000000ULL /* bit 51 */
+#define ldlm_is_server_lock(_l) LDLM_TEST_FLAG((_l), 1ULL << 51)
+#define ldlm_set_server_lock(_l) LDLM_SET_FLAG((_l), 1ULL << 51)
+#define ldlm_clear_server_lock(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 51)
+
+/**
+ * It's set in lock_res_and_lock() and unset in unlock_res_and_lock().
+ *
+ * NB: compared with check_res_locked(), checking this bit is cheaper.
+ * Also, spin_is_locked() is deprecated for kernel code; one reason is
+ * because it works only for SMP so user needs to add extra macros like
+ * LASSERT_SPIN_LOCKED for uniprocessor kernels. */
+#define LDLM_FL_RES_LOCKED 0x0010000000000000ULL /* bit 52 */
+#define ldlm_is_res_locked(_l) LDLM_TEST_FLAG((_l), 1ULL << 52)
+#define ldlm_set_res_locked(_l) LDLM_SET_FLAG((_l), 1ULL << 52)
+#define ldlm_clear_res_locked(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 52)
+
+/**
+ * It's set once we call ldlm_add_waiting_lock_res_locked() to start the
+ * lock-timeout timer and it will never be reset.
+ *
+ * Protected by lock and resource locks. */
+#define LDLM_FL_WAITED 0x0020000000000000ULL /* bit 53 */
+#define ldlm_is_waited(_l) LDLM_TEST_FLAG((_l), 1ULL << 53)
+#define ldlm_set_waited(_l) LDLM_SET_FLAG((_l), 1ULL << 53)
+#define ldlm_clear_waited(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 53)
+
+/** Flag whether this is a server namespace lock. */
+#define LDLM_FL_NS_SRV 0x0040000000000000ULL /* bit 54 */
+#define ldlm_is_ns_srv(_l) LDLM_TEST_FLAG((_l), 1ULL << 54)
+#define ldlm_set_ns_srv(_l) LDLM_SET_FLAG((_l), 1ULL << 54)
+#define ldlm_clear_ns_srv(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 54)
+
+/** Flag whether this lock can be reused. Used by exclusive open. */
+#define LDLM_FL_EXCL 0x0080000000000000ULL /* bit 55 */
+#define ldlm_is_excl(_l) LDLM_TEST_FLAG((_l), 1ULL << 55)
+#define ldlm_set_excl(_l) LDLM_SET_FLAG((_l), 1ULL << 55)
+#define ldlm_clear_excl(_l) LDLM_CLEAR_FLAG((_l), 1ULL << 55)
+
+/** test for ldlm_lock flag bit set */
+#define LDLM_TEST_FLAG(_l, _b) (((_l)->l_flags & (_b)) != 0)
+
+/** set a ldlm_lock flag bit */
+#define LDLM_SET_FLAG(_l, _b) (((_l)->l_flags |= (_b))
+
+/** clear a ldlm_lock flag bit */
+#define LDLM_CLEAR_FLAG(_l, _b) (((_l)->l_flags &= ~(_b))
+
+/** Mask of flags inherited from parent lock when doing intents. */
+#define LDLM_INHERIT_FLAGS LDLM_FL_INHERIT_MASK
+
+/** Mask of Flags sent in AST lock_flags to map into the receiving lock. */
+#define LDLM_AST_FLAGS LDLM_FL_AST_MASK
+
+/** @} subgroup */
+/** @} group */
+#ifdef WIRESHARK_COMPILE
+static int hf_lustre_ldlm_fl_lock_changed = -1;
+static int hf_lustre_ldlm_fl_block_granted = -1;
+static int hf_lustre_ldlm_fl_block_conv = -1;
+static int hf_lustre_ldlm_fl_block_wait = -1;
+static int hf_lustre_ldlm_fl_ast_sent = -1;
+static int hf_lustre_ldlm_fl_replay = -1;
+static int hf_lustre_ldlm_fl_intent_only = -1;
+static int hf_lustre_ldlm_fl_has_intent = -1;
+static int hf_lustre_ldlm_fl_flock_deadlock = -1;
+static int hf_lustre_ldlm_fl_discard_data = -1;
+static int hf_lustre_ldlm_fl_no_timeout = -1;
+static int hf_lustre_ldlm_fl_block_nowait = -1;
+static int hf_lustre_ldlm_fl_test_lock = -1;
+static int hf_lustre_ldlm_fl_cancel_on_block = -1;
+static int hf_lustre_ldlm_fl_deny_on_contention = -1;
+static int hf_lustre_ldlm_fl_ast_discard_data = -1;
+static int hf_lustre_ldlm_fl_fail_loc = -1;
+static int hf_lustre_ldlm_fl_skipped = -1;
+static int hf_lustre_ldlm_fl_cbpending = -1;
+static int hf_lustre_ldlm_fl_wait_noreproc = -1;
+static int hf_lustre_ldlm_fl_cancel = -1;
+static int hf_lustre_ldlm_fl_local_only = -1;
+static int hf_lustre_ldlm_fl_failed = -1;
+static int hf_lustre_ldlm_fl_canceling = -1;
+static int hf_lustre_ldlm_fl_local = -1;
+static int hf_lustre_ldlm_fl_lvb_ready = -1;
+static int hf_lustre_ldlm_fl_kms_ignore = -1;
+static int hf_lustre_ldlm_fl_cp_reqd = -1;
+static int hf_lustre_ldlm_fl_cleaned = -1;
+static int hf_lustre_ldlm_fl_atomic_cb = -1;
+static int hf_lustre_ldlm_fl_bl_ast = -1;
+static int hf_lustre_ldlm_fl_bl_done = -1;
+static int hf_lustre_ldlm_fl_no_lru = -1;
+static int hf_lustre_ldlm_fl_fail_notified = -1;
+static int hf_lustre_ldlm_fl_destroyed = -1;
+static int hf_lustre_ldlm_fl_server_lock = -1;
+static int hf_lustre_ldlm_fl_res_locked = -1;
+static int hf_lustre_ldlm_fl_waited = -1;
+static int hf_lustre_ldlm_fl_ns_srv = -1;
+static int hf_lustre_ldlm_fl_excl = -1;
+
+const value_string lustre_ldlm_flags_vals[] = {
+ {LDLM_FL_LOCK_CHANGED, "LDLM_FL_LOCK_CHANGED"},
+ {LDLM_FL_BLOCK_GRANTED, "LDLM_FL_BLOCK_GRANTED"},
+ {LDLM_FL_BLOCK_CONV, "LDLM_FL_BLOCK_CONV"},
+ {LDLM_FL_BLOCK_WAIT, "LDLM_FL_BLOCK_WAIT"},
+ {LDLM_FL_AST_SENT, "LDLM_FL_AST_SENT"},
+ {LDLM_FL_REPLAY, "LDLM_FL_REPLAY"},
+ {LDLM_FL_INTENT_ONLY, "LDLM_FL_INTENT_ONLY"},
+ {LDLM_FL_HAS_INTENT, "LDLM_FL_HAS_INTENT"},
+ {LDLM_FL_FLOCK_DEADLOCK, "LDLM_FL_FLOCK_DEADLOCK"},
+ {LDLM_FL_DISCARD_DATA, "LDLM_FL_DISCARD_DATA"},
+ {LDLM_FL_NO_TIMEOUT, "LDLM_FL_NO_TIMEOUT"},
+ {LDLM_FL_BLOCK_NOWAIT, "LDLM_FL_BLOCK_NOWAIT"},
+ {LDLM_FL_TEST_LOCK, "LDLM_FL_TEST_LOCK"},
+ {LDLM_FL_CANCEL_ON_BLOCK, "LDLM_FL_CANCEL_ON_BLOCK"},
+ {LDLM_FL_DENY_ON_CONTENTION, "LDLM_FL_DENY_ON_CONTENTION"},
+ {LDLM_FL_AST_DISCARD_DATA, "LDLM_FL_AST_DISCARD_DATA"},
+ {LDLM_FL_FAIL_LOC, "LDLM_FL_FAIL_LOC"},
+ {LDLM_FL_SKIPPED, "LDLM_FL_SKIPPED"},
+ {LDLM_FL_CBPENDING, "LDLM_FL_CBPENDING"},
+ {LDLM_FL_WAIT_NOREPROC, "LDLM_FL_WAIT_NOREPROC"},
+ {LDLM_FL_CANCEL, "LDLM_FL_CANCEL"},
+ {LDLM_FL_LOCAL_ONLY, "LDLM_FL_LOCAL_ONLY"},
+ {LDLM_FL_FAILED, "LDLM_FL_FAILED"},
+ {LDLM_FL_CANCELING, "LDLM_FL_CANCELING"},
+ {LDLM_FL_LOCAL, "LDLM_FL_LOCAL"},
+ {LDLM_FL_LVB_READY, "LDLM_FL_LVB_READY"},
+ {LDLM_FL_KMS_IGNORE, "LDLM_FL_KMS_IGNORE"},
+ {LDLM_FL_CP_REQD, "LDLM_FL_CP_REQD"},
+ {LDLM_FL_CLEANED, "LDLM_FL_CLEANED"},
+ {LDLM_FL_ATOMIC_CB, "LDLM_FL_ATOMIC_CB"},
+ {LDLM_FL_BL_AST, "LDLM_FL_BL_AST"},
+ {LDLM_FL_BL_DONE, "LDLM_FL_BL_DONE"},
+ {LDLM_FL_NO_LRU, "LDLM_FL_NO_LRU"},
+ {LDLM_FL_FAIL_NOTIFIED, "LDLM_FL_FAIL_NOTIFIED"},
+ {LDLM_FL_DESTROYED, "LDLM_FL_DESTROYED"},
+ {LDLM_FL_SERVER_LOCK, "LDLM_FL_SERVER_LOCK"},
+ {LDLM_FL_RES_LOCKED, "LDLM_FL_RES_LOCKED"},
+ {LDLM_FL_WAITED, "LDLM_FL_WAITED"},
+ {LDLM_FL_NS_SRV, "LDLM_FL_NS_SRV"},
+ {LDLM_FL_EXCL, "LDLM_FL_EXCL"},
+ { 0, NULL }
+};
+#endif /* WIRESHARK_COMPILE */
+#endif /* LDLM_ALL_FLAGS_MASK */
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index 5b86ebc..505237d 100755
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -535,8 +535,8 @@
put_pid(tty->session);
put_pid(tty->pgrp);
tty->pgrp = get_pid(task_pgrp(current));
- spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty->session = get_pid(task_session(current));
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
if (current->signal->tty) {
tty_debug(tty, "current tty %s not NULL!!\n",
current->signal->tty->name);
@@ -927,21 +927,24 @@
spin_lock_irq(¤t->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
-
tty = tty_kref_get(current->signal->tty);
+ spin_unlock_irq(¤t->sighand->siglock);
+
if (tty) {
unsigned long flags;
+
+ tty_lock(tty);
spin_lock_irqsave(&tty->ctrl_lock, flags);
put_pid(tty->session);
put_pid(tty->pgrp);
tty->session = NULL;
tty->pgrp = NULL;
spin_unlock_irqrestore(&tty->ctrl_lock, flags);
+ tty_unlock(tty);
tty_kref_put(tty);
} else
tty_debug_hangup(tty, "no current tty\n");
- spin_unlock_irq(¤t->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
@@ -2599,14 +2602,19 @@
return -ENOTTY;
if (retval)
return retval;
- if (!current->signal->tty ||
- (current->signal->tty != real_tty) ||
- (real_tty->session != task_session(current)))
- return -ENOTTY;
+
if (get_user(pgrp_nr, p))
return -EFAULT;
if (pgrp_nr < 0)
return -EINVAL;
+
+ spin_lock_irq(&real_tty->ctrl_lock);
+ if (!current->signal->tty ||
+ (current->signal->tty != real_tty) ||
+ (real_tty->session != task_session(current))) {
+ retval = -ENOTTY;
+ goto out_unlock_ctrl;
+ }
rcu_read_lock();
pgrp = find_vpid(pgrp_nr);
retval = -ESRCH;
@@ -2616,12 +2624,12 @@
if (session_of_pgrp(pgrp) != task_session(current))
goto out_unlock;
retval = 0;
- spin_lock_irq(&tty->ctrl_lock);
put_pid(real_tty->pgrp);
real_tty->pgrp = get_pid(pgrp);
- spin_unlock_irq(&tty->ctrl_lock);
out_unlock:
rcu_read_unlock();
+out_unlock_ctrl:
+ spin_unlock_irq(&real_tty->ctrl_lock);
return retval;
}
@@ -2633,21 +2641,31 @@
*
* Obtain the session id of the tty. If there is no session
* return an error.
- *
- * Locking: none. Reference to current->signal->tty is safe.
*/
static int tiocgsid(struct tty_struct *tty, struct tty_struct *real_tty, pid_t __user *p)
{
+ unsigned long flags;
+ pid_t sid;
+
/*
* (tty == real_tty) is a cheap way of
* testing if the tty is NOT a master pty.
*/
if (tty == real_tty && current->signal->tty != real_tty)
return -ENOTTY;
+
+ spin_lock_irqsave(&real_tty->ctrl_lock, flags);
if (!real_tty->session)
- return -ENOTTY;
- return put_user(pid_vnr(real_tty->session), p);
+ goto err;
+ sid = pid_vnr(real_tty->session);
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+
+ return put_user(sid, p);
+
+err:
+ spin_unlock_irqrestore(&real_tty->ctrl_lock, flags);
+ return -ENOTTY;
}
/**
@@ -3059,10 +3077,14 @@
struct task_struct *g, *p;
struct pid *session;
int i;
+ unsigned long flags;
if (!tty)
return;
- session = tty->session;
+
+ spin_lock_irqsave(&tty->ctrl_lock, flags);
+ session = get_pid(tty->session);
+ spin_unlock_irqrestore(&tty->ctrl_lock, flags);
tty_ldisc_flush(tty);
@@ -3098,6 +3120,7 @@
task_unlock(p);
} while_each_thread(g, p);
read_unlock(&tasklist_lock);
+ put_pid(session);
#endif
}
diff --git a/drivers/usb/gadget/composite.c b/drivers/usb/gadget/composite.c
index 4de456c..62e6d75 100755
--- a/drivers/usb/gadget/composite.c
+++ b/drivers/usb/gadget/composite.c
@@ -1580,6 +1580,19 @@
struct otg_notify *notify = NULL;
notify = get_otg_notify();
#endif
+
+ if (w_length > USB_COMP_EP0_BUFSIZ) {
+ if (ctrl->bRequestType & USB_DIR_IN) {
+ /* Cast away the const, we are going to overwrite on purpose. */
+ __le16 *temp = (__le16 *)&ctrl->wLength;
+
+ *temp = cpu_to_le16(USB_COMP_EP0_BUFSIZ);
+ w_length = USB_COMP_EP0_BUFSIZ;
+ } else {
+ goto done;
+ }
+ }
+
/* partial re-init of the response message; the function or the
* gadget might need to intercept e.g. a control-OUT completion
* when we delegate to it.
@@ -1881,6 +1894,9 @@
if (w_index != 0x5 || (w_value >> 8))
break;
interface = w_value & 0xFF;
+ if (interface >= MAX_CONFIG_INTERFACES ||
+ !os_desc_cfg->interface[interface])
+ break;
buf[6] = w_index;
if (w_length == 0x0A) {
count = count_ext_prop(os_desc_cfg,
@@ -2130,7 +2146,7 @@
if (!cdev->req)
return -ENOMEM;
- cdev->req->buf = kmalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
+ cdev->req->buf = kzalloc(USB_COMP_EP0_BUFSIZ, GFP_KERNEL);
if (!cdev->req->buf)
goto fail;
diff --git a/drivers/usb/gadget/function/rndis.c b/drivers/usb/gadget/function/rndis.c
index 2ec7171..991eee3 100755
--- a/drivers/usb/gadget/function/rndis.c
+++ b/drivers/usb/gadget/function/rndis.c
@@ -652,14 +652,18 @@
rndis_set_cmplt_type *resp;
rndis_resp_t *r;
+ BufLength = le32_to_cpu(buf->InformationBufferLength);
+ BufOffset = le32_to_cpu(buf->InformationBufferOffset);
+ if ((BufLength > RNDIS_MAX_TOTAL_SIZE) ||
+ (BufOffset > RNDIS_MAX_TOTAL_SIZE) ||
+ (BufOffset + 8 >= RNDIS_MAX_TOTAL_SIZE))
+ return -EINVAL;
+
r = rndis_add_response(params, sizeof(rndis_set_cmplt_type));
if (!r)
return -ENOMEM;
resp = (rndis_set_cmplt_type *)r->buf;
- BufLength = le32_to_cpu(buf->InformationBufferLength);
- BufOffset = le32_to_cpu(buf->InformationBufferOffset);
-
#ifdef VERBOSE_DEBUG
pr_debug("%s: Length: %d\n", __func__, BufLength);
pr_debug("%s: Offset: %d\n", __func__, BufOffset);
diff --git a/drivers/video/fbdev/exynos/dpu_7885/decon_core.c b/drivers/video/fbdev/exynos/dpu_7885/decon_core.c
index 006a1c7..5f4a1e2 100755
--- a/drivers/video/fbdev/exynos/dpu_7885/decon_core.c
+++ b/drivers/video/fbdev/exynos/dpu_7885/decon_core.c
@@ -1049,17 +1049,17 @@
regs->plane_cnt[idx] = dpu_get_plane_cnt(config->format);
for (i = 0; i < regs->plane_cnt[idx]; ++i) {
- handle = ion_import_dma_buf(decon->ion_client, config->fd_idma[i]);
- if (IS_ERR(handle)) {
- decon_err("failed to import fd:%d\n", config->fd_idma[i]);
- ret = PTR_ERR(handle);
- goto fail;
- }
-
buf = dma_buf_get(config->fd_idma[i]);
if (IS_ERR_OR_NULL(buf)) {
decon_err("failed to get dma_buf:%ld\n", PTR_ERR(buf));
ret = PTR_ERR(buf);
+ goto fail;
+ }
+
+ handle = ion_import_dma_buf(decon->ion_client, config->fd_idma[i]);
+ if (IS_ERR(handle)) {
+ decon_err("failed to import fd:%d\n", config->fd_idma[i]);
+ ret = PTR_ERR(handle);
goto fail_buf;
}
@@ -1084,9 +1084,9 @@
return ret;
fail_map:
- dma_buf_put(buf);
-fail_buf:
ion_free(decon->ion_client, handle);
+fail_buf:
+ dma_buf_put(buf);
fail:
return ret;
diff --git a/fs/eventpoll.c b/fs/eventpoll.c
index e4d7c75..9b9af5d 100755
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1309,6 +1309,22 @@
RCU_INIT_POINTER(epi->ws, NULL);
}
+ /* Add the current item to the list of active epoll hook for this file */
+ spin_lock(&tfile->f_lock);
+ list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links);
+ spin_unlock(&tfile->f_lock);
+
+ /*
+ * Add the current item to the RB tree. All RB tree operations are
+ * protected by "mtx", and ep_insert() is called with "mtx" held.
+ */
+ ep_rbtree_insert(ep, epi);
+
+ /* now check if we've created too many backpaths */
+ error = -EINVAL;
+ if (full_check && reverse_path_check())
+ goto error_remove_epi;
+
/* Initialize the poll table using the queue callback */
epq.epi = epi;
init_poll_funcptr(&epq.pt, ep_ptable_queue_proc);
@@ -1331,22 +1347,6 @@
if (epi->nwait < 0)
goto error_unregister;
- /* Add the current item to the list of active epoll hook for this file */
- spin_lock(&tfile->f_lock);
- list_add_tail_rcu(&epi->fllink, &tfile->f_ep_links);
- spin_unlock(&tfile->f_lock);
-
- /*
- * Add the current item to the RB tree. All RB tree operations are
- * protected by "mtx", and ep_insert() is called with "mtx" held.
- */
- ep_rbtree_insert(ep, epi);
-
- /* now check if we've created too many backpaths */
- error = -EINVAL;
- if (full_check && reverse_path_check())
- goto error_remove_epi;
-
/* We have to drop the new item inside our item list to keep track of it */
spin_lock_irqsave(&ep->lock, flags);
@@ -1372,6 +1372,8 @@
return 0;
+error_unregister:
+ ep_unregister_pollwait(ep, epi);
error_remove_epi:
spin_lock(&tfile->f_lock);
list_del_rcu(&epi->fllink);
@@ -1379,9 +1381,6 @@
rb_erase(&epi->rbn, &ep->rbr);
-error_unregister:
- ep_unregister_pollwait(ep, epi);
-
/*
* We need to do this because an event could have been arrived on some
* allocated wait queue. Note that we don't care about the ep->ovflist
@@ -1726,9 +1725,9 @@
* during ep_insert().
*/
if (list_empty(&epi->ffd.file->f_tfile_llink)) {
- get_file(epi->ffd.file);
- list_add(&epi->ffd.file->f_tfile_llink,
- &tfile_check_list);
+ if (get_file_rcu(epi->ffd.file))
+ list_add(&epi->ffd.file->f_tfile_llink,
+ &tfile_check_list);
}
}
}
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
index 667f65b..13f564f 100755
--- a/include/linux/lsm_hooks.h
+++ b/include/linux/lsm_hooks.h
@@ -1121,22 +1121,22 @@
*
* @binder_set_context_mgr
* Check whether @mgr is allowed to be the binder context manager.
- * @mgr contains the task_struct for the task being registered.
+ * @mgr contains the struct cred for the current binder process.
* Return 0 if permission is granted.
* @binder_transaction
* Check whether @from is allowed to invoke a binder transaction call
* to @to.
- * @from contains the task_struct for the sending task.
- * @to contains the task_struct for the receiving task.
- * @binder_transfer_binder
+ * @from contains the struct cred for the sending process.
+ * @to contains the struct cred for the receiving process.
+ * @binder_transfer_binder:
* Check whether @from is allowed to transfer a binder reference to @to.
- * @from contains the task_struct for the sending task.
- * @to contains the task_struct for the receiving task.
- * @binder_transfer_file
+ * @from contains the struct cred for the sending process.
+ * @to contains the struct cred for the receiving process.
+ * @binder_transfer_file:
* Check whether @from is allowed to transfer @file to @to.
- * @from contains the task_struct for the sending task.
+ * @from contains the struct cred for the sending process.
* @file contains the struct file being transferred.
- * @to contains the task_struct for the receiving task.
+ * @to contains the struct cred for the receiving process.
*
* @ptrace_access_check:
* Check permission before allowing the current process to trace the
@@ -1338,13 +1338,13 @@
*/
union security_list_options {
- int (*binder_set_context_mgr)(struct task_struct *mgr);
- int (*binder_transaction)(struct task_struct *from,
- struct task_struct *to);
- int (*binder_transfer_binder)(struct task_struct *from,
- struct task_struct *to);
- int (*binder_transfer_file)(struct task_struct *from,
- struct task_struct *to,
+ int (*binder_set_context_mgr)(const struct cred *mgr);
+ int (*binder_transaction)(const struct cred *from,
+ const struct cred *to);
+ int (*binder_transfer_binder)(const struct cred *from,
+ const struct cred *to);
+ int (*binder_transfer_file)(const struct cred *from,
+ const struct cred *to,
struct file *file);
int (*ptrace_access_check)(struct task_struct *child,
diff --git a/include/linux/security.h b/include/linux/security.h
index 30f0c94..d78417d 100755
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -211,13 +211,13 @@
extern int security_init(void);
/* Security operations */
-int security_binder_set_context_mgr(struct task_struct *mgr);
-int security_binder_transaction(struct task_struct *from,
- struct task_struct *to);
-int security_binder_transfer_binder(struct task_struct *from,
- struct task_struct *to);
-int security_binder_transfer_file(struct task_struct *from,
- struct task_struct *to, struct file *file);
+int security_binder_set_context_mgr(const struct cred *mgr);
+int security_binder_transaction(const struct cred *from,
+ const struct cred *to);
+int security_binder_transfer_binder(const struct cred *from,
+ const struct cred *to);
+int security_binder_transfer_file(const struct cred *from,
+ const struct cred *to, struct file *file);
int security_ptrace_access_check(struct task_struct *child, unsigned int mode);
int security_ptrace_traceme(struct task_struct *parent);
int security_capget(struct task_struct *target,
@@ -408,25 +408,25 @@
return 0;
}
-static inline int security_binder_set_context_mgr(struct task_struct *mgr)
+static inline int security_binder_set_context_mgr(const struct cred *mgr)
{
return 0;
}
-static inline int security_binder_transaction(struct task_struct *from,
- struct task_struct *to)
+static inline int security_binder_transaction(const struct cred *from,
+ const struct cred *to)
{
return 0;
}
-static inline int security_binder_transfer_binder(struct task_struct *from,
- struct task_struct *to)
+static inline int security_binder_transfer_binder(const struct cred *from,
+ const struct cred *to)
{
return 0;
}
-static inline int security_binder_transfer_file(struct task_struct *from,
- struct task_struct *to,
+static inline int security_binder_transfer_file(const struct cred *from,
+ const struct cred *to,
struct file *file)
{
return 0;
diff --git a/include/linux/tty.h b/include/linux/tty.h
index 812cdd8..ed48da3 100755
--- a/include/linux/tty.h
+++ b/include/linux/tty.h
@@ -280,6 +280,10 @@
struct termiox *termiox; /* May be NULL for unsupported */
char name[64];
struct pid *pgrp; /* Protected by ctrl lock */
+ /*
+ * Writes protected by both ctrl lock and legacy mutex, readers must use
+ * at least one of them.
+ */
struct pid *session;
unsigned long flags;
int count;
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
index fd60ecc..79f2e1c 100755
--- a/include/net/af_unix.h
+++ b/include/net/af_unix.h
@@ -8,6 +8,7 @@
void unix_inflight(struct user_struct *user, struct file *fp);
void unix_notinflight(struct user_struct *user, struct file *fp);
+void unix_destruct_scm(struct sk_buff *skb);
void unix_gc(void);
void wait_for_unix_gc(void);
struct sock *unix_get_socket(struct file *filp);
diff --git a/include/scsc/scsc_release.h b/include/scsc/scsc_release.h
index d15df29..07833ea 100755
--- a/include/scsc/scsc_release.h
+++ b/include/scsc/scsc_release.h
@@ -13,7 +13,7 @@
#define SCSC_RELEASE_ITERATION 62
#define SCSC_RELEASE_CANDIDATE 0
-#define SCSC_RELEASE_POINT 10
+#define SCSC_RELEASE_POINT 12
#endif
diff --git a/net/Makefile b/net/Makefile
index 543d5b1..d715749 100755
--- a/net/Makefile
+++ b/net/Makefile
@@ -17,7 +17,7 @@
obj-$(CONFIG_WIREGUARD) += wireguard/
obj-$(CONFIG_INET) += ipv4/
obj-$(CONFIG_XFRM) += xfrm/
-obj-$(CONFIG_UNIX) += unix/
+obj-$(CONFIG_UNIX_SCM) += unix/
obj-$(CONFIG_NET) += ipv6/
obj-$(CONFIG_MPTCP) += mptcp/
obj-$(CONFIG_PACKET) += packet/
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index c67efa3..7b0bbda 100755
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -2631,6 +2631,7 @@
rv = 1;
} else if (im) {
if (src_addr) {
+ spin_lock_bh(&im->lock);
for (psf = im->sources; psf; psf = psf->sf_next) {
if (psf->sf_inaddr == src_addr)
break;
@@ -2641,6 +2642,7 @@
im->sfcount[MCAST_EXCLUDE];
else
rv = im->sfcount[MCAST_EXCLUDE] != 0;
+ spin_unlock_bh(&im->lock);
} else
rv = 1; /* unspecified source; tentatively allow */
}
diff --git a/net/unix/Kconfig b/net/unix/Kconfig
index 8b31ab8..3b9e450 100755
--- a/net/unix/Kconfig
+++ b/net/unix/Kconfig
@@ -19,6 +19,11 @@
Say Y unless you know what you are doing.
+config UNIX_SCM
+ bool
+ depends on UNIX
+ default y
+
config UNIX_DIAG
tristate "UNIX: socket monitoring interface"
depends on UNIX
diff --git a/net/unix/Makefile b/net/unix/Makefile
index b663c60..dc686c6 100755
--- a/net/unix/Makefile
+++ b/net/unix/Makefile
@@ -9,3 +9,5 @@
obj-$(CONFIG_UNIX_DIAG) += unix_diag.o
unix_diag-y := diag.o
+
+obj-$(CONFIG_UNIX_SCM) += scm.o
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index b1a7261..e195a53 100755
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -118,6 +118,8 @@
#include <linux/security.h>
#include <linux/freezer.h>
+#include "scm.h"
+
struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE];
EXPORT_SYMBOL_GPL(unix_socket_table);
DEFINE_SPINLOCK(unix_table_lock);
@@ -1495,78 +1497,51 @@
return err;
}
-static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+static void unix_peek_fds(struct scm_cookie *scm, struct sk_buff *skb)
{
- int i;
-
- scm->fp = UNIXCB(skb).fp;
- UNIXCB(skb).fp = NULL;
-
- for (i = scm->fp->count-1; i >= 0; i--)
- unix_notinflight(scm->fp->user, scm->fp->fp[i]);
-}
-
-static void unix_destruct_scm(struct sk_buff *skb)
-{
- struct scm_cookie scm;
- memset(&scm, 0, sizeof(scm));
- scm.pid = UNIXCB(skb).pid;
- if (UNIXCB(skb).fp)
- unix_detach_fds(&scm, skb);
-
- /* Alas, it calls VFS */
- /* So fscking what? fput() had been SMP-safe since the last Summer */
- scm_destroy(&scm);
- sock_wfree(skb);
-}
-
-/*
- * The "user->unix_inflight" variable is protected by the garbage
- * collection lock, and we just read it locklessly here. If you go
- * over the limit, there might be a tiny race in actually noticing
- * it across threads. Tough.
- */
-static inline bool too_many_unix_fds(struct task_struct *p)
-{
- struct user_struct *user = current_user();
-
- if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
- return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
- return false;
-}
-
-#define MAX_RECURSION_LEVEL 4
-
-static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
-{
- int i;
- unsigned char max_level = 0;
-
- if (too_many_unix_fds(current))
- return -ETOOMANYREFS;
-
- for (i = scm->fp->count - 1; i >= 0; i--) {
- struct sock *sk = unix_get_socket(scm->fp->fp[i]);
-
- if (sk)
- max_level = max(max_level,
- unix_sk(sk)->recursion_level);
- }
- if (unlikely(max_level > MAX_RECURSION_LEVEL))
- return -ETOOMANYREFS;
+ scm->fp = scm_fp_dup(UNIXCB(skb).fp);
/*
- * Need to duplicate file references for the sake of garbage
- * collection. Otherwise a socket in the fps might become a
- * candidate for GC while the skb is not yet queued.
+ * Garbage collection of unix sockets starts by selecting a set of
+ * candidate sockets which have reference only from being in flight
+ * (total_refs == inflight_refs). This condition is checked once during
+ * the candidate collection phase, and candidates are marked as such, so
+ * that non-candidates can later be ignored. While inflight_refs is
+ * protected by unix_gc_lock, total_refs (file count) is not, hence this
+ * is an instantaneous decision.
+ *
+ * Once a candidate, however, the socket must not be reinstalled into a
+ * file descriptor while the garbage collection is in progress.
+ *
+ * If the above conditions are met, then the directed graph of
+ * candidates (*) does not change while unix_gc_lock is held.
+ *
+ * Any operations that changes the file count through file descriptors
+ * (dup, close, sendmsg) does not change the graph since candidates are
+ * not installed in fds.
+ *
+ * Dequeing a candidate via recvmsg would install it into an fd, but
+ * that takes unix_gc_lock to decrement the inflight count, so it's
+ * serialized with garbage collection.
+ *
+ * MSG_PEEK is special in that it does not change the inflight count,
+ * yet does install the socket into an fd. The following lock/unlock
+ * pair is to ensure serialization with garbage collection. It must be
+ * done between incrementing the file count and installing the file into
+ * an fd.
+ *
+ * If garbage collection starts after the barrier provided by the
+ * lock/unlock, then it will see the elevated refcount and not mark this
+ * as a candidate. If a garbage collection is already in progress
+ * before the file count was incremented, then the lock/unlock pair will
+ * ensure that garbage collection is finished before progressing to
+ * installing the fd.
+ *
+ * (*) A -> B where B is on the queue of A or B is on the queue of C
+ * which is on the queue of listening socket A.
*/
- UNIXCB(skb).fp = scm_fp_dup(scm->fp);
- if (!UNIXCB(skb).fp)
- return -ENOMEM;
-
- for (i = scm->fp->count - 1; i >= 0; i--)
- unix_inflight(scm->fp->user, scm->fp->fp[i]);
- return max_level;
+ spin_lock(&unix_gc_lock);
+ spin_unlock(&unix_gc_lock);
}
static int unix_scm_to_skb(struct scm_cookie *scm, struct sk_buff *skb, bool send_fds)
@@ -2193,7 +2168,7 @@
sk_peek_offset_fwd(sk, size);
if (UNIXCB(skb).fp)
- scm.fp = scm_fp_dup(UNIXCB(skb).fp);
+ unix_peek_fds(&scm, skb);
}
err = (flags & MSG_TRUNC) ? skb->len - skip : size;
@@ -2438,7 +2413,7 @@
/* It is questionable, see note in unix_dgram_recvmsg.
*/
if (UNIXCB(skb).fp)
- scm.fp = scm_fp_dup(UNIXCB(skb).fp);
+ unix_peek_fds(&scm, skb);
sk_peek_offset_fwd(sk, chunk);
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
index c36757e..8bbe1b8 100755
--- a/net/unix/garbage.c
+++ b/net/unix/garbage.c
@@ -86,77 +86,13 @@
#include <net/scm.h>
#include <net/tcp_states.h>
+#include "scm.h"
+
/* Internal data structures and random procedures: */
-static LIST_HEAD(gc_inflight_list);
static LIST_HEAD(gc_candidates);
-static DEFINE_SPINLOCK(unix_gc_lock);
static DECLARE_WAIT_QUEUE_HEAD(unix_gc_wait);
-unsigned int unix_tot_inflight;
-
-struct sock *unix_get_socket(struct file *filp)
-{
- struct sock *u_sock = NULL;
- struct inode *inode = file_inode(filp);
-
- /* Socket ? */
- if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
- struct socket *sock = SOCKET_I(inode);
- struct sock *s = sock->sk;
-
- /* PF_UNIX ? */
- if (s && sock->ops && sock->ops->family == PF_UNIX)
- u_sock = s;
- }
- return u_sock;
-}
-
-/* Keep the number of times in flight count for the file
- * descriptor if it is for an AF_UNIX socket.
- */
-
-void unix_inflight(struct user_struct *user, struct file *fp)
-{
- struct sock *s = unix_get_socket(fp);
-
- spin_lock(&unix_gc_lock);
-
- if (s) {
- struct unix_sock *u = unix_sk(s);
-
- if (atomic_long_inc_return(&u->inflight) == 1) {
- BUG_ON(!list_empty(&u->link));
- list_add_tail(&u->link, &gc_inflight_list);
- } else {
- BUG_ON(list_empty(&u->link));
- }
- unix_tot_inflight++;
- }
- user->unix_inflight++;
- spin_unlock(&unix_gc_lock);
-}
-
-void unix_notinflight(struct user_struct *user, struct file *fp)
-{
- struct sock *s = unix_get_socket(fp);
-
- spin_lock(&unix_gc_lock);
-
- if (s) {
- struct unix_sock *u = unix_sk(s);
-
- BUG_ON(!atomic_long_read(&u->inflight));
- BUG_ON(list_empty(&u->link));
-
- if (atomic_long_dec_and_test(&u->inflight))
- list_del_init(&u->link);
- unix_tot_inflight--;
- }
- user->unix_inflight--;
- spin_unlock(&unix_gc_lock);
-}
-
static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
struct sk_buff_head *hitlist)
{
diff --git a/net/unix/scm.c b/net/unix/scm.c
new file mode 100755
index 0000000..df8f636
--- /dev/null
+++ b/net/unix/scm.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/socket.h>
+#include <linux/net.h>
+#include <linux/fs.h>
+#include <net/af_unix.h>
+#include <net/scm.h>
+#include <linux/init.h>
+
+#include "scm.h"
+
+unsigned int unix_tot_inflight;
+EXPORT_SYMBOL(unix_tot_inflight);
+
+LIST_HEAD(gc_inflight_list);
+EXPORT_SYMBOL(gc_inflight_list);
+
+DEFINE_SPINLOCK(unix_gc_lock);
+EXPORT_SYMBOL(unix_gc_lock);
+
+struct sock *unix_get_socket(struct file *filp)
+{
+ struct sock *u_sock = NULL;
+ struct inode *inode = file_inode(filp);
+
+ /* Socket ? */
+ if (S_ISSOCK(inode->i_mode) && !(filp->f_mode & FMODE_PATH)) {
+ struct socket *sock = SOCKET_I(inode);
+ struct sock *s = sock->sk;
+
+ /* PF_UNIX ? */
+ if (s && sock->ops && sock->ops->family == PF_UNIX)
+ u_sock = s;
+ }
+ return u_sock;
+}
+EXPORT_SYMBOL(unix_get_socket);
+
+/* Keep the number of times in flight count for the file
+ * descriptor if it is for an AF_UNIX socket.
+ */
+void unix_inflight(struct user_struct *user, struct file *fp)
+{
+ struct sock *s = unix_get_socket(fp);
+
+ spin_lock(&unix_gc_lock);
+
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+ if (atomic_long_inc_return(&u->inflight) == 1) {
+ BUG_ON(!list_empty(&u->link));
+ list_add_tail(&u->link, &gc_inflight_list);
+ } else {
+ BUG_ON(list_empty(&u->link));
+ }
+ unix_tot_inflight++;
+ }
+ user->unix_inflight++;
+ spin_unlock(&unix_gc_lock);
+}
+
+void unix_notinflight(struct user_struct *user, struct file *fp)
+{
+ struct sock *s = unix_get_socket(fp);
+
+ spin_lock(&unix_gc_lock);
+
+ if (s) {
+ struct unix_sock *u = unix_sk(s);
+
+ BUG_ON(!atomic_long_read(&u->inflight));
+ BUG_ON(list_empty(&u->link));
+
+ if (atomic_long_dec_and_test(&u->inflight))
+ list_del_init(&u->link);
+ unix_tot_inflight--;
+ }
+ user->unix_inflight--;
+ spin_unlock(&unix_gc_lock);
+}
+
+/*
+ * The "user->unix_inflight" variable is protected by the garbage
+ * collection lock, and we just read it locklessly here. If you go
+ * over the limit, there might be a tiny race in actually noticing
+ * it across threads. Tough.
+ */
+static inline bool too_many_unix_fds(struct task_struct *p)
+{
+ struct user_struct *user = current_user();
+
+ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
+ return false;
+}
+
+#define MAX_RECURSION_LEVEL 4
+
+int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+{
+ int i;
+ unsigned char max_level = 0;
+
+ if (too_many_unix_fds(current))
+ return -ETOOMANYREFS;
+
+ for (i = scm->fp->count - 1; i >= 0; i--) {
+ struct sock *sk = unix_get_socket(scm->fp->fp[i]);
+
+ if (sk)
+ max_level = max(max_level,
+ unix_sk(sk)->recursion_level);
+ }
+ if (unlikely(max_level > MAX_RECURSION_LEVEL))
+ return -ETOOMANYREFS;
+
+ /*
+ * Need to duplicate file references for the sake of garbage
+ * collection. Otherwise a socket in the fps might become a
+ * candidate for GC while the skb is not yet queued.
+ */
+ UNIXCB(skb).fp = scm_fp_dup(scm->fp);
+ if (!UNIXCB(skb).fp)
+ return -ENOMEM;
+
+ for (i = scm->fp->count - 1; i >= 0; i--)
+ unix_inflight(scm->fp->user, scm->fp->fp[i]);
+ return max_level;
+}
+EXPORT_SYMBOL(unix_attach_fds);
+
+void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
+{
+ int i;
+
+ scm->fp = UNIXCB(skb).fp;
+ UNIXCB(skb).fp = NULL;
+
+ for (i = scm->fp->count-1; i >= 0; i--)
+ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
+}
+EXPORT_SYMBOL(unix_detach_fds);
+
+void unix_destruct_scm(struct sk_buff *skb)
+{
+ struct scm_cookie scm;
+
+ memset(&scm, 0, sizeof(scm));
+ scm.pid = UNIXCB(skb).pid;
+ if (UNIXCB(skb).fp)
+ unix_detach_fds(&scm, skb);
+
+ /* Alas, it calls VFS */
+ /* So fscking what? fput() had been SMP-safe since the last Summer */
+ scm_destroy(&scm);
+ sock_wfree(skb);
+}
+EXPORT_SYMBOL(unix_destruct_scm);
diff --git a/net/unix/scm.h b/net/unix/scm.h
new file mode 100755
index 0000000..5a255a4
--- /dev/null
+++ b/net/unix/scm.h
@@ -0,0 +1,10 @@
+#ifndef NET_UNIX_SCM_H
+#define NET_UNIX_SCM_H
+
+extern struct list_head gc_inflight_list;
+extern spinlock_t unix_gc_lock;
+
+int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb);
+void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb);
+
+#endif
diff --git a/security/samsung/defex_lsm/Kconfig b/security/samsung/defex_lsm/Kconfig
index f263845..1ed27b1 100755
--- a/security/samsung/defex_lsm/Kconfig
+++ b/security/samsung/defex_lsm/Kconfig
@@ -16,7 +16,7 @@
config DEFEX_KERNEL_ONLY
bool "Defex Kernel Only"
depends on SECURITY_DEFEX
- default y
+ default n
help
This lets defex know whether kernel-only build or not.
Default value will be set to "y" if the build is kernel-only.
diff --git a/security/samsung/defex_lsm/build_defex_log b/security/samsung/defex_lsm/build_defex_log
new file mode 100755
index 0000000..fc14ead
--- /dev/null
+++ b/security/samsung/defex_lsm/build_defex_log
@@ -0,0 +1 @@
+enable_build_allowlist
diff --git a/security/samsung/defex_lsm/defex_rules.c b/security/samsung/defex_lsm/defex_rules.c
index 26ef959..6b21aa5 100755
--- a/security/samsung/defex_lsm/defex_rules.c
+++ b/security/samsung/defex_lsm/defex_rules.c
@@ -14,6 +14,213 @@
{feature_immutable_status,"1"},
{feature_ped_status,"1"},
#ifndef DEFEX_USE_PACKED_RULES
+ {feature_ped_exception,"/system/bin/run-as"}, /* DEFAULT */
+ {feature_ped_exception,"/system/bin/dumpstate"}, /* DEFAULT */
+ {feature_safeplace_path,"/init"},
+ {feature_safeplace_path,"/system/bin/init"},
+ {feature_safeplace_path,"/system/bin/app_process32"},
+ {feature_safeplace_path,"/system/bin/app_process64"},
+ {feature_safeplace_path,"/system/bin/blkid"},
+ {feature_safeplace_path,"/system/bin/clatd"},
+ {feature_safeplace_path,"/system/bin/cmd"},
+ {feature_safeplace_path,"/system/bin/corehelper.sh"},
+ {feature_safeplace_path,"/system/bin/crash_dump32"},
+ {feature_safeplace_path,"/system/bin/crash_dump64"},
+ {feature_safeplace_path,"/system/bin/debuggerd"},
+ {feature_safeplace_path,"/system/bin/dnsmasq"},
+ {feature_safeplace_path,"/system/bin/dsms"},
+ {feature_safeplace_path,"/system/bin/dumpstate"},
+ {feature_safeplace_path,"/system/bin/fsck.vfat"},
+ {feature_safeplace_path,"/system/bin/fsck.exfat"},
+ {feature_safeplace_path,"/system/bin/gatekeeperd"},
+ {feature_safeplace_path,"/system/bin/healthd"},
+ {feature_safeplace_path,"/system/bin/installd"},
+ {feature_safeplace_path,"/system/bin/iod"},
+ {feature_safeplace_path,"/system/bin/ip"},
+ {feature_safeplace_path,"/system/bin/iptables"},
+ {feature_safeplace_path,"/system/bin/iptables-restore"},
+ {feature_safeplace_path,"/system/bin/ip6tables"},
+ {feature_safeplace_path,"/system/bin/ip6tables-restore"},
+ {feature_safeplace_path,"/system/bin/lmkd"},
+ {feature_safeplace_path,"/system/bin/lshal"},
+ {feature_safeplace_path,"/system/bin/mdf_fota"},
+ {feature_safeplace_path,"/system/bin/mkfs.vfat"},
+ {feature_safeplace_path,"/system/bin/mkfs.exfat"},
+ {feature_safeplace_path,"/system/bin/netd"},
+ {feature_safeplace_path,"/system/bin/nst"},
+ {feature_safeplace_path,"/system/bin/perfmond"},
+ {feature_safeplace_path,"/system/bin/perfprofd"},
+ {feature_safeplace_path,"/system/bin/sgdisk"},
+ {feature_safeplace_path,"/system/bin/sh"},
+ {feature_safeplace_path,"/system/bin/ss"},
+ {feature_safeplace_path,"/system/bin/storaged"},
+ {feature_safeplace_path,"/system/bin/tc"},
+ {feature_safeplace_path,"/system/bin/uncrypt"},
+ {feature_safeplace_path,"/system/bin/vold"},
+ {feature_safeplace_path,"/system/bin/webview_zygote32"},
+ {feature_safeplace_path,"/system/bin/grep"},
+ {feature_safeplace_path,"/system/bin/e2fsck"},
+ {feature_safeplace_path,"/system/bin/scs"},
+ {feature_safeplace_path,"/system/bin/vdc"},
+ {feature_safeplace_path,"/system/bin/vaultkeeperd"},
+ {feature_safeplace_path,"/system/bin/prepare_param.sh"},
+ {feature_safeplace_path,"/system/bin/smdexe"},
+ {feature_safeplace_path,"/system/bin/diagexe"},
+ {feature_safeplace_path,"/system/bin/ddexe"},
+ {feature_safeplace_path,"/system/bin/connfwexe"},
+ {feature_safeplace_path,"/system/bin/at_distributor"},
+ {feature_safeplace_path,"/system/bin/sdcard"},
+ {feature_safeplace_path,"/system/bin/resetreason"},
+ {feature_safeplace_path,"/system/bin/lpm"},
+ {feature_safeplace_path,"/system/bin/resize2fs"},
+ {feature_safeplace_path,"/system/bin/tune2fs"},
+ {feature_safeplace_path,"/system/bin/patchoat"},
+ {feature_safeplace_path,"/system/bin/knox_changer"},
+ {feature_safeplace_path,"/system/bin/knox_changer_recovery"},
+ {feature_safeplace_path,"/sbin/sswap"},
+ {feature_safeplace_path,"/sbin/cbd"},
+ {feature_safeplace_path,"/sbin/adbd"},
+ {feature_safeplace_path,"/sbin/recovery"},
+ {feature_safeplace_path,"/sbin/mke2fs_static"},
+ {feature_safeplace_path,"/vendor/bin/hw/wpa_supplicant"},
+ {feature_safeplace_path,"/vendor/bin/hw/macloader"},
+ {feature_safeplace_path,"/vendor/bin/hw/mfgloader"},
+ {feature_safeplace_path,"/sbin/dm_verity_hash"},
+ {feature_safeplace_path,"/sbin/dm_verity_signature_checker"},
+ {feature_safeplace_path,"/vendor/bin/qseecomd"},
+ {feature_safeplace_path,"/system/bin/vold_prepare_subdirs"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.early_boot.sh"},
+ {feature_safeplace_path,"/vendor/bin/toybox_vendor"},
+ {feature_safeplace_path,"/vendor/bin/toolbox"},
+ {feature_safeplace_path,"/vendor/bin/hw/android.hardware.usb@1.1-service.wahoo"},
+ {feature_safeplace_path,"/vendor/bin/hw/vendor.qti.hardware.iop@2.0-service"},
+ {feature_safeplace_path,"/vendor/bin/hw/vendor.qti.hardware.perf@1.0-service"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.class_core.sh"},
+ {feature_safeplace_path,"/vendor/bin/irsc_util"},
+ {feature_safeplace_path,"/vendor/bin/rmt_storage"},
+ {feature_safeplace_path,"/system/bin/toybox"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.usb.sh"},
+ {feature_safeplace_path,"/vendor/bin/tftp_server"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.sensors.sh"},
+ {feature_safeplace_path,"/system/bin/insthk"},
+ {feature_safeplace_path,"/vendor/bin/init.class_main.sh"},
+ {feature_safeplace_path,"/vendor/bin/time_daemon"},
+ {feature_safeplace_path,"/vendor/bin/thermal-engine"},
+ {feature_safeplace_path,"/system/bin/sec_diag_uart_log"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.sh"},
+ {feature_safeplace_path,"/system/bin/usbd"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.post_boot.sh"},
+ {feature_safeplace_path,"/system/bin/adbd"},
+ {feature_safeplace_path,"/system/bin/atrace"},
+ {feature_safeplace_path,"/system/bin/fsdbg"},
+ {feature_safeplace_path,"/system/bin/dumpsys"},
+ {feature_safeplace_path,"/system/bin/logcat"},
+ {feature_safeplace_path,"/system/bin/toolbox"},
+ {feature_safeplace_path,"/system/bin/mke2fs"},
+ {feature_safeplace_path,"/vendor/bin/cbd"},
+ {feature_safeplace_path,"/vendor/bin/adsprpcd"},
+ {feature_safeplace_path,"/sbin/e2fsdroid_static"},
+ {feature_safeplace_path,"/system/bin/e2fsdroid"},
+ {feature_safeplace_path,"/system/bin/fsck.f2fs"},
+ {feature_safeplace_path,"/system/bin/make_f2fs"},
+ {feature_safeplace_path,"/system/bin/sload_f2fs"},
+ {feature_safeplace_path,"/system/bin/bpfloader"},
+ {feature_safeplace_path,"/system/bin/wait_for_keymaster"},
+ {feature_safeplace_path,"/system/bin/secdiscard"},
+ {feature_safeplace_path,"/system/bin/idledefrag"},
+ {feature_safeplace_path,"/vendor/bin/init.mdm.sh"},
+ {feature_safeplace_path,"/vendor/bin/mdm_helper"},
+ {feature_safeplace_path,"/vendor/bin/ks"},
+ {feature_safeplace_path,"/vendor/bin/sh"},
+ {feature_safeplace_path,"/system/bin/e4defrag"},
+ {feature_safeplace_path,"/sbin/dm_verity_tz_cmd"},
+ {feature_safeplace_path,"/sbin/mcDriverDaemon_static"},
+ {feature_safeplace_path,"/sbin/qseecomfsd"},
+ {feature_safeplace_path,"/sbin/tzdaemon_recovery"},
+ {feature_safeplace_path,"/vendor/bin/hvdcp_opti"},
+ {feature_safeplace_path,"/sbin/mkfs.f2fs"},
+ {feature_safeplace_path,"/sbin/sload.f2fs"},
+ {feature_safeplace_path,"/system/bin/secilc"},
+ {feature_safeplace_path,"/system/bin/apexd"},
+ {feature_safeplace_path,"/system/bin/art_apex_boot_integrity"},
+ {feature_safeplace_path,"/system/bin/gsid"},
+ {feature_safeplace_path,"/system/bin/idmap2"},
+ {feature_safeplace_path,"/system/bin/charger"},
+ {feature_safeplace_path,"/system/bin/recovery"},
+ {feature_safeplace_path,"/system/bin/watchdogd"},
+ {feature_safeplace_path,"/vendor/bin/hw/vendor.qti.hardware.perf@2.0-service"},
+ {feature_safeplace_path,"/system/bin/netutils-wrapper-1.0"},
+ {feature_safeplace_path,"/system/bin/bugreport"},
+ {feature_safeplace_path,"/system/bin/minadbd"},
+ {feature_safeplace_path,"/system/bin/migrate_legacy_obb_data.sh"},
+ {feature_safeplace_path,"/vendor/bin/shsusrd"},
+ {feature_safeplace_path,"/system/bin/defrag_f2fs"},
+ {feature_safeplace_path,"/system/bin/fastbootd"},
+ {feature_safeplace_path,"/vendor/bin/hw/vendor.qti.hardware.perf@2.1-service"},
+ {feature_safeplace_path,"/vendor/bin/hw/vendor.qti.hardware.perf@2.2-service"},
+ {feature_safeplace_path,"/vendor/bin/grep"},
+ {feature_safeplace_path,"/system/bin/rdxd"},
+ {feature_safeplace_path,"/system/system_ext/bin/dpmd"},
+ {feature_safeplace_path,"/vendor/bin/init.qti.dcvs.sh"},
+ {feature_safeplace_path,"/vendor/bin/vendor_modprobe.sh"},
+ {feature_safeplace_path,"/vendor/bin/init.qti.qcv.sh"},
+ {feature_safeplace_path,"/vendor/bin/init.qcom.crashdata.sh"},
+ {feature_safeplace_path,"/vendor/bin/energy-awareness"},
+ {feature_safeplace_path,"/vendor/bin/qcom-system-daemon"},
+ {feature_safeplace_path,"/vendor/bin/init.qti.kernel.sh"},
+ {feature_safeplace_path,"/vendor/bin/init.kernel.post_boot.sh"},
+ {feature_safeplace_path,"/vendor/bin/init.kernel.post_boot-lahaina.sh"},
+ {feature_safeplace_path,"/vendor/bin/init.qti.keymaster.sh"},
+ {feature_safeplace_path,"/vendor/bin/thermal_manager"},
+ {feature_safeplace_path,"/system/bin/linkerconfig"},
+ {feature_safeplace_path,"/system/bin/snapshotctl"},
+ {feature_safeplace_path,"/system/bin/boringssl_self_test32"},
+ {feature_safeplace_path,"/system/bin/boringssl_self_test64"},
+ {feature_safeplace_path,"/vendor/bin/boringssl_self_test32"},
+ {feature_safeplace_path,"/vendor/bin/boringssl_self_test64"},
+ {feature_safeplace_path,"/apex/com.android.adbd/bin/adbd"},
+ {feature_safeplace_path,"/apex/com.android.sdkext/bin/derive_sdk"},
+ {feature_safeplace_path,"/apex/com.android.conscrypt/bin/boringssl_self_test32"},
+ {feature_safeplace_path,"/apex/com.android.conscrypt/bin/boringssl_self_test64"},
+ {feature_safeplace_path,"/system/bin/applypatch"},
+ {feature_safeplace_path,"/vendor/bin/applypatch"},
+ {feature_safeplace_path,"/system/bin/clean_scratch_files"},
+ {feature_safeplace_path,"/system/bin/fsverity"},
+ {feature_safeplace_path,"/system/bin/fsverity_init"},
+ {feature_safeplace_path,"/system/xbin/librank"},
+ {feature_safeplace_path,"/system/xbin/procrank"},
+ {feature_safeplace_path,"/system/xbin/showmap"},
+ {feature_safeplace_path,"/system/bin/librank"},
+ {feature_safeplace_path,"/system/bin/procrank"},
+ {feature_safeplace_path,"/system/bin/showmap"},
+ {feature_safeplace_path,"/product/bin/dmabuf_dump"},
+ {feature_safeplace_path,"/apex/com.android.runtime/bin/spqr"},
+ {feature_safeplace_path,"/system/bin/perfetto"},
+ {feature_safeplace_path,"/tmp/update_binary"},
+ {feature_safeplace_path,"/tmp/update-binary"},
+ {feature_safeplace_path,"/system/bin/install-recovery.sh"}, /* DEFAULT */
+ {feature_safeplace_path,"/vendor/bin/install-recovery.sh"}, /* DEFAULT */
+ {feature_immutable_path_write,"/system/"}, /* DEFAULT */
+ {feature_immutable_path_write,"/vendor/"}, /* DEFAULT */
+ {feature_immutable_path_open,"/system/bin/"}, /* DEFAULT */
+ {feature_immutable_path_open,"/vendor/bin/"}, /* DEFAULT */
+ {feature_immutable_src_exception,"/system/bin/icd"},
+ {feature_immutable_src_exception,"/system/bin/iof"},
+ {feature_immutable_src_exception,"/system/bin/sh"},
+ {feature_immutable_src_exception,"/system/bin/app_process32"},
+ {feature_immutable_src_exception,"/system/bin/app_process64"},
+ {feature_immutable_src_exception,"/system/bin/crash_dump32"},
+ {feature_immutable_src_exception,"/system/bin/crash_dump64"},
+ {feature_immutable_src_exception,"/system/bin/mediaextractor"},
+ {feature_immutable_src_exception,"/system/bin/surfaceflinger"},
+ {feature_immutable_src_exception,"/vendor/bin/sh"},
+ {feature_immutable_src_exception,"/vendor/bin/hw/android.hardware.media.omx@1.0-service"},
+ {feature_immutable_src_exception,"/vendor/bin/snap_utility_32"},
+ {feature_immutable_src_exception,"/vendor/bin/snap_utility_64"},
+ {feature_immutable_src_exception,"/vendor/bin/icd_vendor"},
+ {feature_immutable_src_exception,"/vendor/bin/iof_vendor"},
+ {feature_immutable_src_exception,"/init"},
+ {feature_immutable_src_exception,"/system/bin/init"},
/* Rules will be added here */
/* Never modify the above line. Rules will be added for buildtime */
#endif /* DEFEX_USE_PACKED_RULES */
diff --git a/security/samsung/dsms/Makefile b/security/samsung/dsms/Makefile
index 2cacda3..05c8dab 100755
--- a/security/samsung/dsms/Makefile
+++ b/security/samsung/dsms/Makefile
@@ -23,5 +23,4 @@
ifeq ($(CONFIG_KUNIT), y)
GCOV_PROFILE := y
ccflags-y += -DDSMS_KUNIT_ENABLED
- obj-$(CONFIG_SECURITY_DSMS) += kunit_test/
endif
diff --git a/security/samsung/dsms/dsms_policy.c b/security/samsung/dsms/dsms_policy.c
index 61c2ffe..93e428d 100755
--- a/security/samsung/dsms/dsms_policy.c
+++ b/security/samsung/dsms/dsms_policy.c
@@ -14,6 +14,9 @@
// vvvvv DO NOT CHANGE THESE LINES! vvvvv
struct dsms_policy_entry dsms_policy[] = {
+{ "security/samsung/defex_lsm/core/defex_main.c", "defex_report_violation" },
+{ "security/samsung/five/five_audit.c", "five_audit_sign_err" },
+{ "security/samsung/five/five_dsms.c", "five_dsms_msg" },
}; // dsms_policy
// ^^^^^ DO NOT CHANGE THESE LINES! ^^^^^
diff --git a/security/sdp/sdp_mm.c b/security/sdp/sdp_mm.c
index d373381..045b820 100755
--- a/security/sdp/sdp_mm.c
+++ b/security/sdp/sdp_mm.c
Binary files differ
diff --git a/security/security.c b/security/security.c
index 371e1c4..eec3c5d 100755
--- a/security/security.c
+++ b/security/security.c
@@ -136,25 +136,25 @@
/* Security operations */
-int security_binder_set_context_mgr(struct task_struct *mgr)
+int security_binder_set_context_mgr(const struct cred *mgr)
{
return call_int_hook(binder_set_context_mgr, 0, mgr);
}
-int security_binder_transaction(struct task_struct *from,
- struct task_struct *to)
+int security_binder_transaction(const struct cred *from,
+ const struct cred *to)
{
return call_int_hook(binder_transaction, 0, from, to);
}
-int security_binder_transfer_binder(struct task_struct *from,
- struct task_struct *to)
+int security_binder_transfer_binder(const struct cred *from,
+ const struct cred *to)
{
return call_int_hook(binder_transfer_binder, 0, from, to);
}
-int security_binder_transfer_file(struct task_struct *from,
- struct task_struct *to, struct file *file)
+int security_binder_transfer_file(const struct cred *from,
+ const struct cred *to, struct file *file)
{
return call_int_hook(binder_transfer_file, 0, from, to, file);
}
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index b141da7..890e562 100755
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -2184,21 +2184,18 @@
/* Hook functions begin here. */
-static int selinux_binder_set_context_mgr(struct task_struct *mgr)
+static int selinux_binder_set_context_mgr(const struct cred *mgr)
{
- u32 mysid = current_sid();
- u32 mgrsid = task_sid(mgr);
-
- return avc_has_perm(mysid, mgrsid, SECCLASS_BINDER,
+ return avc_has_perm(current_sid(), cred_sid(mgr), SECCLASS_BINDER,
BINDER__SET_CONTEXT_MGR, NULL);
}
-static int selinux_binder_transaction(struct task_struct *from,
- struct task_struct *to)
+static int selinux_binder_transaction(const struct cred *from,
+ const struct cred *to)
{
u32 mysid = current_sid();
- u32 fromsid = task_sid(from);
- u32 tosid = task_sid(to);
+ u32 fromsid = cred_sid(from);
+ u32 tosid = cred_sid(to);
int rc;
if (mysid != fromsid) {
@@ -2212,21 +2209,19 @@
NULL);
}
-static int selinux_binder_transfer_binder(struct task_struct *from,
- struct task_struct *to)
+static int selinux_binder_transfer_binder(const struct cred *from,
+ const struct cred *to)
{
- u32 fromsid = task_sid(from);
- u32 tosid = task_sid(to);
-
- return avc_has_perm(fromsid, tosid, SECCLASS_BINDER, BINDER__TRANSFER,
+ return avc_has_perm(cred_sid(from), cred_sid(to),
+ SECCLASS_BINDER, BINDER__TRANSFER,
NULL);
}
-static int selinux_binder_transfer_file(struct task_struct *from,
- struct task_struct *to,
+static int selinux_binder_transfer_file(const struct cred *from,
+ const struct cred *to,
struct file *file)
{
- u32 sid = task_sid(to);
+ u32 sid = cred_sid(to);
struct file_security_struct *fsec = file->f_security;
struct dentry *dentry = file->f_path.dentry;
struct inode_security_struct *isec;