mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 08:31:13 +00:00
Merge branch 'next' into for-linus
This commit is contained in:
commit
434d42cfd0
25 changed files with 205 additions and 64 deletions
|
@ -820,6 +820,8 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
|
||||||
int res;
|
int res;
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
|
memset(&bprm, 0, sizeof(bprm));
|
||||||
|
|
||||||
/* Create the file name */
|
/* Create the file name */
|
||||||
sprintf(buf, "/lib/lib%d.so", id);
|
sprintf(buf, "/lib/lib%d.so", id);
|
||||||
|
|
||||||
|
@ -835,6 +837,12 @@ static int load_flat_shared_library(int id, struct lib_info *libs)
|
||||||
if (!bprm.cred)
|
if (!bprm.cred)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
|
/* We don't really care about recalculating credentials at this point
|
||||||
|
* as we're past the point of no return and are dealing with shared
|
||||||
|
* libraries.
|
||||||
|
*/
|
||||||
|
bprm.cred_prepared = 1;
|
||||||
|
|
||||||
res = prepare_binprm(&bprm);
|
res = prepare_binprm(&bprm);
|
||||||
|
|
||||||
if (!IS_ERR_VALUE(res))
|
if (!IS_ERR_VALUE(res))
|
||||||
|
|
|
@ -417,7 +417,6 @@ extern const kernel_cap_t __cap_init_eff_set;
|
||||||
|
|
||||||
# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
|
# define CAP_EMPTY_SET ((kernel_cap_t){{ 0, 0 }})
|
||||||
# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }})
|
# define CAP_FULL_SET ((kernel_cap_t){{ ~0, ~0 }})
|
||||||
# define CAP_INIT_EFF_SET ((kernel_cap_t){{ ~CAP_TO_MASK(CAP_SETPCAP), ~0 }})
|
|
||||||
# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
|
# define CAP_FS_SET ((kernel_cap_t){{ CAP_FS_MASK_B0 \
|
||||||
| CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
|
| CAP_TO_MASK(CAP_LINUX_IMMUTABLE), \
|
||||||
CAP_FS_MASK_B1 } })
|
CAP_FS_MASK_B1 } })
|
||||||
|
@ -427,11 +426,7 @@ extern const kernel_cap_t __cap_init_eff_set;
|
||||||
|
|
||||||
#endif /* _KERNEL_CAPABILITY_U32S != 2 */
|
#endif /* _KERNEL_CAPABILITY_U32S != 2 */
|
||||||
|
|
||||||
#define CAP_INIT_INH_SET CAP_EMPTY_SET
|
|
||||||
|
|
||||||
# define cap_clear(c) do { (c) = __cap_empty_set; } while (0)
|
# define cap_clear(c) do { (c) = __cap_empty_set; } while (0)
|
||||||
# define cap_set_full(c) do { (c) = __cap_full_set; } while (0)
|
|
||||||
# define cap_set_init_eff(c) do { (c) = __cap_init_eff_set; } while (0)
|
|
||||||
|
|
||||||
#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag))
|
#define cap_raise(c, flag) ((c).cap[CAP_TO_INDEX(flag)] |= CAP_TO_MASK(flag))
|
||||||
#define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag))
|
#define cap_lower(c, flag) ((c).cap[CAP_TO_INDEX(flag)] &= ~CAP_TO_MASK(flag))
|
||||||
|
|
|
@ -83,13 +83,6 @@ extern struct group_info init_groups;
|
||||||
#define INIT_IDS
|
#define INIT_IDS
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*
|
|
||||||
* Because of the reduced scope of CAP_SETPCAP when filesystem
|
|
||||||
* capabilities are in effect, it is safe to allow CAP_SETPCAP to
|
|
||||||
* be available in the default configuration.
|
|
||||||
*/
|
|
||||||
# define CAP_INIT_BSET CAP_FULL_SET
|
|
||||||
|
|
||||||
#ifdef CONFIG_RCU_BOOST
|
#ifdef CONFIG_RCU_BOOST
|
||||||
#define INIT_TASK_RCU_BOOST() \
|
#define INIT_TASK_RCU_BOOST() \
|
||||||
.rcu_boost_mutex = NULL,
|
.rcu_boost_mutex = NULL,
|
||||||
|
|
|
@ -276,6 +276,19 @@ static inline key_serial_t key_serial(struct key *key)
|
||||||
return key ? key->serial : 0;
|
return key ? key->serial : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* key_is_instantiated - Determine if a key has been positively instantiated
|
||||||
|
* @key: The key to check.
|
||||||
|
*
|
||||||
|
* Return true if the specified key has been positively instantiated, false
|
||||||
|
* otherwise.
|
||||||
|
*/
|
||||||
|
static inline bool key_is_instantiated(const struct key *key)
|
||||||
|
{
|
||||||
|
return test_bit(KEY_FLAG_INSTANTIATED, &key->flags) &&
|
||||||
|
!test_bit(KEY_FLAG_NEGATIVE, &key->flags);
|
||||||
|
}
|
||||||
|
|
||||||
#define rcu_dereference_key(KEY) \
|
#define rcu_dereference_key(KEY) \
|
||||||
(rcu_dereference_protected((KEY)->payload.rcudata, \
|
(rcu_dereference_protected((KEY)->payload.rcudata, \
|
||||||
rwsem_is_locked(&((struct key *)(KEY))->sem)))
|
rwsem_is_locked(&((struct key *)(KEY))->sem)))
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
#include <linux/compiler.h>
|
#include <linux/compiler.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
#include <linux/sysctl.h>
|
||||||
|
|
||||||
#define KMOD_PATH_LEN 256
|
#define KMOD_PATH_LEN 256
|
||||||
|
|
||||||
|
@ -109,6 +110,8 @@ call_usermodehelper(char *path, char **argv, char **envp, enum umh_wait wait)
|
||||||
NULL, NULL, NULL);
|
NULL, NULL, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern struct ctl_table usermodehelper_table[];
|
||||||
|
|
||||||
extern void usermodehelper_init(void);
|
extern void usermodehelper_init(void);
|
||||||
|
|
||||||
extern int usermodehelper_disable(void);
|
extern int usermodehelper_disable(void);
|
||||||
|
|
|
@ -22,12 +22,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
|
const kernel_cap_t __cap_empty_set = CAP_EMPTY_SET;
|
||||||
const kernel_cap_t __cap_full_set = CAP_FULL_SET;
|
|
||||||
const kernel_cap_t __cap_init_eff_set = CAP_INIT_EFF_SET;
|
|
||||||
|
|
||||||
EXPORT_SYMBOL(__cap_empty_set);
|
EXPORT_SYMBOL(__cap_empty_set);
|
||||||
EXPORT_SYMBOL(__cap_full_set);
|
|
||||||
EXPORT_SYMBOL(__cap_init_eff_set);
|
|
||||||
|
|
||||||
int file_caps_enabled = 1;
|
int file_caps_enabled = 1;
|
||||||
|
|
||||||
|
|
|
@ -49,10 +49,10 @@ struct cred init_cred = {
|
||||||
.magic = CRED_MAGIC,
|
.magic = CRED_MAGIC,
|
||||||
#endif
|
#endif
|
||||||
.securebits = SECUREBITS_DEFAULT,
|
.securebits = SECUREBITS_DEFAULT,
|
||||||
.cap_inheritable = CAP_INIT_INH_SET,
|
.cap_inheritable = CAP_EMPTY_SET,
|
||||||
.cap_permitted = CAP_FULL_SET,
|
.cap_permitted = CAP_FULL_SET,
|
||||||
.cap_effective = CAP_INIT_EFF_SET,
|
.cap_effective = CAP_FULL_SET,
|
||||||
.cap_bset = CAP_INIT_BSET,
|
.cap_bset = CAP_FULL_SET,
|
||||||
.user = INIT_USER,
|
.user = INIT_USER,
|
||||||
.user_ns = &init_user_ns,
|
.user_ns = &init_user_ns,
|
||||||
.group_info = &init_groups,
|
.group_info = &init_groups,
|
||||||
|
|
100
kernel/kmod.c
100
kernel/kmod.c
|
@ -25,6 +25,7 @@
|
||||||
#include <linux/kmod.h>
|
#include <linux/kmod.h>
|
||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/completion.h>
|
#include <linux/completion.h>
|
||||||
|
#include <linux/cred.h>
|
||||||
#include <linux/file.h>
|
#include <linux/file.h>
|
||||||
#include <linux/fdtable.h>
|
#include <linux/fdtable.h>
|
||||||
#include <linux/workqueue.h>
|
#include <linux/workqueue.h>
|
||||||
|
@ -43,6 +44,13 @@ extern int max_threads;
|
||||||
|
|
||||||
static struct workqueue_struct *khelper_wq;
|
static struct workqueue_struct *khelper_wq;
|
||||||
|
|
||||||
|
#define CAP_BSET (void *)1
|
||||||
|
#define CAP_PI (void *)2
|
||||||
|
|
||||||
|
static kernel_cap_t usermodehelper_bset = CAP_FULL_SET;
|
||||||
|
static kernel_cap_t usermodehelper_inheritable = CAP_FULL_SET;
|
||||||
|
static DEFINE_SPINLOCK(umh_sysctl_lock);
|
||||||
|
|
||||||
#ifdef CONFIG_MODULES
|
#ifdef CONFIG_MODULES
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -132,6 +140,7 @@ EXPORT_SYMBOL(__request_module);
|
||||||
static int ____call_usermodehelper(void *data)
|
static int ____call_usermodehelper(void *data)
|
||||||
{
|
{
|
||||||
struct subprocess_info *sub_info = data;
|
struct subprocess_info *sub_info = data;
|
||||||
|
struct cred *new;
|
||||||
int retval;
|
int retval;
|
||||||
|
|
||||||
spin_lock_irq(¤t->sighand->siglock);
|
spin_lock_irq(¤t->sighand->siglock);
|
||||||
|
@ -153,6 +162,19 @@ static int ____call_usermodehelper(void *data)
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retval = -ENOMEM;
|
||||||
|
new = prepare_kernel_cred(current);
|
||||||
|
if (!new)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
spin_lock(&umh_sysctl_lock);
|
||||||
|
new->cap_bset = cap_intersect(usermodehelper_bset, new->cap_bset);
|
||||||
|
new->cap_inheritable = cap_intersect(usermodehelper_inheritable,
|
||||||
|
new->cap_inheritable);
|
||||||
|
spin_unlock(&umh_sysctl_lock);
|
||||||
|
|
||||||
|
commit_creds(new);
|
||||||
|
|
||||||
retval = kernel_execve(sub_info->path,
|
retval = kernel_execve(sub_info->path,
|
||||||
(const char *const *)sub_info->argv,
|
(const char *const *)sub_info->argv,
|
||||||
(const char *const *)sub_info->envp);
|
(const char *const *)sub_info->envp);
|
||||||
|
@ -420,6 +442,84 @@ unlock:
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(call_usermodehelper_exec);
|
EXPORT_SYMBOL(call_usermodehelper_exec);
|
||||||
|
|
||||||
|
static int proc_cap_handler(struct ctl_table *table, int write,
|
||||||
|
void __user *buffer, size_t *lenp, loff_t *ppos)
|
||||||
|
{
|
||||||
|
struct ctl_table t;
|
||||||
|
unsigned long cap_array[_KERNEL_CAPABILITY_U32S];
|
||||||
|
kernel_cap_t new_cap;
|
||||||
|
int err, i;
|
||||||
|
|
||||||
|
if (write && (!capable(CAP_SETPCAP) ||
|
||||||
|
!capable(CAP_SYS_MODULE)))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert from the global kernel_cap_t to the ulong array to print to
|
||||||
|
* userspace if this is a read.
|
||||||
|
*/
|
||||||
|
spin_lock(&umh_sysctl_lock);
|
||||||
|
for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++) {
|
||||||
|
if (table->data == CAP_BSET)
|
||||||
|
cap_array[i] = usermodehelper_bset.cap[i];
|
||||||
|
else if (table->data == CAP_PI)
|
||||||
|
cap_array[i] = usermodehelper_inheritable.cap[i];
|
||||||
|
else
|
||||||
|
BUG();
|
||||||
|
}
|
||||||
|
spin_unlock(&umh_sysctl_lock);
|
||||||
|
|
||||||
|
t = *table;
|
||||||
|
t.data = &cap_array;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* actually read or write and array of ulongs from userspace. Remember
|
||||||
|
* these are least significant 32 bits first
|
||||||
|
*/
|
||||||
|
err = proc_doulongvec_minmax(&t, write, buffer, lenp, ppos);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* convert from the sysctl array of ulongs to the kernel_cap_t
|
||||||
|
* internal representation
|
||||||
|
*/
|
||||||
|
for (i = 0; i < _KERNEL_CAPABILITY_U32S; i++)
|
||||||
|
new_cap.cap[i] = cap_array[i];
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Drop everything not in the new_cap (but don't add things)
|
||||||
|
*/
|
||||||
|
spin_lock(&umh_sysctl_lock);
|
||||||
|
if (write) {
|
||||||
|
if (table->data == CAP_BSET)
|
||||||
|
usermodehelper_bset = cap_intersect(usermodehelper_bset, new_cap);
|
||||||
|
if (table->data == CAP_PI)
|
||||||
|
usermodehelper_inheritable = cap_intersect(usermodehelper_inheritable, new_cap);
|
||||||
|
}
|
||||||
|
spin_unlock(&umh_sysctl_lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct ctl_table usermodehelper_table[] = {
|
||||||
|
{
|
||||||
|
.procname = "bset",
|
||||||
|
.data = CAP_BSET,
|
||||||
|
.maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
|
||||||
|
.mode = 0600,
|
||||||
|
.proc_handler = proc_cap_handler,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.procname = "inheritable",
|
||||||
|
.data = CAP_PI,
|
||||||
|
.maxlen = _KERNEL_CAPABILITY_U32S * sizeof(unsigned long),
|
||||||
|
.mode = 0600,
|
||||||
|
.proc_handler = proc_cap_handler,
|
||||||
|
},
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
void __init usermodehelper_init(void)
|
void __init usermodehelper_init(void)
|
||||||
{
|
{
|
||||||
khelper_wq = create_singlethread_workqueue("khelper");
|
khelper_wq = create_singlethread_workqueue("khelper");
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#include <linux/kprobes.h>
|
#include <linux/kprobes.h>
|
||||||
#include <linux/pipe_fs_i.h>
|
#include <linux/pipe_fs_i.h>
|
||||||
#include <linux/oom.h>
|
#include <linux/oom.h>
|
||||||
|
#include <linux/kmod.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
|
@ -615,6 +616,11 @@ static struct ctl_table kern_table[] = {
|
||||||
.mode = 0555,
|
.mode = 0555,
|
||||||
.child = random_table,
|
.child = random_table,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
.procname = "usermodehelper",
|
||||||
|
.mode = 0555,
|
||||||
|
.child = usermodehelper_table,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
.procname = "overflowuid",
|
.procname = "overflowuid",
|
||||||
.data = &overflowuid,
|
.data = &overflowuid,
|
||||||
|
|
|
@ -212,10 +212,12 @@ static void dns_resolver_describe(const struct key *key, struct seq_file *m)
|
||||||
int err = key->type_data.x[0];
|
int err = key->type_data.x[0];
|
||||||
|
|
||||||
seq_puts(m, key->description);
|
seq_puts(m, key->description);
|
||||||
if (err)
|
if (key_is_instantiated(key)) {
|
||||||
seq_printf(m, ": %d", err);
|
if (err)
|
||||||
else
|
seq_printf(m, ": %d", err);
|
||||||
seq_printf(m, ": %u", key->datalen);
|
else
|
||||||
|
seq_printf(m, ": %u", key->datalen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -167,6 +167,7 @@ config INTEL_TXT
|
||||||
config LSM_MMAP_MIN_ADDR
|
config LSM_MMAP_MIN_ADDR
|
||||||
int "Low address space for LSM to protect from user allocation"
|
int "Low address space for LSM to protect from user allocation"
|
||||||
depends on SECURITY && SECURITY_SELINUX
|
depends on SECURITY && SECURITY_SELINUX
|
||||||
|
default 32768 if ARM
|
||||||
default 65536
|
default 65536
|
||||||
help
|
help
|
||||||
This is the portion of low virtual memory which should be protected
|
This is the portion of low virtual memory which should be protected
|
||||||
|
|
|
@ -529,15 +529,10 @@ skip:
|
||||||
new->suid = new->fsuid = new->euid;
|
new->suid = new->fsuid = new->euid;
|
||||||
new->sgid = new->fsgid = new->egid;
|
new->sgid = new->fsgid = new->egid;
|
||||||
|
|
||||||
/* For init, we want to retain the capabilities set in the initial
|
if (effective)
|
||||||
* task. Thus we skip the usual capability rules
|
new->cap_effective = new->cap_permitted;
|
||||||
*/
|
else
|
||||||
if (!is_global_init(current)) {
|
cap_clear(new->cap_effective);
|
||||||
if (effective)
|
|
||||||
new->cap_effective = new->cap_permitted;
|
|
||||||
else
|
|
||||||
cap_clear(new->cap_effective);
|
|
||||||
}
|
|
||||||
bprm->cap_effective = effective;
|
bprm->cap_effective = effective;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -109,11 +109,13 @@ extern key_ref_t keyring_search_aux(key_ref_t keyring_ref,
|
||||||
const struct cred *cred,
|
const struct cred *cred,
|
||||||
struct key_type *type,
|
struct key_type *type,
|
||||||
const void *description,
|
const void *description,
|
||||||
key_match_func_t match);
|
key_match_func_t match,
|
||||||
|
bool no_state_check);
|
||||||
|
|
||||||
extern key_ref_t search_my_process_keyrings(struct key_type *type,
|
extern key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
const void *description,
|
const void *description,
|
||||||
key_match_func_t match,
|
key_match_func_t match,
|
||||||
|
bool no_state_check,
|
||||||
const struct cred *cred);
|
const struct cred *cred);
|
||||||
extern key_ref_t search_process_keyrings(struct key_type *type,
|
extern key_ref_t search_process_keyrings(struct key_type *type,
|
||||||
const void *description,
|
const void *description,
|
||||||
|
|
|
@ -206,8 +206,14 @@ SYSCALL_DEFINE4(request_key, const char __user *, _type,
|
||||||
goto error5;
|
goto error5;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* wait for the key to finish being constructed */
|
||||||
|
ret = wait_for_key_construction(key, 1);
|
||||||
|
if (ret < 0)
|
||||||
|
goto error6;
|
||||||
|
|
||||||
ret = key->serial;
|
ret = key->serial;
|
||||||
|
|
||||||
|
error6:
|
||||||
key_put(key);
|
key_put(key);
|
||||||
error5:
|
error5:
|
||||||
key_type_put(ktype);
|
key_type_put(ktype);
|
||||||
|
|
|
@ -176,13 +176,15 @@ static void keyring_describe(const struct key *keyring, struct seq_file *m)
|
||||||
else
|
else
|
||||||
seq_puts(m, "[anon]");
|
seq_puts(m, "[anon]");
|
||||||
|
|
||||||
rcu_read_lock();
|
if (key_is_instantiated(keyring)) {
|
||||||
klist = rcu_dereference(keyring->payload.subscriptions);
|
rcu_read_lock();
|
||||||
if (klist)
|
klist = rcu_dereference(keyring->payload.subscriptions);
|
||||||
seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
|
if (klist)
|
||||||
else
|
seq_printf(m, ": %u/%u", klist->nkeys, klist->maxkeys);
|
||||||
seq_puts(m, ": empty");
|
else
|
||||||
rcu_read_unlock();
|
seq_puts(m, ": empty");
|
||||||
|
rcu_read_unlock();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -271,6 +273,7 @@ struct key *keyring_alloc(const char *description, uid_t uid, gid_t gid,
|
||||||
* @type: The type of key to search for.
|
* @type: The type of key to search for.
|
||||||
* @description: Parameter for @match.
|
* @description: Parameter for @match.
|
||||||
* @match: Function to rule on whether or not a key is the one required.
|
* @match: Function to rule on whether or not a key is the one required.
|
||||||
|
* @no_state_check: Don't check if a matching key is bad
|
||||||
*
|
*
|
||||||
* Search the supplied keyring tree for a key that matches the criteria given.
|
* Search the supplied keyring tree for a key that matches the criteria given.
|
||||||
* The root keyring and any linked keyrings must grant Search permission to the
|
* The root keyring and any linked keyrings must grant Search permission to the
|
||||||
|
@ -303,7 +306,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
|
||||||
const struct cred *cred,
|
const struct cred *cred,
|
||||||
struct key_type *type,
|
struct key_type *type,
|
||||||
const void *description,
|
const void *description,
|
||||||
key_match_func_t match)
|
key_match_func_t match,
|
||||||
|
bool no_state_check)
|
||||||
{
|
{
|
||||||
struct {
|
struct {
|
||||||
struct keyring_list *keylist;
|
struct keyring_list *keylist;
|
||||||
|
@ -345,6 +349,8 @@ key_ref_t keyring_search_aux(key_ref_t keyring_ref,
|
||||||
kflags = keyring->flags;
|
kflags = keyring->flags;
|
||||||
if (keyring->type == type && match(keyring, description)) {
|
if (keyring->type == type && match(keyring, description)) {
|
||||||
key = keyring;
|
key = keyring;
|
||||||
|
if (no_state_check)
|
||||||
|
goto found;
|
||||||
|
|
||||||
/* check it isn't negative and hasn't expired or been
|
/* check it isn't negative and hasn't expired or been
|
||||||
* revoked */
|
* revoked */
|
||||||
|
@ -384,11 +390,13 @@ descend:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* skip revoked keys and expired keys */
|
/* skip revoked keys and expired keys */
|
||||||
if (kflags & (1 << KEY_FLAG_REVOKED))
|
if (!no_state_check) {
|
||||||
continue;
|
if (kflags & (1 << KEY_FLAG_REVOKED))
|
||||||
|
continue;
|
||||||
|
|
||||||
if (key->expiry && now.tv_sec >= key->expiry)
|
if (key->expiry && now.tv_sec >= key->expiry)
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
/* keys that don't match */
|
/* keys that don't match */
|
||||||
if (!match(key, description))
|
if (!match(key, description))
|
||||||
|
@ -399,6 +407,9 @@ descend:
|
||||||
cred, KEY_SEARCH) < 0)
|
cred, KEY_SEARCH) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (no_state_check)
|
||||||
|
goto found;
|
||||||
|
|
||||||
/* we set a different error code if we pass a negative key */
|
/* we set a different error code if we pass a negative key */
|
||||||
if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
|
if (kflags & (1 << KEY_FLAG_NEGATIVE)) {
|
||||||
err = key->type_data.reject_error;
|
err = key->type_data.reject_error;
|
||||||
|
@ -478,7 +489,7 @@ key_ref_t keyring_search(key_ref_t keyring,
|
||||||
return ERR_PTR(-ENOKEY);
|
return ERR_PTR(-ENOKEY);
|
||||||
|
|
||||||
return keyring_search_aux(keyring, current->cred,
|
return keyring_search_aux(keyring, current->cred,
|
||||||
type, description, type->match);
|
type, description, type->match, false);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(keyring_search);
|
EXPORT_SYMBOL(keyring_search);
|
||||||
|
|
||||||
|
|
|
@ -199,7 +199,7 @@ static int proc_keys_show(struct seq_file *m, void *v)
|
||||||
if (key->perm & KEY_POS_VIEW) {
|
if (key->perm & KEY_POS_VIEW) {
|
||||||
skey_ref = search_my_process_keyrings(key->type, key,
|
skey_ref = search_my_process_keyrings(key->type, key,
|
||||||
lookup_user_key_possessed,
|
lookup_user_key_possessed,
|
||||||
cred);
|
true, cred);
|
||||||
if (!IS_ERR(skey_ref)) {
|
if (!IS_ERR(skey_ref)) {
|
||||||
key_ref_put(skey_ref);
|
key_ref_put(skey_ref);
|
||||||
key_ref = make_key_ref(key, 1);
|
key_ref = make_key_ref(key, 1);
|
||||||
|
|
|
@ -331,6 +331,7 @@ void key_fsgid_changed(struct task_struct *tsk)
|
||||||
key_ref_t search_my_process_keyrings(struct key_type *type,
|
key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
const void *description,
|
const void *description,
|
||||||
key_match_func_t match,
|
key_match_func_t match,
|
||||||
|
bool no_state_check,
|
||||||
const struct cred *cred)
|
const struct cred *cred)
|
||||||
{
|
{
|
||||||
key_ref_t key_ref, ret, err;
|
key_ref_t key_ref, ret, err;
|
||||||
|
@ -350,7 +351,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
if (cred->thread_keyring) {
|
if (cred->thread_keyring) {
|
||||||
key_ref = keyring_search_aux(
|
key_ref = keyring_search_aux(
|
||||||
make_key_ref(cred->thread_keyring, 1),
|
make_key_ref(cred->thread_keyring, 1),
|
||||||
cred, type, description, match);
|
cred, type, description, match, no_state_check);
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
|
@ -371,7 +372,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
if (cred->tgcred->process_keyring) {
|
if (cred->tgcred->process_keyring) {
|
||||||
key_ref = keyring_search_aux(
|
key_ref = keyring_search_aux(
|
||||||
make_key_ref(cred->tgcred->process_keyring, 1),
|
make_key_ref(cred->tgcred->process_keyring, 1),
|
||||||
cred, type, description, match);
|
cred, type, description, match, no_state_check);
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
|
@ -395,7 +396,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
make_key_ref(rcu_dereference(
|
make_key_ref(rcu_dereference(
|
||||||
cred->tgcred->session_keyring),
|
cred->tgcred->session_keyring),
|
||||||
1),
|
1),
|
||||||
cred, type, description, match);
|
cred, type, description, match, no_state_check);
|
||||||
rcu_read_unlock();
|
rcu_read_unlock();
|
||||||
|
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
|
@ -417,7 +418,7 @@ key_ref_t search_my_process_keyrings(struct key_type *type,
|
||||||
else if (cred->user->session_keyring) {
|
else if (cred->user->session_keyring) {
|
||||||
key_ref = keyring_search_aux(
|
key_ref = keyring_search_aux(
|
||||||
make_key_ref(cred->user->session_keyring, 1),
|
make_key_ref(cred->user->session_keyring, 1),
|
||||||
cred, type, description, match);
|
cred, type, description, match, no_state_check);
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
goto found;
|
goto found;
|
||||||
|
|
||||||
|
@ -459,7 +460,8 @@ key_ref_t search_process_keyrings(struct key_type *type,
|
||||||
|
|
||||||
might_sleep();
|
might_sleep();
|
||||||
|
|
||||||
key_ref = search_my_process_keyrings(type, description, match, cred);
|
key_ref = search_my_process_keyrings(type, description, match,
|
||||||
|
false, cred);
|
||||||
if (!IS_ERR(key_ref))
|
if (!IS_ERR(key_ref))
|
||||||
goto found;
|
goto found;
|
||||||
err = key_ref;
|
err = key_ref;
|
||||||
|
|
|
@ -530,8 +530,7 @@ struct key *request_key_and_link(struct key_type *type,
|
||||||
dest_keyring, flags);
|
dest_keyring, flags);
|
||||||
|
|
||||||
/* search all the process keyrings for a key */
|
/* search all the process keyrings for a key */
|
||||||
key_ref = search_process_keyrings(type, description, type->match,
|
key_ref = search_process_keyrings(type, description, type->match, cred);
|
||||||
cred);
|
|
||||||
|
|
||||||
if (!IS_ERR(key_ref)) {
|
if (!IS_ERR(key_ref)) {
|
||||||
key = key_ref_to_ptr(key_ref);
|
key = key_ref_to_ptr(key_ref);
|
||||||
|
|
|
@ -59,7 +59,8 @@ static void request_key_auth_describe(const struct key *key,
|
||||||
|
|
||||||
seq_puts(m, "key:");
|
seq_puts(m, "key:");
|
||||||
seq_puts(m, key->description);
|
seq_puts(m, key->description);
|
||||||
seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
|
if (key_is_instantiated(key))
|
||||||
|
seq_printf(m, " pid:%d ci:%zu", rka->pid, rka->callout_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
|
@ -157,8 +157,8 @@ EXPORT_SYMBOL_GPL(user_destroy);
|
||||||
void user_describe(const struct key *key, struct seq_file *m)
|
void user_describe(const struct key *key, struct seq_file *m)
|
||||||
{
|
{
|
||||||
seq_puts(m, key->description);
|
seq_puts(m, key->description);
|
||||||
|
if (key_is_instantiated(key))
|
||||||
seq_printf(m, ": %u", key->datalen);
|
seq_printf(m, ": %u", key->datalen);
|
||||||
}
|
}
|
||||||
|
|
||||||
EXPORT_SYMBOL_GPL(user_describe);
|
EXPORT_SYMBOL_GPL(user_describe);
|
||||||
|
|
|
@ -108,10 +108,9 @@ static bool tomoyo_flush(struct tomoyo_io_buffer *head)
|
||||||
head->read_user_buf += len;
|
head->read_user_buf += len;
|
||||||
w += len;
|
w += len;
|
||||||
}
|
}
|
||||||
if (*w) {
|
head->r.w[0] = w;
|
||||||
head->r.w[0] = w;
|
if (*w)
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
/* Add '\0' for query. */
|
/* Add '\0' for query. */
|
||||||
if (head->poll) {
|
if (head->poll) {
|
||||||
if (!head->read_user_buf_avail ||
|
if (!head->read_user_buf_avail ||
|
||||||
|
@ -459,8 +458,16 @@ static int tomoyo_write_profile(struct tomoyo_io_buffer *head)
|
||||||
if (profile == &tomoyo_default_profile)
|
if (profile == &tomoyo_default_profile)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!strcmp(data, "COMMENT")) {
|
if (!strcmp(data, "COMMENT")) {
|
||||||
const struct tomoyo_path_info *old_comment = profile->comment;
|
static DEFINE_SPINLOCK(lock);
|
||||||
profile->comment = tomoyo_get_name(cp);
|
const struct tomoyo_path_info *new_comment
|
||||||
|
= tomoyo_get_name(cp);
|
||||||
|
const struct tomoyo_path_info *old_comment;
|
||||||
|
if (!new_comment)
|
||||||
|
return -ENOMEM;
|
||||||
|
spin_lock(&lock);
|
||||||
|
old_comment = profile->comment;
|
||||||
|
profile->comment = new_comment;
|
||||||
|
spin_unlock(&lock);
|
||||||
tomoyo_put_name(old_comment);
|
tomoyo_put_name(old_comment);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1011,7 +1011,6 @@ int tomoyo_path_perm(const u8 operation, struct path *path)
|
||||||
break;
|
break;
|
||||||
case TOMOYO_TYPE_RMDIR:
|
case TOMOYO_TYPE_RMDIR:
|
||||||
case TOMOYO_TYPE_CHROOT:
|
case TOMOYO_TYPE_CHROOT:
|
||||||
case TOMOYO_TYPE_UMOUNT:
|
|
||||||
tomoyo_add_slash(&buf);
|
tomoyo_add_slash(&buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,6 +75,7 @@ void *tomoyo_commit_ok(void *data, const unsigned int size)
|
||||||
memset(data, 0, size);
|
memset(data, 0, size);
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
kfree(ptr);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -143,6 +143,7 @@ static int tomoyo_mount_acl(struct tomoyo_request_info *r, char *dev_name,
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
requested_dev_name = tomoyo_realpath_from_path(&path);
|
requested_dev_name = tomoyo_realpath_from_path(&path);
|
||||||
|
path_put(&path);
|
||||||
if (!requested_dev_name) {
|
if (!requested_dev_name) {
|
||||||
error = -ENOENT;
|
error = -ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
|
|
|
@ -390,7 +390,7 @@ bool tomoyo_correct_domain(const unsigned char *domainname)
|
||||||
if (!cp)
|
if (!cp)
|
||||||
break;
|
break;
|
||||||
if (*domainname != '/' ||
|
if (*domainname != '/' ||
|
||||||
!tomoyo_correct_word2(domainname, cp - domainname - 1))
|
!tomoyo_correct_word2(domainname, cp - domainname))
|
||||||
goto out;
|
goto out;
|
||||||
domainname = cp + 1;
|
domainname = cp + 1;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue