diff options
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | fs/kernfs/dir.c | 24 | ||||
-rw-r--r-- | fs/kernfs/inode.c | 162 | ||||
-rw-r--r-- | fs/kernfs/kernfs-internal.h | 8 | ||||
-rw-r--r-- | fs/kernfs/symlink.c | 4 | ||||
-rw-r--r-- | fs/proc/base.c | 5 | ||||
-rw-r--r-- | include/linux/kernfs.h | 13 | ||||
-rw-r--r-- | include/linux/lsm_hooks.h | 13 | ||||
-rw-r--r-- | include/linux/security.h | 9 | ||||
-rwxr-xr-x | scripts/selinux/install_policy.sh | 92 | ||||
-rw-r--r-- | scripts/selinux/mdp/Makefile | 2 | ||||
-rw-r--r-- | scripts/selinux/mdp/mdp.c | 165 | ||||
-rw-r--r-- | security/security.c | 6 | ||||
-rw-r--r-- | security/selinux/hooks.c | 229 | ||||
-rw-r--r-- | security/selinux/include/security.h | 1 | ||||
-rw-r--r-- | security/selinux/netlabel.c | 14 | ||||
-rw-r--r-- | security/selinux/ss/services.c | 7 |
17 files changed, 487 insertions, 269 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index fbb6e45018f5..20dc1a125e24 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -13994,7 +13994,7 @@ W: https://selinuxproject.org | |||
13994 | W: https://github.com/SELinuxProject | 13994 | W: https://github.com/SELinuxProject |
13995 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git | 13995 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git |
13996 | S: Supported | 13996 | S: Supported |
13997 | F: include/linux/selinux* | 13997 | F: include/uapi/linux/selinux_netlink.h |
13998 | F: security/selinux/ | 13998 | F: security/selinux/ |
13999 | F: scripts/selinux/ | 13999 | F: scripts/selinux/ |
14000 | F: Documentation/admin-guide/LSM/SELinux.rst | 14000 | F: Documentation/admin-guide/LSM/SELinux.rst |
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c index 1e7a74b8e064..016ba88f7335 100644 --- a/fs/kernfs/dir.c +++ b/fs/kernfs/dir.c | |||
@@ -532,9 +532,6 @@ void kernfs_put(struct kernfs_node *kn) | |||
532 | kfree_const(kn->name); | 532 | kfree_const(kn->name); |
533 | 533 | ||
534 | if (kn->iattr) { | 534 | if (kn->iattr) { |
535 | if (kn->iattr->ia_secdata) | ||
536 | security_release_secctx(kn->iattr->ia_secdata, | ||
537 | kn->iattr->ia_secdata_len); | ||
538 | simple_xattrs_free(&kn->iattr->xattrs); | 535 | simple_xattrs_free(&kn->iattr->xattrs); |
539 | kmem_cache_free(kernfs_iattrs_cache, kn->iattr); | 536 | kmem_cache_free(kernfs_iattrs_cache, kn->iattr); |
540 | } | 537 | } |
@@ -618,6 +615,7 @@ struct kernfs_node *kernfs_node_from_dentry(struct dentry *dentry) | |||
618 | } | 615 | } |
619 | 616 | ||
620 | static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, | 617 | static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, |
618 | struct kernfs_node *parent, | ||
621 | const char *name, umode_t mode, | 619 | const char *name, umode_t mode, |
622 | kuid_t uid, kgid_t gid, | 620 | kuid_t uid, kgid_t gid, |
623 | unsigned flags) | 621 | unsigned flags) |
@@ -673,6 +671,12 @@ static struct kernfs_node *__kernfs_new_node(struct kernfs_root *root, | |||
673 | goto err_out3; | 671 | goto err_out3; |
674 | } | 672 | } |
675 | 673 | ||
674 | if (parent) { | ||
675 | ret = security_kernfs_init_security(parent, kn); | ||
676 | if (ret) | ||
677 | goto err_out3; | ||
678 | } | ||
679 | |||
676 | return kn; | 680 | return kn; |
677 | 681 | ||
678 | err_out3: | 682 | err_out3: |
@@ -691,7 +695,7 @@ struct kernfs_node *kernfs_new_node(struct kernfs_node *parent, | |||
691 | { | 695 | { |
692 | struct kernfs_node *kn; | 696 | struct kernfs_node *kn; |
693 | 697 | ||
694 | kn = __kernfs_new_node(kernfs_root(parent), | 698 | kn = __kernfs_new_node(kernfs_root(parent), parent, |
695 | name, mode, uid, gid, flags); | 699 | name, mode, uid, gid, flags); |
696 | if (kn) { | 700 | if (kn) { |
697 | kernfs_get(parent); | 701 | kernfs_get(parent); |
@@ -794,9 +798,8 @@ int kernfs_add_one(struct kernfs_node *kn) | |||
794 | /* Update timestamps on the parent */ | 798 | /* Update timestamps on the parent */ |
795 | ps_iattr = parent->iattr; | 799 | ps_iattr = parent->iattr; |
796 | if (ps_iattr) { | 800 | if (ps_iattr) { |
797 | struct iattr *ps_iattrs = &ps_iattr->ia_iattr; | 801 | ktime_get_real_ts64(&ps_iattr->ia_ctime); |
798 | ktime_get_real_ts64(&ps_iattrs->ia_ctime); | 802 | ps_iattr->ia_mtime = ps_iattr->ia_ctime; |
799 | ps_iattrs->ia_mtime = ps_iattrs->ia_ctime; | ||
800 | } | 803 | } |
801 | 804 | ||
802 | mutex_unlock(&kernfs_mutex); | 805 | mutex_unlock(&kernfs_mutex); |
@@ -961,7 +964,7 @@ struct kernfs_root *kernfs_create_root(struct kernfs_syscall_ops *scops, | |||
961 | INIT_LIST_HEAD(&root->supers); | 964 | INIT_LIST_HEAD(&root->supers); |
962 | root->next_generation = 1; | 965 | root->next_generation = 1; |
963 | 966 | ||
964 | kn = __kernfs_new_node(root, "", S_IFDIR | S_IRUGO | S_IXUGO, | 967 | kn = __kernfs_new_node(root, NULL, "", S_IFDIR | S_IRUGO | S_IXUGO, |
965 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, | 968 | GLOBAL_ROOT_UID, GLOBAL_ROOT_GID, |
966 | KERNFS_DIR); | 969 | KERNFS_DIR); |
967 | if (!kn) { | 970 | if (!kn) { |
@@ -1328,9 +1331,8 @@ static void __kernfs_remove(struct kernfs_node *kn) | |||
1328 | 1331 | ||
1329 | /* update timestamps on the parent */ | 1332 | /* update timestamps on the parent */ |
1330 | if (ps_iattr) { | 1333 | if (ps_iattr) { |
1331 | ktime_get_real_ts64(&ps_iattr->ia_iattr.ia_ctime); | 1334 | ktime_get_real_ts64(&ps_iattr->ia_ctime); |
1332 | ps_iattr->ia_iattr.ia_mtime = | 1335 | ps_iattr->ia_mtime = ps_iattr->ia_ctime; |
1333 | ps_iattr->ia_iattr.ia_ctime; | ||
1334 | } | 1336 | } |
1335 | 1337 | ||
1336 | kernfs_put(pos); | 1338 | kernfs_put(pos); |
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c index 0c1fd945ce42..f89a0f13840e 100644 --- a/fs/kernfs/inode.c +++ b/fs/kernfs/inode.c | |||
@@ -31,30 +31,27 @@ static const struct inode_operations kernfs_iops = { | |||
31 | .listxattr = kernfs_iop_listxattr, | 31 | .listxattr = kernfs_iop_listxattr, |
32 | }; | 32 | }; |
33 | 33 | ||
34 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | 34 | static struct kernfs_iattrs *__kernfs_iattrs(struct kernfs_node *kn, int alloc) |
35 | { | 35 | { |
36 | static DEFINE_MUTEX(iattr_mutex); | 36 | static DEFINE_MUTEX(iattr_mutex); |
37 | struct kernfs_iattrs *ret; | 37 | struct kernfs_iattrs *ret; |
38 | struct iattr *iattrs; | ||
39 | 38 | ||
40 | mutex_lock(&iattr_mutex); | 39 | mutex_lock(&iattr_mutex); |
41 | 40 | ||
42 | if (kn->iattr) | 41 | if (kn->iattr || !alloc) |
43 | goto out_unlock; | 42 | goto out_unlock; |
44 | 43 | ||
45 | kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL); | 44 | kn->iattr = kmem_cache_zalloc(kernfs_iattrs_cache, GFP_KERNEL); |
46 | if (!kn->iattr) | 45 | if (!kn->iattr) |
47 | goto out_unlock; | 46 | goto out_unlock; |
48 | iattrs = &kn->iattr->ia_iattr; | ||
49 | 47 | ||
50 | /* assign default attributes */ | 48 | /* assign default attributes */ |
51 | iattrs->ia_mode = kn->mode; | 49 | kn->iattr->ia_uid = GLOBAL_ROOT_UID; |
52 | iattrs->ia_uid = GLOBAL_ROOT_UID; | 50 | kn->iattr->ia_gid = GLOBAL_ROOT_GID; |
53 | iattrs->ia_gid = GLOBAL_ROOT_GID; | ||
54 | 51 | ||
55 | ktime_get_real_ts64(&iattrs->ia_atime); | 52 | ktime_get_real_ts64(&kn->iattr->ia_atime); |
56 | iattrs->ia_mtime = iattrs->ia_atime; | 53 | kn->iattr->ia_mtime = kn->iattr->ia_atime; |
57 | iattrs->ia_ctime = iattrs->ia_atime; | 54 | kn->iattr->ia_ctime = kn->iattr->ia_atime; |
58 | 55 | ||
59 | simple_xattrs_init(&kn->iattr->xattrs); | 56 | simple_xattrs_init(&kn->iattr->xattrs); |
60 | out_unlock: | 57 | out_unlock: |
@@ -63,32 +60,37 @@ out_unlock: | |||
63 | return ret; | 60 | return ret; |
64 | } | 61 | } |
65 | 62 | ||
63 | static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn) | ||
64 | { | ||
65 | return __kernfs_iattrs(kn, 1); | ||
66 | } | ||
67 | |||
68 | static struct kernfs_iattrs *kernfs_iattrs_noalloc(struct kernfs_node *kn) | ||
69 | { | ||
70 | return __kernfs_iattrs(kn, 0); | ||
71 | } | ||
72 | |||
66 | int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) | 73 | int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr) |
67 | { | 74 | { |
68 | struct kernfs_iattrs *attrs; | 75 | struct kernfs_iattrs *attrs; |
69 | struct iattr *iattrs; | ||
70 | unsigned int ia_valid = iattr->ia_valid; | 76 | unsigned int ia_valid = iattr->ia_valid; |
71 | 77 | ||
72 | attrs = kernfs_iattrs(kn); | 78 | attrs = kernfs_iattrs(kn); |
73 | if (!attrs) | 79 | if (!attrs) |
74 | return -ENOMEM; | 80 | return -ENOMEM; |
75 | 81 | ||
76 | iattrs = &attrs->ia_iattr; | ||
77 | |||
78 | if (ia_valid & ATTR_UID) | 82 | if (ia_valid & ATTR_UID) |
79 | iattrs->ia_uid = iattr->ia_uid; | 83 | attrs->ia_uid = iattr->ia_uid; |
80 | if (ia_valid & ATTR_GID) | 84 | if (ia_valid & ATTR_GID) |
81 | iattrs->ia_gid = iattr->ia_gid; | 85 | attrs->ia_gid = iattr->ia_gid; |
82 | if (ia_valid & ATTR_ATIME) | 86 | if (ia_valid & ATTR_ATIME) |
83 | iattrs->ia_atime = iattr->ia_atime; | 87 | attrs->ia_atime = iattr->ia_atime; |
84 | if (ia_valid & ATTR_MTIME) | 88 | if (ia_valid & ATTR_MTIME) |
85 | iattrs->ia_mtime = iattr->ia_mtime; | 89 | attrs->ia_mtime = iattr->ia_mtime; |
86 | if (ia_valid & ATTR_CTIME) | 90 | if (ia_valid & ATTR_CTIME) |
87 | iattrs->ia_ctime = iattr->ia_ctime; | 91 | attrs->ia_ctime = iattr->ia_ctime; |
88 | if (ia_valid & ATTR_MODE) { | 92 | if (ia_valid & ATTR_MODE) |
89 | umode_t mode = iattr->ia_mode; | 93 | kn->mode = iattr->ia_mode; |
90 | iattrs->ia_mode = kn->mode = mode; | ||
91 | } | ||
92 | return 0; | 94 | return 0; |
93 | } | 95 | } |
94 | 96 | ||
@@ -135,23 +137,6 @@ out: | |||
135 | return error; | 137 | return error; |
136 | } | 138 | } |
137 | 139 | ||
138 | static int kernfs_node_setsecdata(struct kernfs_iattrs *attrs, void **secdata, | ||
139 | u32 *secdata_len) | ||
140 | { | ||
141 | void *old_secdata; | ||
142 | size_t old_secdata_len; | ||
143 | |||
144 | old_secdata = attrs->ia_secdata; | ||
145 | old_secdata_len = attrs->ia_secdata_len; | ||
146 | |||
147 | attrs->ia_secdata = *secdata; | ||
148 | attrs->ia_secdata_len = *secdata_len; | ||
149 | |||
150 | *secdata = old_secdata; | ||
151 | *secdata_len = old_secdata_len; | ||
152 | return 0; | ||
153 | } | ||
154 | |||
155 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) | 140 | ssize_t kernfs_iop_listxattr(struct dentry *dentry, char *buf, size_t size) |
156 | { | 141 | { |
157 | struct kernfs_node *kn = kernfs_dentry_node(dentry); | 142 | struct kernfs_node *kn = kernfs_dentry_node(dentry); |
@@ -171,14 +156,15 @@ static inline void set_default_inode_attr(struct inode *inode, umode_t mode) | |||
171 | inode->i_ctime = current_time(inode); | 156 | inode->i_ctime = current_time(inode); |
172 | } | 157 | } |
173 | 158 | ||
174 | static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) | 159 | static inline void set_inode_attr(struct inode *inode, |
160 | struct kernfs_iattrs *attrs) | ||
175 | { | 161 | { |
176 | struct super_block *sb = inode->i_sb; | 162 | struct super_block *sb = inode->i_sb; |
177 | inode->i_uid = iattr->ia_uid; | 163 | inode->i_uid = attrs->ia_uid; |
178 | inode->i_gid = iattr->ia_gid; | 164 | inode->i_gid = attrs->ia_gid; |
179 | inode->i_atime = timespec64_trunc(iattr->ia_atime, sb->s_time_gran); | 165 | inode->i_atime = timespec64_trunc(attrs->ia_atime, sb->s_time_gran); |
180 | inode->i_mtime = timespec64_trunc(iattr->ia_mtime, sb->s_time_gran); | 166 | inode->i_mtime = timespec64_trunc(attrs->ia_mtime, sb->s_time_gran); |
181 | inode->i_ctime = timespec64_trunc(iattr->ia_ctime, sb->s_time_gran); | 167 | inode->i_ctime = timespec64_trunc(attrs->ia_ctime, sb->s_time_gran); |
182 | } | 168 | } |
183 | 169 | ||
184 | static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) | 170 | static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) |
@@ -186,15 +172,12 @@ static void kernfs_refresh_inode(struct kernfs_node *kn, struct inode *inode) | |||
186 | struct kernfs_iattrs *attrs = kn->iattr; | 172 | struct kernfs_iattrs *attrs = kn->iattr; |
187 | 173 | ||
188 | inode->i_mode = kn->mode; | 174 | inode->i_mode = kn->mode; |
189 | if (attrs) { | 175 | if (attrs) |
190 | /* | 176 | /* |
191 | * kernfs_node has non-default attributes get them from | 177 | * kernfs_node has non-default attributes get them from |
192 | * persistent copy in kernfs_node. | 178 | * persistent copy in kernfs_node. |
193 | */ | 179 | */ |
194 | set_inode_attr(inode, &attrs->ia_iattr); | 180 | set_inode_attr(inode, attrs); |
195 | security_inode_notifysecctx(inode, attrs->ia_secdata, | ||
196 | attrs->ia_secdata_len); | ||
197 | } | ||
198 | 181 | ||
199 | if (kernfs_type(kn) == KERNFS_DIR) | 182 | if (kernfs_type(kn) == KERNFS_DIR) |
200 | set_nlink(inode, kn->dir.subdirs + 2); | 183 | set_nlink(inode, kn->dir.subdirs + 2); |
@@ -305,78 +288,57 @@ int kernfs_iop_permission(struct inode *inode, int mask) | |||
305 | return generic_permission(inode, mask); | 288 | return generic_permission(inode, mask); |
306 | } | 289 | } |
307 | 290 | ||
308 | static int kernfs_xattr_get(const struct xattr_handler *handler, | 291 | int kernfs_xattr_get(struct kernfs_node *kn, const char *name, |
309 | struct dentry *unused, struct inode *inode, | 292 | void *value, size_t size) |
310 | const char *suffix, void *value, size_t size) | ||
311 | { | 293 | { |
312 | const char *name = xattr_full_name(handler, suffix); | 294 | struct kernfs_iattrs *attrs = kernfs_iattrs_noalloc(kn); |
313 | struct kernfs_node *kn = inode->i_private; | ||
314 | struct kernfs_iattrs *attrs; | ||
315 | |||
316 | attrs = kernfs_iattrs(kn); | ||
317 | if (!attrs) | 295 | if (!attrs) |
318 | return -ENOMEM; | 296 | return -ENODATA; |
319 | 297 | ||
320 | return simple_xattr_get(&attrs->xattrs, name, value, size); | 298 | return simple_xattr_get(&attrs->xattrs, name, value, size); |
321 | } | 299 | } |
322 | 300 | ||
323 | static int kernfs_xattr_set(const struct xattr_handler *handler, | 301 | int kernfs_xattr_set(struct kernfs_node *kn, const char *name, |
324 | struct dentry *unused, struct inode *inode, | 302 | const void *value, size_t size, int flags) |
325 | const char *suffix, const void *value, | ||
326 | size_t size, int flags) | ||
327 | { | 303 | { |
328 | const char *name = xattr_full_name(handler, suffix); | 304 | struct kernfs_iattrs *attrs = kernfs_iattrs(kn); |
329 | struct kernfs_node *kn = inode->i_private; | ||
330 | struct kernfs_iattrs *attrs; | ||
331 | |||
332 | attrs = kernfs_iattrs(kn); | ||
333 | if (!attrs) | 305 | if (!attrs) |
334 | return -ENOMEM; | 306 | return -ENOMEM; |
335 | 307 | ||
336 | return simple_xattr_set(&attrs->xattrs, name, value, size, flags); | 308 | return simple_xattr_set(&attrs->xattrs, name, value, size, flags); |
337 | } | 309 | } |
338 | 310 | ||
339 | static const struct xattr_handler kernfs_trusted_xattr_handler = { | 311 | static int kernfs_vfs_xattr_get(const struct xattr_handler *handler, |
340 | .prefix = XATTR_TRUSTED_PREFIX, | 312 | struct dentry *unused, struct inode *inode, |
341 | .get = kernfs_xattr_get, | 313 | const char *suffix, void *value, size_t size) |
342 | .set = kernfs_xattr_set, | ||
343 | }; | ||
344 | |||
345 | static int kernfs_security_xattr_set(const struct xattr_handler *handler, | ||
346 | struct dentry *unused, struct inode *inode, | ||
347 | const char *suffix, const void *value, | ||
348 | size_t size, int flags) | ||
349 | { | 314 | { |
315 | const char *name = xattr_full_name(handler, suffix); | ||
350 | struct kernfs_node *kn = inode->i_private; | 316 | struct kernfs_node *kn = inode->i_private; |
351 | struct kernfs_iattrs *attrs; | ||
352 | void *secdata; | ||
353 | u32 secdata_len = 0; | ||
354 | int error; | ||
355 | |||
356 | attrs = kernfs_iattrs(kn); | ||
357 | if (!attrs) | ||
358 | return -ENOMEM; | ||
359 | 317 | ||
360 | error = security_inode_setsecurity(inode, suffix, value, size, flags); | 318 | return kernfs_xattr_get(kn, name, value, size); |
361 | if (error) | 319 | } |
362 | return error; | ||
363 | error = security_inode_getsecctx(inode, &secdata, &secdata_len); | ||
364 | if (error) | ||
365 | return error; | ||
366 | 320 | ||
367 | mutex_lock(&kernfs_mutex); | 321 | static int kernfs_vfs_xattr_set(const struct xattr_handler *handler, |
368 | error = kernfs_node_setsecdata(attrs, &secdata, &secdata_len); | 322 | struct dentry *unused, struct inode *inode, |
369 | mutex_unlock(&kernfs_mutex); | 323 | const char *suffix, const void *value, |
324 | size_t size, int flags) | ||
325 | { | ||
326 | const char *name = xattr_full_name(handler, suffix); | ||
327 | struct kernfs_node *kn = inode->i_private; | ||
370 | 328 | ||
371 | if (secdata) | 329 | return kernfs_xattr_set(kn, name, value, size, flags); |
372 | security_release_secctx(secdata, secdata_len); | ||
373 | return error; | ||
374 | } | 330 | } |
375 | 331 | ||
332 | static const struct xattr_handler kernfs_trusted_xattr_handler = { | ||
333 | .prefix = XATTR_TRUSTED_PREFIX, | ||
334 | .get = kernfs_vfs_xattr_get, | ||
335 | .set = kernfs_vfs_xattr_set, | ||
336 | }; | ||
337 | |||
376 | static const struct xattr_handler kernfs_security_xattr_handler = { | 338 | static const struct xattr_handler kernfs_security_xattr_handler = { |
377 | .prefix = XATTR_SECURITY_PREFIX, | 339 | .prefix = XATTR_SECURITY_PREFIX, |
378 | .get = kernfs_xattr_get, | 340 | .get = kernfs_vfs_xattr_get, |
379 | .set = kernfs_security_xattr_set, | 341 | .set = kernfs_vfs_xattr_set, |
380 | }; | 342 | }; |
381 | 343 | ||
382 | const struct xattr_handler *kernfs_xattr_handlers[] = { | 344 | const struct xattr_handler *kernfs_xattr_handlers[] = { |
diff --git a/fs/kernfs/kernfs-internal.h b/fs/kernfs/kernfs-internal.h index 0b7d197a904c..3c437990f39a 100644 --- a/fs/kernfs/kernfs-internal.h +++ b/fs/kernfs/kernfs-internal.h | |||
@@ -20,9 +20,11 @@ | |||
20 | #include <linux/fs_context.h> | 20 | #include <linux/fs_context.h> |
21 | 21 | ||
22 | struct kernfs_iattrs { | 22 | struct kernfs_iattrs { |
23 | struct iattr ia_iattr; | 23 | kuid_t ia_uid; |
24 | void *ia_secdata; | 24 | kgid_t ia_gid; |
25 | u32 ia_secdata_len; | 25 | struct timespec64 ia_atime; |
26 | struct timespec64 ia_mtime; | ||
27 | struct timespec64 ia_ctime; | ||
26 | 28 | ||
27 | struct simple_xattrs xattrs; | 29 | struct simple_xattrs xattrs; |
28 | }; | 30 | }; |
diff --git a/fs/kernfs/symlink.c b/fs/kernfs/symlink.c index 162f43b80c84..eb46c3a16e2f 100644 --- a/fs/kernfs/symlink.c +++ b/fs/kernfs/symlink.c | |||
@@ -33,8 +33,8 @@ struct kernfs_node *kernfs_create_link(struct kernfs_node *parent, | |||
33 | kgid_t gid = GLOBAL_ROOT_GID; | 33 | kgid_t gid = GLOBAL_ROOT_GID; |
34 | 34 | ||
35 | if (target->iattr) { | 35 | if (target->iattr) { |
36 | uid = target->iattr->ia_iattr.ia_uid; | 36 | uid = target->iattr->ia_uid; |
37 | gid = target->iattr->ia_iattr.ia_gid; | 37 | gid = target->iattr->ia_gid; |
38 | } | 38 | } |
39 | 39 | ||
40 | kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, uid, gid, | 40 | kn = kernfs_new_node(parent, name, S_IFLNK|S_IRWXUGO, uid, gid, |
diff --git a/fs/proc/base.c b/fs/proc/base.c index f179568b4c76..b6ccb6c57706 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -2535,6 +2535,11 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf, | |||
2535 | rcu_read_unlock(); | 2535 | rcu_read_unlock(); |
2536 | return -EACCES; | 2536 | return -EACCES; |
2537 | } | 2537 | } |
2538 | /* Prevent changes to overridden credentials. */ | ||
2539 | if (current_cred() != current_real_cred()) { | ||
2540 | rcu_read_unlock(); | ||
2541 | return -EBUSY; | ||
2542 | } | ||
2538 | rcu_read_unlock(); | 2543 | rcu_read_unlock(); |
2539 | 2544 | ||
2540 | if (count > PAGE_SIZE) | 2545 | if (count > PAGE_SIZE) |
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h index e446ab97ee0c..2bf477f86eb1 100644 --- a/include/linux/kernfs.h +++ b/include/linux/kernfs.h | |||
@@ -371,6 +371,11 @@ __poll_t kernfs_generic_poll(struct kernfs_open_file *of, | |||
371 | struct poll_table_struct *pt); | 371 | struct poll_table_struct *pt); |
372 | void kernfs_notify(struct kernfs_node *kn); | 372 | void kernfs_notify(struct kernfs_node *kn); |
373 | 373 | ||
374 | int kernfs_xattr_get(struct kernfs_node *kn, const char *name, | ||
375 | void *value, size_t size); | ||
376 | int kernfs_xattr_set(struct kernfs_node *kn, const char *name, | ||
377 | const void *value, size_t size, int flags); | ||
378 | |||
374 | const void *kernfs_super_ns(struct super_block *sb); | 379 | const void *kernfs_super_ns(struct super_block *sb); |
375 | int kernfs_get_tree(struct fs_context *fc); | 380 | int kernfs_get_tree(struct fs_context *fc); |
376 | void kernfs_free_fs_context(struct fs_context *fc); | 381 | void kernfs_free_fs_context(struct fs_context *fc); |
@@ -473,6 +478,14 @@ static inline int kernfs_setattr(struct kernfs_node *kn, | |||
473 | 478 | ||
474 | static inline void kernfs_notify(struct kernfs_node *kn) { } | 479 | static inline void kernfs_notify(struct kernfs_node *kn) { } |
475 | 480 | ||
481 | static inline int kernfs_xattr_get(struct kernfs_node *kn, const char *name, | ||
482 | void *value, size_t size) | ||
483 | { return -ENOSYS; } | ||
484 | |||
485 | static inline int kernfs_xattr_set(struct kernfs_node *kn, const char *name, | ||
486 | const void *value, size_t size, int flags) | ||
487 | { return -ENOSYS; } | ||
488 | |||
476 | static inline const void *kernfs_super_ns(struct super_block *sb) | 489 | static inline const void *kernfs_super_ns(struct super_block *sb) |
477 | { return NULL; } | 490 | { return NULL; } |
478 | 491 | ||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h index a240a3fc5fc4..f7e55d0d2672 100644 --- a/include/linux/lsm_hooks.h +++ b/include/linux/lsm_hooks.h | |||
@@ -445,6 +445,15 @@ | |||
445 | * to abort the copy up. Note that the caller is responsible for reading | 445 | * to abort the copy up. Note that the caller is responsible for reading |
446 | * and writing the xattrs as this hook is merely a filter. | 446 | * and writing the xattrs as this hook is merely a filter. |
447 | * | 447 | * |
448 | * Security hooks for kernfs node operations | ||
449 | * | ||
450 | * @kernfs_init_security: | ||
451 | * Initialize the security context of a newly created kernfs node based | ||
452 | * on its own and its parent's attributes. | ||
453 | * | ||
454 | * @kn_dir the parent kernfs node | ||
455 | * @kn the new child kernfs node | ||
456 | * | ||
448 | * Security hooks for file operations | 457 | * Security hooks for file operations |
449 | * | 458 | * |
450 | * @file_permission: | 459 | * @file_permission: |
@@ -1570,6 +1579,9 @@ union security_list_options { | |||
1570 | int (*inode_copy_up)(struct dentry *src, struct cred **new); | 1579 | int (*inode_copy_up)(struct dentry *src, struct cred **new); |
1571 | int (*inode_copy_up_xattr)(const char *name); | 1580 | int (*inode_copy_up_xattr)(const char *name); |
1572 | 1581 | ||
1582 | int (*kernfs_init_security)(struct kernfs_node *kn_dir, | ||
1583 | struct kernfs_node *kn); | ||
1584 | |||
1573 | int (*file_permission)(struct file *file, int mask); | 1585 | int (*file_permission)(struct file *file, int mask); |
1574 | int (*file_alloc_security)(struct file *file); | 1586 | int (*file_alloc_security)(struct file *file); |
1575 | void (*file_free_security)(struct file *file); | 1587 | void (*file_free_security)(struct file *file); |
@@ -1871,6 +1883,7 @@ struct security_hook_heads { | |||
1871 | struct hlist_head inode_getsecid; | 1883 | struct hlist_head inode_getsecid; |
1872 | struct hlist_head inode_copy_up; | 1884 | struct hlist_head inode_copy_up; |
1873 | struct hlist_head inode_copy_up_xattr; | 1885 | struct hlist_head inode_copy_up_xattr; |
1886 | struct hlist_head kernfs_init_security; | ||
1874 | struct hlist_head file_permission; | 1887 | struct hlist_head file_permission; |
1875 | struct hlist_head file_alloc_security; | 1888 | struct hlist_head file_alloc_security; |
1876 | struct hlist_head file_free_security; | 1889 | struct hlist_head file_free_security; |
diff --git a/include/linux/security.h b/include/linux/security.h index 49f2685324b0..d543293216b9 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -51,6 +51,7 @@ struct fown_struct; | |||
51 | struct file_operations; | 51 | struct file_operations; |
52 | struct msg_msg; | 52 | struct msg_msg; |
53 | struct xattr; | 53 | struct xattr; |
54 | struct kernfs_node; | ||
54 | struct xfrm_sec_ctx; | 55 | struct xfrm_sec_ctx; |
55 | struct mm_struct; | 56 | struct mm_struct; |
56 | struct fs_context; | 57 | struct fs_context; |
@@ -299,6 +300,8 @@ int security_inode_listsecurity(struct inode *inode, char *buffer, size_t buffer | |||
299 | void security_inode_getsecid(struct inode *inode, u32 *secid); | 300 | void security_inode_getsecid(struct inode *inode, u32 *secid); |
300 | int security_inode_copy_up(struct dentry *src, struct cred **new); | 301 | int security_inode_copy_up(struct dentry *src, struct cred **new); |
301 | int security_inode_copy_up_xattr(const char *name); | 302 | int security_inode_copy_up_xattr(const char *name); |
303 | int security_kernfs_init_security(struct kernfs_node *kn_dir, | ||
304 | struct kernfs_node *kn); | ||
302 | int security_file_permission(struct file *file, int mask); | 305 | int security_file_permission(struct file *file, int mask); |
303 | int security_file_alloc(struct file *file); | 306 | int security_file_alloc(struct file *file); |
304 | void security_file_free(struct file *file); | 307 | void security_file_free(struct file *file); |
@@ -801,6 +804,12 @@ static inline int security_inode_copy_up(struct dentry *src, struct cred **new) | |||
801 | return 0; | 804 | return 0; |
802 | } | 805 | } |
803 | 806 | ||
807 | static inline int security_kernfs_init_security(struct kernfs_node *kn_dir, | ||
808 | struct kernfs_node *kn) | ||
809 | { | ||
810 | return 0; | ||
811 | } | ||
812 | |||
804 | static inline int security_inode_copy_up_xattr(const char *name) | 813 | static inline int security_inode_copy_up_xattr(const char *name) |
805 | { | 814 | { |
806 | return -EOPNOTSUPP; | 815 | return -EOPNOTSUPP; |
diff --git a/scripts/selinux/install_policy.sh b/scripts/selinux/install_policy.sh index 0b86c47baf7d..2dccf141241d 100755 --- a/scripts/selinux/install_policy.sh +++ b/scripts/selinux/install_policy.sh | |||
@@ -1,30 +1,61 @@ | |||
1 | #!/bin/sh | 1 | #!/bin/sh |
2 | # SPDX-License-Identifier: GPL-2.0 | 2 | # SPDX-License-Identifier: GPL-2.0 |
3 | set -e | ||
3 | if [ `id -u` -ne 0 ]; then | 4 | if [ `id -u` -ne 0 ]; then |
4 | echo "$0: must be root to install the selinux policy" | 5 | echo "$0: must be root to install the selinux policy" |
5 | exit 1 | 6 | exit 1 |
6 | fi | 7 | fi |
8 | |||
7 | SF=`which setfiles` | 9 | SF=`which setfiles` |
8 | if [ $? -eq 1 ]; then | 10 | if [ $? -eq 1 ]; then |
9 | if [ -f /sbin/setfiles ]; then | 11 | echo "Could not find setfiles" |
10 | SF="/usr/setfiles" | 12 | echo "Do you have policycoreutils installed?" |
11 | else | 13 | exit 1 |
12 | echo "no selinux tools installed: setfiles" | ||
13 | exit 1 | ||
14 | fi | ||
15 | fi | 14 | fi |
16 | 15 | ||
17 | cd mdp | ||
18 | |||
19 | CP=`which checkpolicy` | 16 | CP=`which checkpolicy` |
17 | if [ $? -eq 1 ]; then | ||
18 | echo "Could not find checkpolicy" | ||
19 | echo "Do you have checkpolicy installed?" | ||
20 | exit 1 | ||
21 | fi | ||
20 | VERS=`$CP -V | awk '{print $1}'` | 22 | VERS=`$CP -V | awk '{print $1}'` |
21 | 23 | ||
22 | ./mdp policy.conf file_contexts | 24 | ENABLED=`which selinuxenabled` |
23 | $CP -o policy.$VERS policy.conf | 25 | if [ $? -eq 1 ]; then |
26 | echo "Could not find selinuxenabled" | ||
27 | echo "Do you have libselinux-utils installed?" | ||
28 | exit 1 | ||
29 | fi | ||
30 | |||
31 | if selinuxenabled; then | ||
32 | echo "SELinux is already enabled" | ||
33 | echo "This prevents safely relabeling all files." | ||
34 | echo "Boot with selinux=0 on the kernel command-line or" | ||
35 | echo "SELINUX=disabled in /etc/selinux/config." | ||
36 | exit 1 | ||
37 | fi | ||
38 | |||
39 | cd mdp | ||
40 | ./mdp -m policy.conf file_contexts | ||
41 | $CP -U allow -M -o policy.$VERS policy.conf | ||
24 | 42 | ||
25 | mkdir -p /etc/selinux/dummy/policy | 43 | mkdir -p /etc/selinux/dummy/policy |
26 | mkdir -p /etc/selinux/dummy/contexts/files | 44 | mkdir -p /etc/selinux/dummy/contexts/files |
27 | 45 | ||
46 | echo "__default__:user_u:s0" > /etc/selinux/dummy/seusers | ||
47 | echo "base_r:base_t:s0" > /etc/selinux/dummy/contexts/failsafe_context | ||
48 | echo "base_r:base_t:s0 base_r:base_t:s0" > /etc/selinux/dummy/default_contexts | ||
49 | cat > /etc/selinux/dummy/contexts/x_contexts <<EOF | ||
50 | client * user_u:base_r:base_t:s0 | ||
51 | property * user_u:object_r:base_t:s0 | ||
52 | extension * user_u:object_r:base_t:s0 | ||
53 | selection * user_u:object_r:base_t:s0 | ||
54 | event * user_u:object_r:base_t:s0 | ||
55 | EOF | ||
56 | touch /etc/selinux/dummy/contexts/virtual_domain_context | ||
57 | touch /etc/selinux/dummy/contexts/virtual_image_context | ||
58 | |||
28 | cp file_contexts /etc/selinux/dummy/contexts/files | 59 | cp file_contexts /etc/selinux/dummy/contexts/files |
29 | cp dbus_contexts /etc/selinux/dummy/contexts | 60 | cp dbus_contexts /etc/selinux/dummy/contexts |
30 | cp policy.$VERS /etc/selinux/dummy/policy | 61 | cp policy.$VERS /etc/selinux/dummy/policy |
@@ -33,37 +64,22 @@ FC_FILE=/etc/selinux/dummy/contexts/files/file_contexts | |||
33 | if [ ! -d /etc/selinux ]; then | 64 | if [ ! -d /etc/selinux ]; then |
34 | mkdir -p /etc/selinux | 65 | mkdir -p /etc/selinux |
35 | fi | 66 | fi |
36 | if [ ! -f /etc/selinux/config ]; then | 67 | if [ -f /etc/selinux/config ]; then |
37 | cat > /etc/selinux/config << EOF | 68 | echo "/etc/selinux/config exists, moving to /etc/selinux/config.bak." |
38 | SELINUX=enforcing | 69 | mv /etc/selinux/config /etc/selinux/config.bak |
70 | fi | ||
71 | echo "Creating new /etc/selinux/config for dummy policy." | ||
72 | cat > /etc/selinux/config << EOF | ||
73 | SELINUX=permissive | ||
39 | SELINUXTYPE=dummy | 74 | SELINUXTYPE=dummy |
40 | EOF | 75 | EOF |
41 | else | ||
42 | TYPE=`cat /etc/selinux/config | grep "^SELINUXTYPE" | tail -1 | awk -F= '{ print $2 '}` | ||
43 | if [ "eq$TYPE" != "eqdummy" ]; then | ||
44 | selinuxenabled | ||
45 | if [ $? -eq 0 ]; then | ||
46 | echo "SELinux already enabled with a non-dummy policy." | ||
47 | echo "Exiting. Please install policy by hand if that" | ||
48 | echo "is what you REALLY want." | ||
49 | exit 1 | ||
50 | fi | ||
51 | mv /etc/selinux/config /etc/selinux/config.mdpbak | ||
52 | grep -v "^SELINUXTYPE" /etc/selinux/config.mdpbak >> /etc/selinux/config | ||
53 | echo "SELINUXTYPE=dummy" >> /etc/selinux/config | ||
54 | fi | ||
55 | fi | ||
56 | 76 | ||
57 | cd /etc/selinux/dummy/contexts/files | 77 | cd /etc/selinux/dummy/contexts/files |
58 | $SF file_contexts / | 78 | $SF -F file_contexts / |
59 | 79 | ||
60 | mounts=`cat /proc/$$/mounts | egrep "ext2|ext3|xfs|jfs|ext4|ext4dev|gfs2" | awk '{ print $2 '}` | 80 | mounts=`cat /proc/$$/mounts | \ |
61 | $SF file_contexts $mounts | 81 | egrep "ext[234]|jfs|xfs|reiserfs|jffs2|gfs2|btrfs|f2fs|ocfs2" | \ |
82 | awk '{ print $2 '}` | ||
83 | $SF -F file_contexts $mounts | ||
62 | 84 | ||
63 | 85 | echo "-F" > /.autorelabel | |
64 | dodev=`cat /proc/$$/mounts | grep "/dev "` | ||
65 | if [ "eq$dodev" != "eq" ]; then | ||
66 | mount --move /dev /mnt | ||
67 | $SF file_contexts /dev | ||
68 | mount --move /mnt /dev | ||
69 | fi | ||
diff --git a/scripts/selinux/mdp/Makefile b/scripts/selinux/mdp/Makefile index e9c92db7e2a3..8a1269a9d0ba 100644 --- a/scripts/selinux/mdp/Makefile +++ b/scripts/selinux/mdp/Makefile | |||
@@ -2,7 +2,7 @@ | |||
2 | hostprogs-y := mdp | 2 | hostprogs-y := mdp |
3 | HOST_EXTRACFLAGS += \ | 3 | HOST_EXTRACFLAGS += \ |
4 | -I$(srctree)/include/uapi -I$(srctree)/include \ | 4 | -I$(srctree)/include/uapi -I$(srctree)/include \ |
5 | -I$(srctree)/security/selinux/include | 5 | -I$(srctree)/security/selinux/include -I$(objtree)/include |
6 | 6 | ||
7 | always := $(hostprogs-y) | 7 | always := $(hostprogs-y) |
8 | clean-files := policy.* file_contexts | 8 | clean-files := policy.* file_contexts |
diff --git a/scripts/selinux/mdp/mdp.c b/scripts/selinux/mdp/mdp.c index 6d51b74bc679..18fd6143888b 100644 --- a/scripts/selinux/mdp/mdp.c +++ b/scripts/selinux/mdp/mdp.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include <stdlib.h> | 32 | #include <stdlib.h> |
33 | #include <unistd.h> | 33 | #include <unistd.h> |
34 | #include <string.h> | 34 | #include <string.h> |
35 | #include <linux/kconfig.h> | ||
35 | 36 | ||
36 | static void usage(char *name) | 37 | static void usage(char *name) |
37 | { | 38 | { |
@@ -94,10 +95,31 @@ int main(int argc, char *argv[]) | |||
94 | } | 95 | } |
95 | fprintf(fout, "\n"); | 96 | fprintf(fout, "\n"); |
96 | 97 | ||
97 | /* NOW PRINT OUT MLS STUFF */ | 98 | /* print out mls declarations and constraints */ |
98 | if (mls) { | 99 | if (mls) { |
99 | printf("MLS not yet implemented\n"); | 100 | fprintf(fout, "sensitivity s0;\n"); |
100 | exit(1); | 101 | fprintf(fout, "sensitivity s1;\n"); |
102 | fprintf(fout, "dominance { s0 s1 }\n"); | ||
103 | fprintf(fout, "category c0;\n"); | ||
104 | fprintf(fout, "category c1;\n"); | ||
105 | fprintf(fout, "level s0:c0.c1;\n"); | ||
106 | fprintf(fout, "level s1:c0.c1;\n"); | ||
107 | #define SYSTEMLOW "s0" | ||
108 | #define SYSTEMHIGH "s1:c0.c1" | ||
109 | for (i = 0; secclass_map[i].name; i++) { | ||
110 | struct security_class_mapping *map = &secclass_map[i]; | ||
111 | |||
112 | fprintf(fout, "mlsconstrain %s {\n", map->name); | ||
113 | for (j = 0; map->perms[j]; j++) | ||
114 | fprintf(fout, "\t%s\n", map->perms[j]); | ||
115 | /* | ||
116 | * This requires all subjects and objects to be | ||
117 | * single-level (l2 eq h2), and that the subject | ||
118 | * level dominate the object level (h1 dom h2) | ||
119 | * in order to have any permissions to it. | ||
120 | */ | ||
121 | fprintf(fout, "} (l2 eq h2 and h1 dom h2);\n\n"); | ||
122 | } | ||
101 | } | 123 | } |
102 | 124 | ||
103 | /* types, roles, and allows */ | 125 | /* types, roles, and allows */ |
@@ -107,34 +129,127 @@ int main(int argc, char *argv[]) | |||
107 | for (i = 0; secclass_map[i].name; i++) | 129 | for (i = 0; secclass_map[i].name; i++) |
108 | fprintf(fout, "allow base_t base_t:%s *;\n", | 130 | fprintf(fout, "allow base_t base_t:%s *;\n", |
109 | secclass_map[i].name); | 131 | secclass_map[i].name); |
110 | fprintf(fout, "user user_u roles { base_r };\n"); | 132 | fprintf(fout, "user user_u roles { base_r }"); |
111 | fprintf(fout, "\n"); | 133 | if (mls) |
134 | fprintf(fout, " level %s range %s - %s", SYSTEMLOW, | ||
135 | SYSTEMLOW, SYSTEMHIGH); | ||
136 | fprintf(fout, ";\n"); | ||
137 | |||
138 | #define SUBJUSERROLETYPE "user_u:base_r:base_t" | ||
139 | #define OBJUSERROLETYPE "user_u:object_r:base_t" | ||
112 | 140 | ||
113 | /* default sids */ | 141 | /* default sids */ |
114 | for (i = 1; i < initial_sid_to_string_len; i++) | 142 | for (i = 1; i < initial_sid_to_string_len; i++) |
115 | fprintf(fout, "sid %s user_u:base_r:base_t\n", initial_sid_to_string[i]); | 143 | fprintf(fout, "sid %s " SUBJUSERROLETYPE "%s\n", |
144 | initial_sid_to_string[i], mls ? ":" SYSTEMLOW : ""); | ||
116 | fprintf(fout, "\n"); | 145 | fprintf(fout, "\n"); |
117 | 146 | ||
118 | fprintf(fout, "fs_use_xattr ext2 user_u:base_r:base_t;\n"); | 147 | #define FS_USE(behavior, fstype) \ |
119 | fprintf(fout, "fs_use_xattr ext3 user_u:base_r:base_t;\n"); | 148 | fprintf(fout, "fs_use_%s %s " OBJUSERROLETYPE "%s;\n", \ |
120 | fprintf(fout, "fs_use_xattr ext4 user_u:base_r:base_t;\n"); | 149 | behavior, fstype, mls ? ":" SYSTEMLOW : "") |
121 | fprintf(fout, "fs_use_xattr jfs user_u:base_r:base_t;\n"); | 150 | |
122 | fprintf(fout, "fs_use_xattr xfs user_u:base_r:base_t;\n"); | 151 | /* |
123 | fprintf(fout, "fs_use_xattr reiserfs user_u:base_r:base_t;\n"); | 152 | * Filesystems whose inode labels can be fetched via getxattr. |
124 | fprintf(fout, "fs_use_xattr jffs2 user_u:base_r:base_t;\n"); | 153 | */ |
125 | fprintf(fout, "fs_use_xattr gfs2 user_u:base_r:base_t;\n"); | 154 | #ifdef CONFIG_EXT2_FS_SECURITY |
155 | FS_USE("xattr", "ext2"); | ||
156 | #endif | ||
157 | #ifdef CONFIG_EXT4_FS_SECURITY | ||
158 | #ifdef CONFIG_EXT4_USE_FOR_EXT2 | ||
159 | FS_USE("xattr", "ext2"); | ||
160 | #endif | ||
161 | FS_USE("xattr", "ext3"); | ||
162 | FS_USE("xattr", "ext4"); | ||
163 | #endif | ||
164 | #ifdef CONFIG_JFS_SECURITY | ||
165 | FS_USE("xattr", "jfs"); | ||
166 | #endif | ||
167 | #ifdef CONFIG_REISERFS_FS_SECURITY | ||
168 | FS_USE("xattr", "reiserfs"); | ||
169 | #endif | ||
170 | #ifdef CONFIG_JFFS2_FS_SECURITY | ||
171 | FS_USE("xattr", "jffs2"); | ||
172 | #endif | ||
173 | #ifdef CONFIG_XFS_FS | ||
174 | FS_USE("xattr", "xfs"); | ||
175 | #endif | ||
176 | #ifdef CONFIG_GFS2_FS | ||
177 | FS_USE("xattr", "gfs2"); | ||
178 | #endif | ||
179 | #ifdef CONFIG_BTRFS_FS | ||
180 | FS_USE("xattr", "btrfs"); | ||
181 | #endif | ||
182 | #ifdef CONFIG_F2FS_FS_SECURITY | ||
183 | FS_USE("xattr", "f2fs"); | ||
184 | #endif | ||
185 | #ifdef CONFIG_OCFS2_FS | ||
186 | FS_USE("xattr", "ocsfs2"); | ||
187 | #endif | ||
188 | #ifdef CONFIG_OVERLAY_FS | ||
189 | FS_USE("xattr", "overlay"); | ||
190 | #endif | ||
191 | #ifdef CONFIG_SQUASHFS_XATTR | ||
192 | FS_USE("xattr", "squashfs"); | ||
193 | #endif | ||
194 | |||
195 | /* | ||
196 | * Filesystems whose inodes are labeled from allocating task. | ||
197 | */ | ||
198 | FS_USE("task", "pipefs"); | ||
199 | FS_USE("task", "sockfs"); | ||
126 | 200 | ||
127 | fprintf(fout, "fs_use_task eventpollfs user_u:base_r:base_t;\n"); | 201 | /* |
128 | fprintf(fout, "fs_use_task pipefs user_u:base_r:base_t;\n"); | 202 | * Filesystems whose inode labels are computed from both |
129 | fprintf(fout, "fs_use_task sockfs user_u:base_r:base_t;\n"); | 203 | * the allocating task and the superblock label. |
204 | */ | ||
205 | #ifdef CONFIG_UNIX98_PTYS | ||
206 | FS_USE("trans", "devpts"); | ||
207 | #endif | ||
208 | #ifdef CONFIG_HUGETLBFS | ||
209 | FS_USE("trans", "hugetlbfs"); | ||
210 | #endif | ||
211 | #ifdef CONFIG_TMPFS | ||
212 | FS_USE("trans", "tmpfs"); | ||
213 | #endif | ||
214 | #ifdef CONFIG_DEVTMPFS | ||
215 | FS_USE("trans", "devtmpfs"); | ||
216 | #endif | ||
217 | #ifdef CONFIG_POSIX_MQUEUE | ||
218 | FS_USE("trans", "mqueue"); | ||
219 | #endif | ||
130 | 220 | ||
131 | fprintf(fout, "fs_use_trans mqueue user_u:base_r:base_t;\n"); | 221 | #define GENFSCON(fstype, prefix) \ |
132 | fprintf(fout, "fs_use_trans devpts user_u:base_r:base_t;\n"); | 222 | fprintf(fout, "genfscon %s %s " OBJUSERROLETYPE "%s\n", \ |
133 | fprintf(fout, "fs_use_trans hugetlbfs user_u:base_r:base_t;\n"); | 223 | fstype, prefix, mls ? ":" SYSTEMLOW : "") |
134 | fprintf(fout, "fs_use_trans tmpfs user_u:base_r:base_t;\n"); | ||
135 | fprintf(fout, "fs_use_trans shm user_u:base_r:base_t;\n"); | ||
136 | 224 | ||
137 | fprintf(fout, "genfscon proc / user_u:base_r:base_t\n"); | 225 | /* |
226 | * Filesystems whose inodes are labeled from path prefix match | ||
227 | * relative to the filesystem root. Depending on the filesystem, | ||
228 | * only a single label for all inodes may be supported. Here | ||
229 | * we list the filesystem types for which per-file labeling is | ||
230 | * supported using genfscon; any other filesystem type can also | ||
231 | * be added by only with a single entry for all of its inodes. | ||
232 | */ | ||
233 | #ifdef CONFIG_PROC_FS | ||
234 | GENFSCON("proc", "/"); | ||
235 | #endif | ||
236 | #ifdef CONFIG_SECURITY_SELINUX | ||
237 | GENFSCON("selinuxfs", "/"); | ||
238 | #endif | ||
239 | #ifdef CONFIG_SYSFS | ||
240 | GENFSCON("sysfs", "/"); | ||
241 | #endif | ||
242 | #ifdef CONFIG_DEBUG_FS | ||
243 | GENFSCON("debugfs", "/"); | ||
244 | #endif | ||
245 | #ifdef CONFIG_TRACING | ||
246 | GENFSCON("tracefs", "/"); | ||
247 | #endif | ||
248 | #ifdef CONFIG_PSTORE | ||
249 | GENFSCON("pstore", "/"); | ||
250 | #endif | ||
251 | GENFSCON("cgroup", "/"); | ||
252 | GENFSCON("cgroup2", "/"); | ||
138 | 253 | ||
139 | fclose(fout); | 254 | fclose(fout); |
140 | 255 | ||
@@ -143,8 +258,8 @@ int main(int argc, char *argv[]) | |||
143 | printf("Wrote policy, but cannot open %s for writing\n", ctxout); | 258 | printf("Wrote policy, but cannot open %s for writing\n", ctxout); |
144 | usage(argv[0]); | 259 | usage(argv[0]); |
145 | } | 260 | } |
146 | fprintf(fout, "/ user_u:base_r:base_t\n"); | 261 | fprintf(fout, "/ " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); |
147 | fprintf(fout, "/.* user_u:base_r:base_t\n"); | 262 | fprintf(fout, "/.* " OBJUSERROLETYPE "%s\n", mls ? ":" SYSTEMLOW : ""); |
148 | fclose(fout); | 263 | fclose(fout); |
149 | 264 | ||
150 | return 0; | 265 | return 0; |
diff --git a/security/security.c b/security/security.c index 23cbb1a295a3..8d6ef9da94eb 100644 --- a/security/security.c +++ b/security/security.c | |||
@@ -1318,6 +1318,12 @@ int security_inode_copy_up_xattr(const char *name) | |||
1318 | } | 1318 | } |
1319 | EXPORT_SYMBOL(security_inode_copy_up_xattr); | 1319 | EXPORT_SYMBOL(security_inode_copy_up_xattr); |
1320 | 1320 | ||
1321 | int security_kernfs_init_security(struct kernfs_node *kn_dir, | ||
1322 | struct kernfs_node *kn) | ||
1323 | { | ||
1324 | return call_int_hook(kernfs_init_security, 0, kn_dir, kn); | ||
1325 | } | ||
1326 | |||
1321 | int security_file_permission(struct file *file, int mask) | 1327 | int security_file_permission(struct file *file, int mask) |
1322 | { | 1328 | { |
1323 | int ret; | 1329 | int ret; |
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index 1d0b37af2444..c61787b15f27 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c | |||
@@ -89,6 +89,8 @@ | |||
89 | #include <linux/msg.h> | 89 | #include <linux/msg.h> |
90 | #include <linux/shm.h> | 90 | #include <linux/shm.h> |
91 | #include <linux/bpf.h> | 91 | #include <linux/bpf.h> |
92 | #include <linux/kernfs.h> | ||
93 | #include <linux/stringhash.h> /* for hashlen_string() */ | ||
92 | #include <uapi/linux/mount.h> | 94 | #include <uapi/linux/mount.h> |
93 | 95 | ||
94 | #include "avc.h" | 96 | #include "avc.h" |
@@ -751,11 +753,13 @@ static int selinux_set_mnt_opts(struct super_block *sb, | |||
751 | 753 | ||
752 | if (!strcmp(sb->s_type->name, "debugfs") || | 754 | if (!strcmp(sb->s_type->name, "debugfs") || |
753 | !strcmp(sb->s_type->name, "tracefs") || | 755 | !strcmp(sb->s_type->name, "tracefs") || |
754 | !strcmp(sb->s_type->name, "sysfs") || | 756 | !strcmp(sb->s_type->name, "pstore")) |
755 | !strcmp(sb->s_type->name, "pstore") || | 757 | sbsec->flags |= SE_SBGENFS; |
758 | |||
759 | if (!strcmp(sb->s_type->name, "sysfs") || | ||
756 | !strcmp(sb->s_type->name, "cgroup") || | 760 | !strcmp(sb->s_type->name, "cgroup") || |
757 | !strcmp(sb->s_type->name, "cgroup2")) | 761 | !strcmp(sb->s_type->name, "cgroup2")) |
758 | sbsec->flags |= SE_SBGENFS; | 762 | sbsec->flags |= SE_SBGENFS | SE_SBGENFS_XATTR; |
759 | 763 | ||
760 | if (!sbsec->behavior) { | 764 | if (!sbsec->behavior) { |
761 | /* | 765 | /* |
@@ -1354,6 +1358,67 @@ static int selinux_genfs_get_sid(struct dentry *dentry, | |||
1354 | return rc; | 1358 | return rc; |
1355 | } | 1359 | } |
1356 | 1360 | ||
1361 | static int inode_doinit_use_xattr(struct inode *inode, struct dentry *dentry, | ||
1362 | u32 def_sid, u32 *sid) | ||
1363 | { | ||
1364 | #define INITCONTEXTLEN 255 | ||
1365 | char *context; | ||
1366 | unsigned int len; | ||
1367 | int rc; | ||
1368 | |||
1369 | len = INITCONTEXTLEN; | ||
1370 | context = kmalloc(len + 1, GFP_NOFS); | ||
1371 | if (!context) | ||
1372 | return -ENOMEM; | ||
1373 | |||
1374 | context[len] = '\0'; | ||
1375 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); | ||
1376 | if (rc == -ERANGE) { | ||
1377 | kfree(context); | ||
1378 | |||
1379 | /* Need a larger buffer. Query for the right size. */ | ||
1380 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0); | ||
1381 | if (rc < 0) | ||
1382 | return rc; | ||
1383 | |||
1384 | len = rc; | ||
1385 | context = kmalloc(len + 1, GFP_NOFS); | ||
1386 | if (!context) | ||
1387 | return -ENOMEM; | ||
1388 | |||
1389 | context[len] = '\0'; | ||
1390 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, | ||
1391 | context, len); | ||
1392 | } | ||
1393 | if (rc < 0) { | ||
1394 | kfree(context); | ||
1395 | if (rc != -ENODATA) { | ||
1396 | pr_warn("SELinux: %s: getxattr returned %d for dev=%s ino=%ld\n", | ||
1397 | __func__, -rc, inode->i_sb->s_id, inode->i_ino); | ||
1398 | return rc; | ||
1399 | } | ||
1400 | *sid = def_sid; | ||
1401 | return 0; | ||
1402 | } | ||
1403 | |||
1404 | rc = security_context_to_sid_default(&selinux_state, context, rc, sid, | ||
1405 | def_sid, GFP_NOFS); | ||
1406 | if (rc) { | ||
1407 | char *dev = inode->i_sb->s_id; | ||
1408 | unsigned long ino = inode->i_ino; | ||
1409 | |||
1410 | if (rc == -EINVAL) { | ||
1411 | pr_notice_ratelimited("SELinux: inode=%lu on dev=%s was found to have an invalid context=%s. This indicates you may need to relabel the inode or the filesystem in question.\n", | ||
1412 | ino, dev, context); | ||
1413 | } else { | ||
1414 | pr_warn("SELinux: %s: context_to_sid(%s) returned %d for dev=%s ino=%ld\n", | ||
1415 | __func__, context, -rc, dev, ino); | ||
1416 | } | ||
1417 | } | ||
1418 | kfree(context); | ||
1419 | return 0; | ||
1420 | } | ||
1421 | |||
1357 | /* The inode's security attributes must be initialized before first use. */ | 1422 | /* The inode's security attributes must be initialized before first use. */ |
1358 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) | 1423 | static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dentry) |
1359 | { | 1424 | { |
@@ -1362,9 +1427,6 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1362 | u32 task_sid, sid = 0; | 1427 | u32 task_sid, sid = 0; |
1363 | u16 sclass; | 1428 | u16 sclass; |
1364 | struct dentry *dentry; | 1429 | struct dentry *dentry; |
1365 | #define INITCONTEXTLEN 255 | ||
1366 | char *context = NULL; | ||
1367 | unsigned len = 0; | ||
1368 | int rc = 0; | 1430 | int rc = 0; |
1369 | 1431 | ||
1370 | if (isec->initialized == LABEL_INITIALIZED) | 1432 | if (isec->initialized == LABEL_INITIALIZED) |
@@ -1432,72 +1494,11 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1432 | goto out; | 1494 | goto out; |
1433 | } | 1495 | } |
1434 | 1496 | ||
1435 | len = INITCONTEXTLEN; | 1497 | rc = inode_doinit_use_xattr(inode, dentry, sbsec->def_sid, |
1436 | context = kmalloc(len+1, GFP_NOFS); | 1498 | &sid); |
1437 | if (!context) { | ||
1438 | rc = -ENOMEM; | ||
1439 | dput(dentry); | ||
1440 | goto out; | ||
1441 | } | ||
1442 | context[len] = '\0'; | ||
1443 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); | ||
1444 | if (rc == -ERANGE) { | ||
1445 | kfree(context); | ||
1446 | |||
1447 | /* Need a larger buffer. Query for the right size. */ | ||
1448 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, NULL, 0); | ||
1449 | if (rc < 0) { | ||
1450 | dput(dentry); | ||
1451 | goto out; | ||
1452 | } | ||
1453 | len = rc; | ||
1454 | context = kmalloc(len+1, GFP_NOFS); | ||
1455 | if (!context) { | ||
1456 | rc = -ENOMEM; | ||
1457 | dput(dentry); | ||
1458 | goto out; | ||
1459 | } | ||
1460 | context[len] = '\0'; | ||
1461 | rc = __vfs_getxattr(dentry, inode, XATTR_NAME_SELINUX, context, len); | ||
1462 | } | ||
1463 | dput(dentry); | 1499 | dput(dentry); |
1464 | if (rc < 0) { | 1500 | if (rc) |
1465 | if (rc != -ENODATA) { | 1501 | goto out; |
1466 | pr_warn("SELinux: %s: getxattr returned " | ||
1467 | "%d for dev=%s ino=%ld\n", __func__, | ||
1468 | -rc, inode->i_sb->s_id, inode->i_ino); | ||
1469 | kfree(context); | ||
1470 | goto out; | ||
1471 | } | ||
1472 | /* Map ENODATA to the default file SID */ | ||
1473 | sid = sbsec->def_sid; | ||
1474 | rc = 0; | ||
1475 | } else { | ||
1476 | rc = security_context_to_sid_default(&selinux_state, | ||
1477 | context, rc, &sid, | ||
1478 | sbsec->def_sid, | ||
1479 | GFP_NOFS); | ||
1480 | if (rc) { | ||
1481 | char *dev = inode->i_sb->s_id; | ||
1482 | unsigned long ino = inode->i_ino; | ||
1483 | |||
1484 | if (rc == -EINVAL) { | ||
1485 | if (printk_ratelimit()) | ||
1486 | pr_notice("SELinux: inode=%lu on dev=%s was found to have an invalid " | ||
1487 | "context=%s. This indicates you may need to relabel the inode or the " | ||
1488 | "filesystem in question.\n", ino, dev, context); | ||
1489 | } else { | ||
1490 | pr_warn("SELinux: %s: context_to_sid(%s) " | ||
1491 | "returned %d for dev=%s ino=%ld\n", | ||
1492 | __func__, context, -rc, dev, ino); | ||
1493 | } | ||
1494 | kfree(context); | ||
1495 | /* Leave with the unlabeled SID */ | ||
1496 | rc = 0; | ||
1497 | break; | ||
1498 | } | ||
1499 | } | ||
1500 | kfree(context); | ||
1501 | break; | 1502 | break; |
1502 | case SECURITY_FS_USE_TASK: | 1503 | case SECURITY_FS_USE_TASK: |
1503 | sid = task_sid; | 1504 | sid = task_sid; |
@@ -1548,9 +1549,21 @@ static int inode_doinit_with_dentry(struct inode *inode, struct dentry *opt_dent | |||
1548 | goto out; | 1549 | goto out; |
1549 | rc = selinux_genfs_get_sid(dentry, sclass, | 1550 | rc = selinux_genfs_get_sid(dentry, sclass, |
1550 | sbsec->flags, &sid); | 1551 | sbsec->flags, &sid); |
1551 | dput(dentry); | 1552 | if (rc) { |
1552 | if (rc) | 1553 | dput(dentry); |
1553 | goto out; | 1554 | goto out; |
1555 | } | ||
1556 | |||
1557 | if ((sbsec->flags & SE_SBGENFS_XATTR) && | ||
1558 | (inode->i_opflags & IOP_XATTR)) { | ||
1559 | rc = inode_doinit_use_xattr(inode, dentry, | ||
1560 | sid, &sid); | ||
1561 | if (rc) { | ||
1562 | dput(dentry); | ||
1563 | goto out; | ||
1564 | } | ||
1565 | } | ||
1566 | dput(dentry); | ||
1554 | } | 1567 | } |
1555 | break; | 1568 | break; |
1556 | } | 1569 | } |
@@ -3371,6 +3384,67 @@ static int selinux_inode_copy_up_xattr(const char *name) | |||
3371 | return -EOPNOTSUPP; | 3384 | return -EOPNOTSUPP; |
3372 | } | 3385 | } |
3373 | 3386 | ||
3387 | /* kernfs node operations */ | ||
3388 | |||
3389 | static int selinux_kernfs_init_security(struct kernfs_node *kn_dir, | ||
3390 | struct kernfs_node *kn) | ||
3391 | { | ||
3392 | const struct task_security_struct *tsec = current_security(); | ||
3393 | u32 parent_sid, newsid, clen; | ||
3394 | int rc; | ||
3395 | char *context; | ||
3396 | |||
3397 | rc = kernfs_xattr_get(kn_dir, XATTR_NAME_SELINUX, NULL, 0); | ||
3398 | if (rc == -ENODATA) | ||
3399 | return 0; | ||
3400 | else if (rc < 0) | ||
3401 | return rc; | ||
3402 | |||
3403 | clen = (u32)rc; | ||
3404 | context = kmalloc(clen, GFP_KERNEL); | ||
3405 | if (!context) | ||
3406 | return -ENOMEM; | ||
3407 | |||
3408 | rc = kernfs_xattr_get(kn_dir, XATTR_NAME_SELINUX, context, clen); | ||
3409 | if (rc < 0) { | ||
3410 | kfree(context); | ||
3411 | return rc; | ||
3412 | } | ||
3413 | |||
3414 | rc = security_context_to_sid(&selinux_state, context, clen, &parent_sid, | ||
3415 | GFP_KERNEL); | ||
3416 | kfree(context); | ||
3417 | if (rc) | ||
3418 | return rc; | ||
3419 | |||
3420 | if (tsec->create_sid) { | ||
3421 | newsid = tsec->create_sid; | ||
3422 | } else { | ||
3423 | u16 secclass = inode_mode_to_security_class(kn->mode); | ||
3424 | struct qstr q; | ||
3425 | |||
3426 | q.name = kn->name; | ||
3427 | q.hash_len = hashlen_string(kn_dir, kn->name); | ||
3428 | |||
3429 | rc = security_transition_sid(&selinux_state, tsec->sid, | ||
3430 | parent_sid, secclass, &q, | ||
3431 | &newsid); | ||
3432 | if (rc) | ||
3433 | return rc; | ||
3434 | } | ||
3435 | |||
3436 | rc = security_sid_to_context_force(&selinux_state, newsid, | ||
3437 | &context, &clen); | ||
3438 | if (rc) | ||
3439 | return rc; | ||
3440 | |||
3441 | rc = kernfs_xattr_set(kn, XATTR_NAME_SELINUX, context, clen, | ||
3442 | XATTR_CREATE); | ||
3443 | kfree(context); | ||
3444 | return rc; | ||
3445 | } | ||
3446 | |||
3447 | |||
3374 | /* file security operations */ | 3448 | /* file security operations */ |
3375 | 3449 | ||
3376 | static int selinux_revalidate_file_permission(struct file *file, int mask) | 3450 | static int selinux_revalidate_file_permission(struct file *file, int mask) |
@@ -4438,7 +4512,7 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4438 | struct lsm_network_audit net = {0,}; | 4512 | struct lsm_network_audit net = {0,}; |
4439 | struct sockaddr_in *addr4 = NULL; | 4513 | struct sockaddr_in *addr4 = NULL; |
4440 | struct sockaddr_in6 *addr6 = NULL; | 4514 | struct sockaddr_in6 *addr6 = NULL; |
4441 | u16 family_sa = address->sa_family; | 4515 | u16 family_sa; |
4442 | unsigned short snum; | 4516 | unsigned short snum; |
4443 | u32 sid, node_perm; | 4517 | u32 sid, node_perm; |
4444 | 4518 | ||
@@ -4448,6 +4522,9 @@ static int selinux_socket_bind(struct socket *sock, struct sockaddr *address, in | |||
4448 | * need to check address->sa_family as it is possible to have | 4522 | * need to check address->sa_family as it is possible to have |
4449 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4523 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
4450 | */ | 4524 | */ |
4525 | if (addrlen < offsetofend(struct sockaddr, sa_family)) | ||
4526 | return -EINVAL; | ||
4527 | family_sa = address->sa_family; | ||
4451 | switch (family_sa) { | 4528 | switch (family_sa) { |
4452 | case AF_UNSPEC: | 4529 | case AF_UNSPEC: |
4453 | case AF_INET: | 4530 | case AF_INET: |
@@ -4580,6 +4657,8 @@ static int selinux_socket_connect_helper(struct socket *sock, | |||
4580 | * need to check address->sa_family as it is possible to have | 4657 | * need to check address->sa_family as it is possible to have |
4581 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. | 4658 | * sk->sk_family = PF_INET6 with addr->sa_family = AF_INET. |
4582 | */ | 4659 | */ |
4660 | if (addrlen < offsetofend(struct sockaddr, sa_family)) | ||
4661 | return -EINVAL; | ||
4583 | switch (address->sa_family) { | 4662 | switch (address->sa_family) { |
4584 | case AF_INET: | 4663 | case AF_INET: |
4585 | addr4 = (struct sockaddr_in *)address; | 4664 | addr4 = (struct sockaddr_in *)address; |
@@ -6719,6 +6798,8 @@ static struct security_hook_list selinux_hooks[] __lsm_ro_after_init = { | |||
6719 | LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up), | 6798 | LSM_HOOK_INIT(inode_copy_up, selinux_inode_copy_up), |
6720 | LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr), | 6799 | LSM_HOOK_INIT(inode_copy_up_xattr, selinux_inode_copy_up_xattr), |
6721 | 6800 | ||
6801 | LSM_HOOK_INIT(kernfs_init_security, selinux_kernfs_init_security), | ||
6802 | |||
6722 | LSM_HOOK_INIT(file_permission, selinux_file_permission), | 6803 | LSM_HOOK_INIT(file_permission, selinux_file_permission), |
6723 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), | 6804 | LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security), |
6724 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), | 6805 | LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl), |
diff --git a/security/selinux/include/security.h b/security/selinux/include/security.h index b5b7c5aade8c..111121281c47 100644 --- a/security/selinux/include/security.h +++ b/security/selinux/include/security.h | |||
@@ -58,6 +58,7 @@ | |||
58 | #define SE_SBINITIALIZED 0x0100 | 58 | #define SE_SBINITIALIZED 0x0100 |
59 | #define SE_SBPROC 0x0200 | 59 | #define SE_SBPROC 0x0200 |
60 | #define SE_SBGENFS 0x0400 | 60 | #define SE_SBGENFS 0x0400 |
61 | #define SE_SBGENFS_XATTR 0x0800 | ||
61 | 62 | ||
62 | #define CONTEXT_STR "context" | 63 | #define CONTEXT_STR "context" |
63 | #define FSCONTEXT_STR "fscontext" | 64 | #define FSCONTEXT_STR "fscontext" |
diff --git a/security/selinux/netlabel.c b/security/selinux/netlabel.c index 186e727b737b..6fd9954e1c08 100644 --- a/security/selinux/netlabel.c +++ b/security/selinux/netlabel.c | |||
@@ -288,11 +288,8 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, | |||
288 | int rc; | 288 | int rc; |
289 | struct netlbl_lsm_secattr secattr; | 289 | struct netlbl_lsm_secattr secattr; |
290 | struct sk_security_struct *sksec = ep->base.sk->sk_security; | 290 | struct sk_security_struct *sksec = ep->base.sk->sk_security; |
291 | struct sockaddr *addr; | ||
292 | struct sockaddr_in addr4; | 291 | struct sockaddr_in addr4; |
293 | #if IS_ENABLED(CONFIG_IPV6) | ||
294 | struct sockaddr_in6 addr6; | 292 | struct sockaddr_in6 addr6; |
295 | #endif | ||
296 | 293 | ||
297 | if (ep->base.sk->sk_family != PF_INET && | 294 | if (ep->base.sk->sk_family != PF_INET && |
298 | ep->base.sk->sk_family != PF_INET6) | 295 | ep->base.sk->sk_family != PF_INET6) |
@@ -310,16 +307,15 @@ int selinux_netlbl_sctp_assoc_request(struct sctp_endpoint *ep, | |||
310 | if (ip_hdr(skb)->version == 4) { | 307 | if (ip_hdr(skb)->version == 4) { |
311 | addr4.sin_family = AF_INET; | 308 | addr4.sin_family = AF_INET; |
312 | addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; | 309 | addr4.sin_addr.s_addr = ip_hdr(skb)->saddr; |
313 | addr = (struct sockaddr *)&addr4; | 310 | rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr4, &secattr); |
314 | #if IS_ENABLED(CONFIG_IPV6) | 311 | } else if (IS_ENABLED(CONFIG_IPV6) && ip_hdr(skb)->version == 6) { |
315 | } else { | ||
316 | addr6.sin6_family = AF_INET6; | 312 | addr6.sin6_family = AF_INET6; |
317 | addr6.sin6_addr = ipv6_hdr(skb)->saddr; | 313 | addr6.sin6_addr = ipv6_hdr(skb)->saddr; |
318 | addr = (struct sockaddr *)&addr6; | 314 | rc = netlbl_conn_setattr(ep->base.sk, (void *)&addr6, &secattr); |
319 | #endif | 315 | } else { |
316 | rc = -EAFNOSUPPORT; | ||
320 | } | 317 | } |
321 | 318 | ||
322 | rc = netlbl_conn_setattr(ep->base.sk, addr, &secattr); | ||
323 | if (rc == 0) | 319 | if (rc == 0) |
324 | sksec->nlbl_state = NLBL_LABELED; | 320 | sksec->nlbl_state = NLBL_LABELED; |
325 | 321 | ||
diff --git a/security/selinux/ss/services.c b/security/selinux/ss/services.c index ec62918521b1..cc043bc8fd4c 100644 --- a/security/selinux/ss/services.c +++ b/security/selinux/ss/services.c | |||
@@ -1318,14 +1318,11 @@ static int security_sid_to_context_core(struct selinux_state *state, | |||
1318 | rc = -EINVAL; | 1318 | rc = -EINVAL; |
1319 | goto out_unlock; | 1319 | goto out_unlock; |
1320 | } | 1320 | } |
1321 | if (only_invalid && !context->len) { | 1321 | if (only_invalid && !context->len) |
1322 | scontext = NULL; | ||
1323 | scontext_len = 0; | ||
1324 | rc = 0; | 1322 | rc = 0; |
1325 | } else { | 1323 | else |
1326 | rc = context_struct_to_string(policydb, context, scontext, | 1324 | rc = context_struct_to_string(policydb, context, scontext, |
1327 | scontext_len); | 1325 | scontext_len); |
1328 | } | ||
1329 | out_unlock: | 1326 | out_unlock: |
1330 | read_unlock(&state->ss->policy_rwlock); | 1327 | read_unlock(&state->ss->policy_rwlock); |
1331 | out: | 1328 | out: |