aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/security.h55
-rw-r--r--security/capability.c17
-rw-r--r--security/security.c18
-rw-r--r--security/selinux/hooks.c29
-rw-r--r--security/smack/smack_lsm.c24
5 files changed, 143 insertions, 0 deletions
diff --git a/include/linux/security.h b/include/linux/security.h
index 10a09257952b..d050b66ab9ef 100644
--- a/include/linux/security.h
+++ b/include/linux/security.h
@@ -1382,6 +1382,41 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts)
1382 * audit_rule_init. 1382 * audit_rule_init.
1383 * @rule contains the allocated rule 1383 * @rule contains the allocated rule
1384 * 1384 *
1385 * @inode_notifysecctx:
1386 * Notify the security module of what the security context of an inode
1387 * should be. Initializes the incore security context managed by the
1388 * security module for this inode. Example usage: NFS client invokes
1389 * this hook to initialize the security context in its incore inode to the
1390 * value provided by the server for the file when the server returned the
1391 * file's attributes to the client.
1392 *
1393 * Must be called with inode->i_mutex locked.
1394 *
1395 * @inode we wish to set the security context of.
1396 * @ctx contains the string which we wish to set in the inode.
1397 * @ctxlen contains the length of @ctx.
1398 *
1399 * @inode_setsecctx:
1400 * Change the security context of an inode. Updates the
1401 * incore security context managed by the security module and invokes the
1402 * fs code as needed (via __vfs_setxattr_noperm) to update any backing
1403 * xattrs that represent the context. Example usage: NFS server invokes
1404 * this hook to change the security context in its incore inode and on the
1405 * backing filesystem to a value provided by the client on a SETATTR
1406 * operation.
1407 *
1408 * Must be called with inode->i_mutex locked.
1409 *
1410 * @dentry contains the inode we wish to set the security context of.
1411 * @ctx contains the string which we wish to set in the inode.
1412 * @ctxlen contains the length of @ctx.
1413 *
1414 * @inode_getsecctx:
1415 * Returns a string containing all relavent security context information
1416 *
1417 * @inode we wish to set the security context of.
1418 * @ctx is a pointer in which to place the allocated security context.
1419 * @ctxlen points to the place to put the length of @ctx.
1385 * This is the main security structure. 1420 * This is the main security structure.
1386 */ 1421 */
1387struct security_operations { 1422struct security_operations {
@@ -1590,6 +1625,10 @@ struct security_operations {
1590 int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid); 1625 int (*secctx_to_secid) (const char *secdata, u32 seclen, u32 *secid);
1591 void (*release_secctx) (char *secdata, u32 seclen); 1626 void (*release_secctx) (char *secdata, u32 seclen);
1592 1627
1628 int (*inode_notifysecctx)(struct inode *inode, void *ctx, u32 ctxlen);
1629 int (*inode_setsecctx)(struct dentry *dentry, void *ctx, u32 ctxlen);
1630 int (*inode_getsecctx)(struct inode *inode, void **ctx, u32 *ctxlen);
1631
1593#ifdef CONFIG_SECURITY_NETWORK 1632#ifdef CONFIG_SECURITY_NETWORK
1594 int (*unix_stream_connect) (struct socket *sock, 1633 int (*unix_stream_connect) (struct socket *sock,
1595 struct socket *other, struct sock *newsk); 1634 struct socket *other, struct sock *newsk);
@@ -1839,6 +1878,9 @@ int security_secid_to_secctx(u32 secid, char **secdata, u32 *seclen);
1839int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid); 1878int security_secctx_to_secid(const char *secdata, u32 seclen, u32 *secid);
1840void security_release_secctx(char *secdata, u32 seclen); 1879void security_release_secctx(char *secdata, u32 seclen);
1841 1880
1881int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen);
1882int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen);
1883int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen);
1842#else /* CONFIG_SECURITY */ 1884#else /* CONFIG_SECURITY */
1843struct security_mnt_opts { 1885struct security_mnt_opts {
1844}; 1886};
@@ -2595,6 +2637,19 @@ static inline int security_secctx_to_secid(const char *secdata,
2595static inline void security_release_secctx(char *secdata, u32 seclen) 2637static inline void security_release_secctx(char *secdata, u32 seclen)
2596{ 2638{
2597} 2639}
2640
2641static inline int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
2642{
2643 return -EOPNOTSUPP;
2644}
2645static inline int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
2646{
2647 return -EOPNOTSUPP;
2648}
2649static inline int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
2650{
2651 return -EOPNOTSUPP;
2652}
2598#endif /* CONFIG_SECURITY */ 2653#endif /* CONFIG_SECURITY */
2599 2654
2600#ifdef CONFIG_SECURITY_NETWORK 2655#ifdef CONFIG_SECURITY_NETWORK
diff --git a/security/capability.c b/security/capability.c
index 93a2ffe65905..fce07a7bc825 100644
--- a/security/capability.c
+++ b/security/capability.c
@@ -822,6 +822,20 @@ static void cap_release_secctx(char *secdata, u32 seclen)
822{ 822{
823} 823}
824 824
825static int cap_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
826{
827 return 0;
828}
829
830static int cap_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
831{
832 return 0;
833}
834
835static int cap_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
836{
837 return 0;
838}
825#ifdef CONFIG_KEYS 839#ifdef CONFIG_KEYS
826static int cap_key_alloc(struct key *key, const struct cred *cred, 840static int cap_key_alloc(struct key *key, const struct cred *cred,
827 unsigned long flags) 841 unsigned long flags)
@@ -1032,6 +1046,9 @@ void security_fixup_ops(struct security_operations *ops)
1032 set_to_cap_if_null(ops, secid_to_secctx); 1046 set_to_cap_if_null(ops, secid_to_secctx);
1033 set_to_cap_if_null(ops, secctx_to_secid); 1047 set_to_cap_if_null(ops, secctx_to_secid);
1034 set_to_cap_if_null(ops, release_secctx); 1048 set_to_cap_if_null(ops, release_secctx);
1049 set_to_cap_if_null(ops, inode_notifysecctx);
1050 set_to_cap_if_null(ops, inode_setsecctx);
1051 set_to_cap_if_null(ops, inode_getsecctx);
1035#ifdef CONFIG_SECURITY_NETWORK 1052#ifdef CONFIG_SECURITY_NETWORK
1036 set_to_cap_if_null(ops, unix_stream_connect); 1053 set_to_cap_if_null(ops, unix_stream_connect);
1037 set_to_cap_if_null(ops, unix_may_send); 1054 set_to_cap_if_null(ops, unix_may_send);
diff --git a/security/security.c b/security/security.c
index d8b727637f02..c4c673240c1c 100644
--- a/security/security.c
+++ b/security/security.c
@@ -974,6 +974,24 @@ void security_release_secctx(char *secdata, u32 seclen)
974} 974}
975EXPORT_SYMBOL(security_release_secctx); 975EXPORT_SYMBOL(security_release_secctx);
976 976
977int security_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
978{
979 return security_ops->inode_notifysecctx(inode, ctx, ctxlen);
980}
981EXPORT_SYMBOL(security_inode_notifysecctx);
982
983int security_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
984{
985 return security_ops->inode_setsecctx(dentry, ctx, ctxlen);
986}
987EXPORT_SYMBOL(security_inode_setsecctx);
988
989int security_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
990{
991 return security_ops->inode_getsecctx(inode, ctx, ctxlen);
992}
993EXPORT_SYMBOL(security_inode_getsecctx);
994
977#ifdef CONFIG_SECURITY_NETWORK 995#ifdef CONFIG_SECURITY_NETWORK
978 996
979int security_unix_stream_connect(struct socket *sock, struct socket *other, 997int security_unix_stream_connect(struct socket *sock, struct socket *other,
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index 134a9c0d2004..7118be2a74a5 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -5351,6 +5351,32 @@ static void selinux_release_secctx(char *secdata, u32 seclen)
5351 kfree(secdata); 5351 kfree(secdata);
5352} 5352}
5353 5353
5354/*
5355 * called with inode->i_mutex locked
5356 */
5357static int selinux_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
5358{
5359 return selinux_inode_setsecurity(inode, XATTR_SELINUX_SUFFIX, ctx, ctxlen, 0);
5360}
5361
5362/*
5363 * called with inode->i_mutex locked
5364 */
5365static int selinux_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
5366{
5367 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SELINUX, ctx, ctxlen, 0);
5368}
5369
5370static int selinux_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
5371{
5372 int len = 0;
5373 len = selinux_inode_getsecurity(inode, XATTR_SELINUX_SUFFIX,
5374 ctx, true);
5375 if (len < 0)
5376 return len;
5377 *ctxlen = len;
5378 return 0;
5379}
5354#ifdef CONFIG_KEYS 5380#ifdef CONFIG_KEYS
5355 5381
5356static int selinux_key_alloc(struct key *k, const struct cred *cred, 5382static int selinux_key_alloc(struct key *k, const struct cred *cred,
@@ -5550,6 +5576,9 @@ static struct security_operations selinux_ops = {
5550 .secid_to_secctx = selinux_secid_to_secctx, 5576 .secid_to_secctx = selinux_secid_to_secctx,
5551 .secctx_to_secid = selinux_secctx_to_secid, 5577 .secctx_to_secid = selinux_secctx_to_secid,
5552 .release_secctx = selinux_release_secctx, 5578 .release_secctx = selinux_release_secctx,
5579 .inode_notifysecctx = selinux_inode_notifysecctx,
5580 .inode_setsecctx = selinux_inode_setsecctx,
5581 .inode_getsecctx = selinux_inode_getsecctx,
5553 5582
5554 .unix_stream_connect = selinux_socket_unix_stream_connect, 5583 .unix_stream_connect = selinux_socket_unix_stream_connect,
5555 .unix_may_send = selinux_socket_unix_may_send, 5584 .unix_may_send = selinux_socket_unix_may_send,
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
index 969f5fee1906..0b3bb646f90e 100644
--- a/security/smack/smack_lsm.c
+++ b/security/smack/smack_lsm.c
@@ -3057,6 +3057,27 @@ static void smack_release_secctx(char *secdata, u32 seclen)
3057{ 3057{
3058} 3058}
3059 3059
3060static int smack_inode_notifysecctx(struct inode *inode, void *ctx, u32 ctxlen)
3061{
3062 return smack_inode_setsecurity(inode, XATTR_SMACK_SUFFIX, ctx, ctxlen, 0);
3063}
3064
3065static int smack_inode_setsecctx(struct dentry *dentry, void *ctx, u32 ctxlen)
3066{
3067 return __vfs_setxattr_noperm(dentry, XATTR_NAME_SMACK, ctx, ctxlen, 0);
3068}
3069
3070static int smack_inode_getsecctx(struct inode *inode, void **ctx, u32 *ctxlen)
3071{
3072 int len = 0;
3073 len = smack_inode_getsecurity(inode, XATTR_SMACK_SUFFIX, ctx, true);
3074
3075 if (len < 0)
3076 return len;
3077 *ctxlen = len;
3078 return 0;
3079}
3080
3060struct security_operations smack_ops = { 3081struct security_operations smack_ops = {
3061 .name = "smack", 3082 .name = "smack",
3062 3083
@@ -3185,6 +3206,9 @@ struct security_operations smack_ops = {
3185 .secid_to_secctx = smack_secid_to_secctx, 3206 .secid_to_secctx = smack_secid_to_secctx,
3186 .secctx_to_secid = smack_secctx_to_secid, 3207 .secctx_to_secid = smack_secctx_to_secid,
3187 .release_secctx = smack_release_secctx, 3208 .release_secctx = smack_release_secctx,
3209 .inode_notifysecctx = smack_inode_notifysecctx,
3210 .inode_setsecctx = smack_inode_setsecctx,
3211 .inode_getsecctx = smack_inode_getsecctx,
3188}; 3212};
3189 3213
3190 3214