History

tun: fix LSM/SELinux labeling of tun/tap devices

This patch corrects some problems with LSM/SELinux that were introduced with the multiqueue patchset. The problem stems from the fact that the multiqueue work changed the relationship between the tun device and its associated socket; before the socket persisted for the life of the device, however after the multiqueue changes the socket only persisted for the life of the userspace connection (fd open). For non-persistent devices this is not an issue, but for persistent devices this can cause the tun device to lose its SELinux label. We correct this problem by adding an opaque LSM security blob to the tun device struct which allows us to have the LSM security state, e.g. SELinux labeling information, persist for the lifetime of the tun device. In the process we tweak the LSM hooks to work with this new approach to TUN device/socket labeling and introduce a new LSM hook, security_tun_dev_attach_queue(), to approve requests to attach to a TUN queue via TUNSETQUEUE. The SELinux code has been adjusted to match the new LSM hooks, the other LSMs do not make use of the LSM TUN controls. This patch makes use of the recently added "tun_socket:attach_queue" permission to restrict access to the TUNSETQUEUE operation. On older SELinux policies which do not define the "tun_socket:attach_queue" permission the access control decision for TUNSETQUEUE will be handled according to the SELinux policy's unknown permission setting.

Paul Moore committed 13 years ago

Commit 5dbbaf21 parent 6f96c146 files · +151 −37Browse files

Showing the changes to include/linux (1 of 6 files). Show all

Unified · Split

include/linux/security.h+46−13
@@ -989,17 +989,29 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) · 988 unmodified lines
989989 * tells the LSM to decrement the number of secmark labeling rules loaded
990990 * @req_classify_flow:
991991 * Sets the flow's sid to the openreq sid.
992+ * @tun_dev_alloc_security:
993+ * This hook allows a module to allocate a security structure for a TUN
994+ * device.
995+ * @security pointer to a security structure pointer.
996+ * Returns a zero on success, negative values on failure.
997+ * @tun_dev_free_security:
998+ * This hook allows a module to free the security structure for a TUN
999+ * device.
1000+ * @security pointer to the TUN device's security structure
9921001 * @tun_dev_create:
9931002 * Check permissions prior to creating a new TUN device.
994− * @tun_dev_post_create:
995− * This hook allows a module to update or allocate a per-socket security
996− * structure.
997− * @sk contains the newly created sock structure.
1003+ * @tun_dev_attach_queue:
1004+ * Check permissions prior to attaching to a TUN device queue.
1005+ * @security pointer to the TUN device's security structure.
9981006 * @tun_dev_attach:
999− * Check permissions prior to attaching to a persistent TUN device. This
1000− * hook can also be used by the module to update any security state
1007+ * This hook can be used by the module to update any security state
10011008 * associated with the TUN device's sock structure.
10021009 * @sk contains the existing sock structure.
1010+ * @security pointer to the TUN device's security structure.
1011+ * @tun_dev_open:
1012+ * This hook can be used by the module to update any security state
1013+ * associated with the TUN device's security structure.
1014+ * @security pointer to the TUN devices's security structure.
10031015 *
10041016 * Security hooks for XFRM operations.
10051017 *
@@ -1620,9 +1632,12 @@ struct security_operations { · 614 unmodified lines
16201632 void (*secmark_refcount_inc) (void);
16211633 void (*secmark_refcount_dec) (void);
16221634 void (*req_classify_flow) (const struct request_sock *req, struct flowi *fl);
1623− int (*tun_dev_create)(void);
1624− void (*tun_dev_post_create)(struct sock *sk);
1625− int (*tun_dev_attach)(struct sock *sk);
1635+ int (*tun_dev_alloc_security) (void **security);
1636+ void (*tun_dev_free_security) (void *security);
1637+ int (*tun_dev_create) (void);
1638+ int (*tun_dev_attach_queue) (void *security);
1639+ int (*tun_dev_attach) (struct sock *sk, void *security);
1640+ int (*tun_dev_open) (void *security);
16261641 #endif /* CONFIG_SECURITY_NETWORK */
16271642
16281643 #ifdef CONFIG_SECURITY_NETWORK_XFRM
@@ -2566,9 +2581,12 @@ void security_inet_conn_established(struct sock *sk, · 937 unmodified lines
25662581 int security_secmark_relabel_packet(u32 secid);
25672582 void security_secmark_refcount_inc(void);
25682583 void security_secmark_refcount_dec(void);
2584+int security_tun_dev_alloc_security(void **security);
2585+void security_tun_dev_free_security(void *security);
25692586 int security_tun_dev_create(void);
2570−void security_tun_dev_post_create(struct sock *sk);
2571−int security_tun_dev_attach(struct sock *sk);
2587+int security_tun_dev_attach_queue(void *security);
2588+int security_tun_dev_attach(struct sock *sk, void *security);
2589+int security_tun_dev_open(void *security);
25722590
25732591 #else /* CONFIG_SECURITY_NETWORK */
25742592 static inline int security_unix_stream_connect(struct sock *sock,
@@ -2733,16 +2751,31 @@ static inline void security_secmark_refcount_dec(void) · 158 unmodified lines
27332751 {
27342752 }
27352753
2754+static inline int security_tun_dev_alloc_security(void **security)
2755+{
2756+ return 0;
2757+}
2758+
2759+static inline void security_tun_dev_free_security(void *security)
2760+{
2761+}
2762+
27362763 static inline int security_tun_dev_create(void)
27372764 {
27382765 return 0;
27392766 }
27402767
2741−static inline void security_tun_dev_post_create(struct sock *sk)
2768+static inline int security_tun_dev_attach_queue(void *security)
2769+{
2770+ return 0;
2771+}
2772+
2773+static inline int security_tun_dev_attach(struct sock *sk, void *security)
27422774 {
2775+ return 0;
27432776 }
27442777
2745−static inline int security_tun_dev_attach(struct sock *sk)
2778+static inline int security_tun_dev_open(void *security)
27462779 {
27472780 return 0;
27482781 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t