aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/admin-guide/LSM/index.rst13
-rw-r--r--fs/proc/base.c64
-rw-r--r--fs/proc/internal.h1
-rw-r--r--include/linux/security.h15
-rw-r--r--security/security.c24
5 files changed, 96 insertions, 21 deletions
diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-guide/LSM/index.rst
index c980dfe9abf1..9842e21afd4a 100644
--- a/Documentation/admin-guide/LSM/index.rst
+++ b/Documentation/admin-guide/LSM/index.rst
@@ -17,9 +17,8 @@ MAC extensions, other extensions can be built using the LSM to provide
17specific changes to system operation when these tweaks are not available 17specific changes to system operation when these tweaks are not available
18in the core functionality of Linux itself. 18in the core functionality of Linux itself.
19 19
20Without a specific LSM built into the kernel, the default LSM will be the 20The Linux capabilities modules will always be included. This may be
21Linux capabilities system. Most LSMs choose to extend the capabilities 21followed by any number of "minor" modules and at most one "major" module.
22system, building their checks on top of the defined capability hooks.
23For more details on capabilities, see ``capabilities(7)`` in the Linux 22For more details on capabilities, see ``capabilities(7)`` in the Linux
24man-pages project. 23man-pages project.
25 24
@@ -30,6 +29,14 @@ order in which checks are made. The capability module will always
30be first, followed by any "minor" modules (e.g. Yama) and then 29be first, followed by any "minor" modules (e.g. Yama) and then
31the one "major" module (e.g. SELinux) if there is one configured. 30the one "major" module (e.g. SELinux) if there is one configured.
32 31
32Process attributes associated with "major" security modules should
33be accessed and maintained using the special files in ``/proc/.../attr``.
34A security module may maintain a module specific subdirectory there,
35named after the module. ``/proc/.../attr/smack`` is provided by the Smack
36security module and contains all its special files. The files directly
37in ``/proc/.../attr`` remain as legacy interfaces for modules that provide
38subdirectories.
39
33.. toctree:: 40.. toctree::
34 :maxdepth: 1 41 :maxdepth: 1
35 42
diff --git a/fs/proc/base.c b/fs/proc/base.c
index 633a63462573..c9d775fd24ef 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -140,9 +140,13 @@ struct pid_entry {
140#define REG(NAME, MODE, fops) \ 140#define REG(NAME, MODE, fops) \
141 NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {}) 141 NOD(NAME, (S_IFREG|(MODE)), NULL, &fops, {})
142#define ONE(NAME, MODE, show) \ 142#define ONE(NAME, MODE, show) \
143 NOD(NAME, (S_IFREG|(MODE)), \ 143 NOD(NAME, (S_IFREG|(MODE)), \
144 NULL, &proc_single_file_operations, \ 144 NULL, &proc_single_file_operations, \
145 { .proc_show = show } ) 145 { .proc_show = show } )
146#define ATTR(LSM, NAME, MODE) \
147 NOD(NAME, (S_IFREG|(MODE)), \
148 NULL, &proc_pid_attr_operations, \
149 { .lsm = LSM })
146 150
147/* 151/*
148 * Count the number of hardlinks for the pid_entry table, excluding the . 152 * Count the number of hardlinks for the pid_entry table, excluding the .
@@ -2525,7 +2529,7 @@ static ssize_t proc_pid_attr_read(struct file * file, char __user * buf,
2525 if (!task) 2529 if (!task)
2526 return -ESRCH; 2530 return -ESRCH;
2527 2531
2528 length = security_getprocattr(task, 2532 length = security_getprocattr(task, PROC_I(inode)->op.lsm,
2529 (char*)file->f_path.dentry->d_name.name, 2533 (char*)file->f_path.dentry->d_name.name,
2530 &p); 2534 &p);
2531 put_task_struct(task); 2535 put_task_struct(task);
@@ -2574,7 +2578,9 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
2574 if (rv < 0) 2578 if (rv < 0)
2575 goto out_free; 2579 goto out_free;
2576 2580
2577 rv = security_setprocattr(file->f_path.dentry->d_name.name, page, count); 2581 rv = security_setprocattr(PROC_I(inode)->op.lsm,
2582 file->f_path.dentry->d_name.name, page,
2583 count);
2578 mutex_unlock(&current->signal->cred_guard_mutex); 2584 mutex_unlock(&current->signal->cred_guard_mutex);
2579out_free: 2585out_free:
2580 kfree(page); 2586 kfree(page);
@@ -2588,13 +2594,53 @@ static const struct file_operations proc_pid_attr_operations = {
2588 .llseek = generic_file_llseek, 2594 .llseek = generic_file_llseek,
2589}; 2595};
2590 2596
2597#define LSM_DIR_OPS(LSM) \
2598static int proc_##LSM##_attr_dir_iterate(struct file *filp, \
2599 struct dir_context *ctx) \
2600{ \
2601 return proc_pident_readdir(filp, ctx, \
2602 LSM##_attr_dir_stuff, \
2603 ARRAY_SIZE(LSM##_attr_dir_stuff)); \
2604} \
2605\
2606static const struct file_operations proc_##LSM##_attr_dir_ops = { \
2607 .read = generic_read_dir, \
2608 .iterate = proc_##LSM##_attr_dir_iterate, \
2609 .llseek = default_llseek, \
2610}; \
2611\
2612static struct dentry *proc_##LSM##_attr_dir_lookup(struct inode *dir, \
2613 struct dentry *dentry, unsigned int flags) \
2614{ \
2615 return proc_pident_lookup(dir, dentry, \
2616 LSM##_attr_dir_stuff, \
2617 ARRAY_SIZE(LSM##_attr_dir_stuff)); \
2618} \
2619\
2620static const struct inode_operations proc_##LSM##_attr_dir_inode_ops = { \
2621 .lookup = proc_##LSM##_attr_dir_lookup, \
2622 .getattr = pid_getattr, \
2623 .setattr = proc_setattr, \
2624}
2625
2626#ifdef CONFIG_SECURITY_SMACK
2627static const struct pid_entry smack_attr_dir_stuff[] = {
2628 ATTR("smack", "current", 0666),
2629};
2630LSM_DIR_OPS(smack);
2631#endif
2632
2591static const struct pid_entry attr_dir_stuff[] = { 2633static const struct pid_entry attr_dir_stuff[] = {
2592 REG("current", S_IRUGO|S_IWUGO, proc_pid_attr_operations), 2634 ATTR(NULL, "current", 0666),
2593 REG("prev", S_IRUGO, proc_pid_attr_operations), 2635 ATTR(NULL, "prev", 0444),
2594 REG("exec", S_IRUGO|S_IWUGO, proc_pid_attr_operations), 2636 ATTR(NULL, "exec", 0666),
2595 REG("fscreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), 2637 ATTR(NULL, "fscreate", 0666),
2596 REG("keycreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), 2638 ATTR(NULL, "keycreate", 0666),
2597 REG("sockcreate", S_IRUGO|S_IWUGO, proc_pid_attr_operations), 2639 ATTR(NULL, "sockcreate", 0666),
2640#ifdef CONFIG_SECURITY_SMACK
2641 DIR("smack", 0555,
2642 proc_smack_attr_dir_inode_ops, proc_smack_attr_dir_ops),
2643#endif
2598}; 2644};
2599 2645
2600static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx) 2646static int proc_attr_dir_readdir(struct file *file, struct dir_context *ctx)
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index 5185d7f6a51e..d4f9989063d0 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -81,6 +81,7 @@ union proc_op {
81 int (*proc_show)(struct seq_file *m, 81 int (*proc_show)(struct seq_file *m,
82 struct pid_namespace *ns, struct pid *pid, 82 struct pid_namespace *ns, struct pid *pid,
83 struct task_struct *task); 83 struct task_struct *task);
84 const char *lsm;
84}; 85};
85 86
86struct proc_inode { 87struct proc_inode {
diff --git a/include/linux/security.h b/include/linux/security.h
index dbfb5a66babb..b2c5333ed4b5 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -366,8 +366,10 @@ int security_sem_semctl(struct kern_ipc_perm *sma, int cmd);
366int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops, 366int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
367 unsigned nsops, int alter); 367 unsigned nsops, int alter);
368void security_d_instantiate(struct dentry *dentry, struct inode *inode); 368void security_d_instantiate(struct dentry *dentry, struct inode *inode);
369int security_getprocattr(struct task_struct *p, char *name, char **value); 369int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
370int security_setprocattr(const char *name, void *value, size_t size); 370 char **value);
371int security_setprocattr(const char *lsm, const char *name, void *value,
372 size_t size);
371int security_netlink_send(struct sock *sk, struct sk_buff *skb); 373int security_netlink_send(struct sock *sk, struct sk_buff *skb);
372int security_ismaclabel(const char *name); 374int security_ismaclabel(const char *name);
373int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen); 375int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
@@ -1112,15 +1114,18 @@ static inline int security_sem_semop(struct kern_ipc_perm *sma,
1112 return 0; 1114 return 0;
1113} 1115}
1114 1116
1115static inline void security_d_instantiate(struct dentry *dentry, struct inode *inode) 1117static inline void security_d_instantiate(struct dentry *dentry,
1118 struct inode *inode)
1116{ } 1119{ }
1117 1120
1118static inline int security_getprocattr(struct task_struct *p, char *name, char **value) 1121static inline int security_getprocattr(struct task_struct *p, const char *lsm,
1122 char *name, char **value)
1119{ 1123{
1120 return -EINVAL; 1124 return -EINVAL;
1121} 1125}
1122 1126
1123static inline int security_setprocattr(char *name, void *value, size_t size) 1127static inline int security_setprocattr(const char *lsm, char *name,
1128 void *value, size_t size)
1124{ 1129{
1125 return -EINVAL; 1130 return -EINVAL;
1126} 1131}
diff --git a/security/security.c b/security/security.c
index 9411f659454b..60b39db95c2f 100644
--- a/security/security.c
+++ b/security/security.c
@@ -1485,14 +1485,30 @@ void security_d_instantiate(struct dentry *dentry, struct inode *inode)
1485} 1485}
1486EXPORT_SYMBOL(security_d_instantiate); 1486EXPORT_SYMBOL(security_d_instantiate);
1487 1487
1488int security_getprocattr(struct task_struct *p, char *name, char **value) 1488int security_getprocattr(struct task_struct *p, const char *lsm, char *name,
1489 char **value)
1489{ 1490{
1490 return call_int_hook(getprocattr, -EINVAL, p, name, value); 1491 struct security_hook_list *hp;
1492
1493 hlist_for_each_entry(hp, &security_hook_heads.getprocattr, list) {
1494 if (lsm != NULL && strcmp(lsm, hp->lsm))
1495 continue;
1496 return hp->hook.getprocattr(p, name, value);
1497 }
1498 return -EINVAL;
1491} 1499}
1492 1500
1493int security_setprocattr(const char *name, void *value, size_t size) 1501int security_setprocattr(const char *lsm, const char *name, void *value,
1502 size_t size)
1494{ 1503{
1495 return call_int_hook(setprocattr, -EINVAL, name, value, size); 1504 struct security_hook_list *hp;
1505
1506 hlist_for_each_entry(hp, &security_hook_heads.setprocattr, list) {
1507 if (lsm != NULL && strcmp(lsm, hp->lsm))
1508 continue;
1509 return hp->hook.setprocattr(name, value, size);
1510 }
1511 return -EINVAL;
1496} 1512}
1497 1513
1498int security_netlink_send(struct sock *sk, struct sk_buff *skb) 1514int security_netlink_send(struct sock *sk, struct sk_buff *skb)