2
* Userspace side of netlink communications with eCryptfs kernel
5
* Copyright (C) 2004-2007 International Business Machines Corp.
6
* Author(s): Michael A. Halcrow <mhalcrow@us.ibm.com>
7
* Tyler Hicks <tyhicks@ou.edu>
9
* This program is free software; you can redistribute it and/or
10
* modify it under the terms of the GNU General Public License as
11
* published by the Free Software Foundation; either version 2 of the
12
* License, or (at your option) any later version.
14
* This program is distributed in the hope that it will be useful, but
15
* WITHOUT ANY WARRANTY; without even the implied warranty of
16
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
* General Public License for more details.
19
* You should have received a copy of the GNU General Public License
20
* along with this program; if not, write to the Free Software
21
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
34
#include <sys/socket.h>
36
#include "../include/ecryptfs.h"
38
int ecryptfs_send_netlink(int sk_fd, struct ecryptfs_netlink_message *emsg,
39
uint16_t msg_type, uint16_t msg_flags,
42
struct nlmsghdr *nlh = NULL;
43
struct sockaddr_nl dst_addr;
47
payload_len = emsg ? sizeof(*emsg) + emsg->data_len : 0;
48
nlh = malloc(NLMSG_SPACE(payload_len));
50
ecryptfs_syslog(LOG_ERR, "Failed to allocate memory for "
51
"netlink header: %s\n", strerror(errno));
55
memset(&dst_addr, 0, sizeof(dst_addr));
56
dst_addr.nl_family = AF_NETLINK;
58
dst_addr.nl_groups = 0;
59
nlh->nlmsg_len = NLMSG_LENGTH(payload_len);
60
nlh->nlmsg_seq = msg_seq;
62
nlh->nlmsg_type = msg_type;
63
nlh->nlmsg_flags = msg_flags;
65
memcpy(NLMSG_DATA(nlh), emsg, payload_len);
66
rc = sendto(sk_fd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&dst_addr,
70
syslog(LOG_ERR, "Failed to send eCryptfs netlink "
71
"message: %s\n", strerror(errno));
79
int ecryptfs_recv_netlink(int sk_fd, struct ecryptfs_netlink_message **emsg,
80
int *msg_seq, int *msg_type)
82
struct nlmsghdr *nlh = NULL;
83
struct sockaddr_nl nladdr;
84
socklen_t nladdr_len = sizeof(nladdr);
86
int buf_len = sizeof(*nlh);
91
nlh = (struct nlmsghdr *)realloc(nlh, buf_len);
94
syslog(LOG_ERR, "Failed to allocate memory for "
95
"netlink message: %s\n", strerror(errno));
98
rc = recvfrom(sk_fd, nlh, buf_len, flags, (struct sockaddr*)&nladdr,
102
syslog(LOG_ERR, "Failed to receive netlink header; errno = "
103
"[%d]; errno msg = [%s]\n", errno, strerror(errno));
106
if (flags & MSG_PEEK) {
107
buf_len = nlh->nlmsg_len;
111
if (nladdr_len != sizeof(nladdr)) {
113
syslog(LOG_ERR, "Received invalid netlink message\n");
118
syslog(LOG_WARNING, "Received netlink packet from a "
119
"userspace application; pid [%d] may be trying "
120
"to spoof eCryptfs netlink packets\n",
124
pl_len = NLMSG_PAYLOAD(nlh, 0);
126
*emsg = malloc(pl_len);
129
syslog(LOG_ERR, "Failed to allocate memory "
130
"for eCryptfs netlink message: %s\n",
134
memcpy(*emsg, NLMSG_DATA(nlh), pl_len);
136
*msg_seq = nlh->nlmsg_seq;
137
*msg_type = nlh->nlmsg_type;
144
int ecryptfs_init_netlink(int *sk_fd)
146
struct sockaddr_nl src_addr;
149
(*sk_fd) = socket(PF_NETLINK, SOCK_RAW, NETLINK_ECRYPTFS);
152
syslog(LOG_ERR, "Failed to create the eCryptfs "
153
"netlink socket: %s\n", strerror(errno));
156
memset(&src_addr, 0, sizeof(src_addr));
157
src_addr.nl_family = AF_NETLINK;
158
src_addr.nl_pid = getpid();
159
src_addr.nl_groups = 0;
160
rc = bind(*sk_fd, (struct sockaddr *)&src_addr, sizeof(src_addr));
163
syslog(LOG_ERR, "Failed to bind the eCryptfs netlink "
164
"socket: %s\n", strerror(errno));
167
syslog(LOG_DEBUG, "eCryptfs netlink socket was successfully "
173
void ecryptfs_release_netlink(int sk_fd)
176
syslog(LOG_DEBUG, "eCryptfs netlink socket was successfully "
180
int init_netlink_daemon(void)
185
syslog(LOG_INFO, "Starting eCryptfs userspace netlink daemon "
192
int ecryptfs_run_netlink_daemon(int sk_fd)
194
struct ecryptfs_netlink_message *emsg = NULL;
195
struct ecryptfs_ctx ctx;
196
int msg_seq, msg_type;
200
memset(&ctx, 0, sizeof(struct ecryptfs_ctx));
202
if ((rc = ecryptfs_register_key_modules(&ctx))) {
203
syslog(LOG_ERR, "Failed to register key modules; rc = [%d]\n",
208
rc = ecryptfs_recv_netlink(sk_fd, &emsg, &msg_seq, &msg_type);
210
syslog(LOG_ERR, "Error while receiving eCryptfs netlink "
211
"message; errno = [%d]; errno msg = [%s]\n", errno,
214
if (error_count > ECRYPTFS_NETLINK_ERROR_COUNT_THRESHOLD) {
215
syslog(LOG_ERR, "Netlink error threshold exceeded "
216
"maximum of [%d]; terminating daemon\n",
217
ECRYPTFS_NETLINK_ERROR_COUNT_THRESHOLD);
221
} else if (msg_type == ECRYPTFS_NLMSG_HELO) {
222
syslog(LOG_DEBUG, "Received eCryptfs netlink HELO "
223
"message from the kernel\n");
225
} else if (msg_type == ECRYPTFS_NLMSG_QUIT) {
226
syslog(LOG_DEBUG, "Received eCryptfs netlink QUIT "
227
"message from the kernel\n");
231
} else if (msg_type == ECRYPTFS_NLMSG_REQUEST) {
232
struct ecryptfs_netlink_message *reply = NULL;
234
rc = parse_packet(&ctx, emsg, &reply);
236
syslog(LOG_ERR, "Failed to process "
241
reply->index = emsg->index;
242
rc = ecryptfs_send_netlink(sk_fd, reply,
243
ECRYPTFS_NLMSG_RESPONSE, 0,
246
syslog(LOG_ERR, "Failed to send netlink "
247
"message in response to kernel "
253
syslog(LOG_DEBUG, "Received unrecognized netlink "
254
"message type [%d]\n", msg_type);
259
ecryptfs_free_key_mod_list(&ctx);