File openssl-ocloexec.patch of Package openssl.openSUSE_Evergreen_11.4
diff -rNU 30 ../openssl-1.0.1n-o/crypto/bio/b_sock.c ./crypto/bio/b_sock.c
--- ../openssl-1.0.1n-o/crypto/bio/b_sock.c 2015-06-11 16:01:49.000000000 +0200
+++ ./crypto/bio/b_sock.c 2015-06-12 03:39:13.000000000 +0200
@@ -692,103 +692,103 @@
addrlen = res->ai_addrlen <= sizeof(server) ?
res->ai_addrlen : sizeof(server);
memcpy(&server, res->ai_addr, addrlen);
(*p_freeaddrinfo.f) (res);
goto again;
} while (0);
# endif
if (!BIO_get_port(p, &port))
goto err;
memset((char *)&server, 0, sizeof(server));
server.sa_in.sin_family = AF_INET;
server.sa_in.sin_port = htons(port);
addrlen = sizeof(server.sa_in);
if (h == NULL || strcmp(h, "*") == 0)
server.sa_in.sin_addr.s_addr = INADDR_ANY;
else {
if (!BIO_get_host_ip(h, &(ip[0])))
goto err;
l = (unsigned long)
((unsigned long)ip[0] << 24L) |
((unsigned long)ip[1] << 16L) |
((unsigned long)ip[2] << 8L) | ((unsigned long)ip[3]);
server.sa_in.sin_addr.s_addr = htonl(l);
}
again:
- s = socket(server.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
+ s = socket(server.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC, SOCKET_PROTOCOL);
if (s == INVALID_SOCKET) {
SYSerr(SYS_F_SOCKET, get_last_socket_error());
ERR_add_error_data(3, "port='", host, "'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_CREATE_SOCKET);
goto err;
}
# ifdef SO_REUSEADDR
if (bind_mode == BIO_BIND_REUSEADDR) {
int i = 1;
ret = setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char *)&i, sizeof(i));
bind_mode = BIO_BIND_NORMAL;
}
# endif
if (bind(s, &server.sa, addrlen) == -1) {
# ifdef SO_REUSEADDR
err_num = get_last_socket_error();
if ((bind_mode == BIO_BIND_REUSEADDR_IF_UNUSED) &&
# ifdef OPENSSL_SYS_WINDOWS
/*
* Some versions of Windows define EADDRINUSE to a dummy value.
*/
(err_num == WSAEADDRINUSE))
# else
(err_num == EADDRINUSE))
# endif
{
client = server;
if (h == NULL || strcmp(h, "*") == 0) {
# if OPENSSL_USE_IPV6
if (client.sa.sa_family == AF_INET6) {
memset(&client.sa_in6.sin6_addr, 0,
sizeof(client.sa_in6.sin6_addr));
client.sa_in6.sin6_addr.s6_addr[15] = 1;
} else
# endif
if (client.sa.sa_family == AF_INET) {
client.sa_in.sin_addr.s_addr = htonl(0x7F000001);
} else
goto err;
}
- cs = socket(client.sa.sa_family, SOCK_STREAM, SOCKET_PROTOCOL);
+ cs = socket(client.sa.sa_family, SOCK_STREAM|SOCK_CLOEXEC, SOCKET_PROTOCOL);
if (cs != INVALID_SOCKET) {
int ii;
ii = connect(cs, &client.sa, addrlen);
closesocket(cs);
if (ii == INVALID_SOCKET) {
bind_mode = BIO_BIND_REUSEADDR;
closesocket(s);
goto again;
}
/* else error */
}
/* else error */
}
# endif
SYSerr(SYS_F_BIND, err_num);
ERR_add_error_data(3, "port='", host, "'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_BIND_SOCKET);
goto err;
}
if (listen(s, MAX_LISTEN) == -1) {
SYSerr(SYS_F_BIND, get_last_socket_error());
ERR_add_error_data(3, "port='", host, "'");
BIOerr(BIO_F_BIO_GET_ACCEPT_SOCKET, BIO_R_UNABLE_TO_LISTEN_SOCKET);
goto err;
}
ret = 1;
err:
if (str != NULL)
OPENSSL_free(str);
if ((ret == 0) && (s != INVALID_SOCKET)) {
diff -rNU 30 ../openssl-1.0.1n-o/crypto/bio/bss_conn.c ./crypto/bio/bss_conn.c
--- ../openssl-1.0.1n-o/crypto/bio/bss_conn.c 2015-06-11 16:01:49.000000000 +0200
+++ ./crypto/bio/bss_conn.c 2015-06-12 03:39:55.000000000 +0200
@@ -168,61 +168,61 @@
c->state = BIO_CONN_S_GET_IP;
break;
case BIO_CONN_S_GET_IP:
if (BIO_get_host_ip(c->param_hostname, &(c->ip[0])) <= 0)
goto exit_loop;
c->state = BIO_CONN_S_GET_PORT;
break;
case BIO_CONN_S_GET_PORT:
if (c->param_port == NULL) {
/* abort(); */
goto exit_loop;
} else if (BIO_get_port(c->param_port, &c->port) <= 0)
goto exit_loop;
c->state = BIO_CONN_S_CREATE_SOCKET;
break;
case BIO_CONN_S_CREATE_SOCKET:
/* now setup address */
memset((char *)&c->them, 0, sizeof(c->them));
c->them.sin_family = AF_INET;
c->them.sin_port = htons((unsigned short)c->port);
l = (unsigned long)
((unsigned long)c->ip[0] << 24L) |
((unsigned long)c->ip[1] << 16L) |
((unsigned long)c->ip[2] << 8L) | ((unsigned long)c->ip[3]);
c->them.sin_addr.s_addr = htonl(l);
c->state = BIO_CONN_S_CREATE_SOCKET;
- ret = socket(AF_INET, SOCK_STREAM, SOCKET_PROTOCOL);
+ ret = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC, SOCKET_PROTOCOL);
if (ret == INVALID_SOCKET) {
SYSerr(SYS_F_SOCKET, get_last_socket_error());
ERR_add_error_data(4, "host=", c->param_hostname,
":", c->param_port);
BIOerr(BIO_F_CONN_STATE, BIO_R_UNABLE_TO_CREATE_SOCKET);
goto exit_loop;
}
b->num = ret;
c->state = BIO_CONN_S_NBIO;
break;
case BIO_CONN_S_NBIO:
if (c->nbio) {
if (!BIO_socket_nbio(b->num, 1)) {
BIOerr(BIO_F_CONN_STATE, BIO_R_ERROR_SETTING_NBIO);
ERR_add_error_data(4, "host=",
c->param_hostname, ":", c->param_port);
goto exit_loop;
}
}
c->state = BIO_CONN_S_CONNECT;
# if defined(SO_KEEPALIVE) && !defined(OPENSSL_SYS_MPE)
i = 1;
i = setsockopt(b->num, SOL_SOCKET, SO_KEEPALIVE, (char *)&i,
sizeof(i));
if (i < 0) {
SYSerr(SYS_F_SOCKET, get_last_socket_error());
ERR_add_error_data(4, "host=", c->param_hostname,
":", c->param_port);
diff -rNU 30 ../openssl-1.0.1n-o/crypto/bio/bss_dgram.c ./crypto/bio/bss_dgram.c
--- ../openssl-1.0.1n-o/crypto/bio/bss_dgram.c 2015-06-11 16:01:49.000000000 +0200
+++ ./crypto/bio/bss_dgram.c 2015-06-12 03:45:25.000000000 +0200
@@ -1091,61 +1091,61 @@
}
}
# endif
static int dgram_sctp_read(BIO *b, char *out, int outl)
{
int ret = 0, n = 0, i, optval;
socklen_t optlen;
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
union sctp_notification *snp;
struct msghdr msg;
struct iovec iov;
struct cmsghdr *cmsg;
char cmsgbuf[512];
if (out != NULL) {
clear_socket_error();
do {
memset(&data->rcvinfo, 0x00,
sizeof(struct bio_dgram_sctp_rcvinfo));
iov.iov_base = out;
iov.iov_len = outl;
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = cmsgbuf;
msg.msg_controllen = 512;
msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, 0);
+ n = recvmsg(b->num, &msg, MSG_CMSG_CLOEXEC);
if (n <= 0) {
if (n < 0)
ret = n;
break;
}
if (msg.msg_controllen > 0) {
for (cmsg = CMSG_FIRSTHDR(&msg); cmsg;
cmsg = CMSG_NXTHDR(&msg, cmsg)) {
if (cmsg->cmsg_level != IPPROTO_SCTP)
continue;
# ifdef SCTP_RCVINFO
if (cmsg->cmsg_type == SCTP_RCVINFO) {
struct sctp_rcvinfo *rcvinfo;
rcvinfo = (struct sctp_rcvinfo *)CMSG_DATA(cmsg);
data->rcvinfo.rcv_sid = rcvinfo->rcv_sid;
data->rcvinfo.rcv_ssn = rcvinfo->rcv_ssn;
data->rcvinfo.rcv_flags = rcvinfo->rcv_flags;
data->rcvinfo.rcv_ppid = rcvinfo->rcv_ppid;
data->rcvinfo.rcv_tsn = rcvinfo->rcv_tsn;
data->rcvinfo.rcv_cumtsn = rcvinfo->rcv_cumtsn;
data->rcvinfo.rcv_context = rcvinfo->rcv_context;
}
# endif
# ifdef SCTP_SNDRCV
if (cmsg->cmsg_type == SCTP_SNDRCV) {
struct sctp_sndrcvinfo *sndrcvinfo;
@@ -1716,83 +1716,83 @@
ret =
setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
sizeof(struct sctp_event));
# else
eventsize = sizeof(struct sctp_event_subscribe);
ret = getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event, &eventsize);
if (ret < 0)
return -1;
event.sctp_sender_dry_event = 1;
ret =
setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
sizeof(struct sctp_event_subscribe));
# endif
if (ret < 0)
return -1;
/* peek for notification */
memset(&snp, 0x00, sizeof(union sctp_notification));
iov.iov_base = (char *)&snp;
iov.iov_len = sizeof(union sctp_notification);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, MSG_PEEK);
+ n = recvmsg(b->num, &msg, MSG_PEEK | MSG_CMSG_CLOEXEC);
if (n <= 0) {
if ((n < 0) && (get_last_socket_error() != EAGAIN)
&& (get_last_socket_error() != EWOULDBLOCK))
return -1;
else
return 0;
}
/* if we find a notification, process it and try again if necessary */
while (msg.msg_flags & MSG_NOTIFICATION) {
memset(&snp, 0x00, sizeof(union sctp_notification));
iov.iov_base = (char *)&snp;
iov.iov_len = sizeof(union sctp_notification);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, 0);
+ n = recvmsg(b->num, &msg, MSG_CMSG_CLOEXEC);
if (n <= 0) {
if ((n < 0) && (get_last_socket_error() != EAGAIN)
&& (get_last_socket_error() != EWOULDBLOCK))
return -1;
else
return is_dry;
}
if (snp.sn_header.sn_type == SCTP_SENDER_DRY_EVENT) {
is_dry = 1;
/* disable sender dry event */
# ifdef SCTP_EVENT
memset(&event, 0, sizeof(struct sctp_event));
event.se_assoc_id = 0;
event.se_type = SCTP_SENDER_DRY_EVENT;
event.se_on = 0;
ret =
setsockopt(b->num, IPPROTO_SCTP, SCTP_EVENT, &event,
sizeof(struct sctp_event));
# else
eventsize = (socklen_t) sizeof(struct sctp_event_subscribe);
ret =
getsockopt(b->num, IPPROTO_SCTP, SCTP_EVENTS, &event,
&eventsize);
if (ret < 0)
return -1;
event.sctp_sender_dry_event = 0;
@@ -1803,123 +1803,123 @@
if (ret < 0)
return -1;
}
# ifdef SCTP_AUTHENTICATION_EVENT
if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
dgram_sctp_handle_auth_free_key_event(b, &snp);
# endif
if (data->handle_notifications != NULL)
data->handle_notifications(b, data->notification_context,
(void *)&snp);
/* found notification, peek again */
memset(&snp, 0x00, sizeof(union sctp_notification));
iov.iov_base = (char *)&snp;
iov.iov_len = sizeof(union sctp_notification);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
/* if we have seen the dry already, don't wait */
if (is_dry) {
sockflags = fcntl(b->num, F_GETFL, 0);
fcntl(b->num, F_SETFL, O_NONBLOCK);
}
- n = recvmsg(b->num, &msg, MSG_PEEK);
+ n = recvmsg(b->num, &msg, MSG_PEEK | MSG_CMSG_CLOEXEC);
if (is_dry) {
fcntl(b->num, F_SETFL, sockflags);
}
if (n <= 0) {
if ((n < 0) && (get_last_socket_error() != EAGAIN)
&& (get_last_socket_error() != EWOULDBLOCK))
return -1;
else
return is_dry;
}
}
/* read anything else */
return is_dry;
}
int BIO_dgram_sctp_msg_waiting(BIO *b)
{
int n, sockflags;
union sctp_notification snp;
struct msghdr msg;
struct iovec iov;
bio_dgram_sctp_data *data = (bio_dgram_sctp_data *) b->ptr;
/* Check if there are any messages waiting to be read */
do {
memset(&snp, 0x00, sizeof(union sctp_notification));
iov.iov_base = (char *)&snp;
iov.iov_len = sizeof(union sctp_notification);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
sockflags = fcntl(b->num, F_GETFL, 0);
fcntl(b->num, F_SETFL, O_NONBLOCK);
- n = recvmsg(b->num, &msg, MSG_PEEK);
+ n = recvmsg(b->num, &msg, MSG_PEEK | MSG_CMSG_CLOEXEC);
fcntl(b->num, F_SETFL, sockflags);
/* if notification, process and try again */
if (n > 0 && (msg.msg_flags & MSG_NOTIFICATION)) {
# ifdef SCTP_AUTHENTICATION_EVENT
if (snp.sn_header.sn_type == SCTP_AUTHENTICATION_EVENT)
dgram_sctp_handle_auth_free_key_event(b, &snp);
# endif
memset(&snp, 0x00, sizeof(union sctp_notification));
iov.iov_base = (char *)&snp;
iov.iov_len = sizeof(union sctp_notification);
msg.msg_name = NULL;
msg.msg_namelen = 0;
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_control = NULL;
msg.msg_controllen = 0;
msg.msg_flags = 0;
- n = recvmsg(b->num, &msg, 0);
+ n = recvmsg(b->num, &msg, MSG_CMSG_CLOEXEC);
if (data->handle_notifications != NULL)
data->handle_notifications(b, data->notification_context,
(void *)&snp);
}
} while (n > 0 && (msg.msg_flags & MSG_NOTIFICATION));
/* Return 1 if there is a message to be read, return 0 otherwise. */
if (n > 0)
return 1;
else
return 0;
}
static int dgram_sctp_puts(BIO *bp, const char *str)
{
int n, ret;
n = strlen(str);
ret = dgram_sctp_write(bp, str, n);
return (ret);
}
# endif
static int BIO_dgram_should_retry(int i)
{
int err;
if ((i == 0) || (i == -1)) {
diff -rNU 30 ../openssl-1.0.1n-o/crypto/bio/bss_file.c ./crypto/bio/bss_file.c
--- ../openssl-1.0.1n-o/crypto/bio/bss_file.c 2015-06-11 15:01:06.000000000 +0200
+++ ./crypto/bio/bss_file.c 2015-06-12 03:49:35.000000000 +0200
@@ -92,104 +92,108 @@
# if defined(OPENSSL_SYS_NETWARE) && defined(NETWARE_CLIB)
# include <nwfileio.h>
# endif
# if !defined(OPENSSL_NO_STDIO)
static int MS_CALLBACK file_write(BIO *h, const char *buf, int num);
static int MS_CALLBACK file_read(BIO *h, char *buf, int size);
static int MS_CALLBACK file_puts(BIO *h, const char *str);
static int MS_CALLBACK file_gets(BIO *h, char *str, int size);
static long MS_CALLBACK file_ctrl(BIO *h, int cmd, long arg1, void *arg2);
static int MS_CALLBACK file_new(BIO *h);
static int MS_CALLBACK file_free(BIO *data);
static BIO_METHOD methods_filep = {
BIO_TYPE_FILE,
"FILE pointer",
file_write,
file_read,
file_puts,
file_gets,
file_ctrl,
file_new,
file_free,
NULL,
};
BIO *BIO_new_file(const char *filename, const char *mode)
{
BIO *ret;
FILE *file = NULL;
+ size_t modelen = strlen (mode);
+ char newmode[modelen + 2];
+
+ memcpy (mempcpy (newmode, mode, modelen), "e", 2);
# if defined(_WIN32) && defined(CP_UTF8)
int sz, len_0 = (int)strlen(filename) + 1;
DWORD flags;
/*
* Basically there are three cases to cover: a) filename is
* pure ASCII string; b) actual UTF-8 encoded string and
* c) locale-ized string, i.e. one containing 8-bit
* characters that are meaningful in current system locale.
* If filename is pure ASCII or real UTF-8 encoded string,
* MultiByteToWideChar succeeds and _wfopen works. If
* filename is locale-ized string, chances are that
* MultiByteToWideChar fails reporting
* ERROR_NO_UNICODE_TRANSLATION, in which case we fall
* back to fopen...
*/
if ((sz = MultiByteToWideChar(CP_UTF8, (flags = MB_ERR_INVALID_CHARS),
filename, len_0, NULL, 0)) > 0 ||
(GetLastError() == ERROR_INVALID_FLAGS &&
(sz = MultiByteToWideChar(CP_UTF8, (flags = 0),
filename, len_0, NULL, 0)) > 0)
) {
WCHAR wmode[8];
WCHAR *wfilename = _alloca(sz * sizeof(WCHAR));
if (MultiByteToWideChar(CP_UTF8, flags,
filename, len_0, wfilename, sz) &&
MultiByteToWideChar(CP_UTF8, 0, mode, strlen(mode) + 1,
wmode, sizeof(wmode) / sizeof(wmode[0])) &&
(file = _wfopen(wfilename, wmode)) == NULL &&
(errno == ENOENT || errno == EBADF)
) {
/*
* UTF-8 decode succeeded, but no file, filename
* could still have been locale-ized...
*/
file = fopen(filename, mode);
}
} else if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
file = fopen(filename, mode);
}
# else
- file = fopen(filename, mode);
+ file = fopen(filename, newmode);
# endif
if (file == NULL) {
SYSerr(SYS_F_FOPEN, get_last_sys_error());
ERR_add_error_data(5, "fopen('", filename, "','", mode, "')");
if (errno == ENOENT)
BIOerr(BIO_F_BIO_NEW_FILE, BIO_R_NO_SUCH_FILE);
else
BIOerr(BIO_F_BIO_NEW_FILE, ERR_R_SYS_LIB);
return (NULL);
}
if ((ret = BIO_new(BIO_s_file())) == NULL) {
fclose(file);
return (NULL);
}
BIO_clear_flags(ret, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
* UPLINK */
BIO_set_fp(ret, file, BIO_CLOSE);
return (ret);
}
BIO *BIO_new_fp(FILE *stream, int close_flag)
{
BIO *ret;
if ((ret = BIO_new(BIO_s_file())) == NULL)
return (NULL);
BIO_set_flags(ret, BIO_FLAGS_UPLINK); /* redundant, left for
* documentation puposes */
@@ -248,61 +252,61 @@
}
return (ret);
}
static int MS_CALLBACK file_write(BIO *b, const char *in, int inl)
{
int ret = 0;
if (b->init && (in != NULL)) {
if (b->flags & BIO_FLAGS_UPLINK)
ret = UP_fwrite(in, (int)inl, 1, b->ptr);
else
ret = fwrite(in, (int)inl, 1, (FILE *)b->ptr);
if (ret)
ret = inl;
/* ret=fwrite(in,1,(int)inl,(FILE *)b->ptr); */
/*
* according to Tim Hudson <tjh@cryptsoft.com>, the commented out
* version above can cause 'inl' write calls under some stupid stdio
* implementations (VMS)
*/
}
return (ret);
}
static long MS_CALLBACK file_ctrl(BIO *b, int cmd, long num, void *ptr)
{
long ret = 1;
FILE *fp = (FILE *)b->ptr;
FILE **fpp;
- char p[4];
+ char p[5];
switch (cmd) {
case BIO_C_FILE_SEEK:
case BIO_CTRL_RESET:
if (b->flags & BIO_FLAGS_UPLINK)
ret = (long)UP_fseek(b->ptr, num, 0);
else
ret = (long)fseek(fp, num, 0);
break;
case BIO_CTRL_EOF:
if (b->flags & BIO_FLAGS_UPLINK)
ret = (long)UP_feof(fp);
else
ret = (long)feof(fp);
break;
case BIO_C_FILE_TELL:
case BIO_CTRL_INFO:
if (b->flags & BIO_FLAGS_UPLINK)
ret = UP_ftell(b->ptr);
else
ret = ftell(fp);
break;
case BIO_C_SET_FILE_PTR:
file_free(b);
b->shutdown = (int)num & BIO_CLOSE;
b->ptr = ptr;
b->init = 1;
# if BIO_FLAGS_UPLINK!=0
# if defined(__MINGW32__) && defined(__MSVCRT__) && !defined(_IOB_ENTRIES)
# define _IOB_ENTRIES 20
@@ -359,60 +363,62 @@
file_free(b);
b->shutdown = (int)num & BIO_CLOSE;
if (num & BIO_FP_APPEND) {
if (num & BIO_FP_READ)
BUF_strlcpy(p, "a+", sizeof p);
else
BUF_strlcpy(p, "a", sizeof p);
} else if ((num & BIO_FP_READ) && (num & BIO_FP_WRITE))
BUF_strlcpy(p, "r+", sizeof p);
else if (num & BIO_FP_WRITE)
BUF_strlcpy(p, "w", sizeof p);
else if (num & BIO_FP_READ)
BUF_strlcpy(p, "r", sizeof p);
else {
BIOerr(BIO_F_FILE_CTRL, BIO_R_BAD_FOPEN_MODE);
ret = 0;
break;
}
# if defined(OPENSSL_SYS_MSDOS) || defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_OS2) || defined(OPENSSL_SYS_WIN32_CYGWIN)
if (!(num & BIO_FP_TEXT))
strcat(p, "b");
else
strcat(p, "t");
# endif
# if defined(OPENSSL_SYS_NETWARE)
if (!(num & BIO_FP_TEXT))
strcat(p, "b");
else
strcat(p, "t");
# endif
+ strcat(p, "e");
+
fp = fopen(ptr, p);
if (fp == NULL) {
SYSerr(SYS_F_FOPEN, get_last_sys_error());
ERR_add_error_data(5, "fopen('", ptr, "','", p, "')");
BIOerr(BIO_F_FILE_CTRL, ERR_R_SYS_LIB);
ret = 0;
break;
}
b->ptr = fp;
b->init = 1;
BIO_clear_flags(b, BIO_FLAGS_UPLINK); /* we did fopen -> we disengage
* UPLINK */
break;
case BIO_C_GET_FILE_PTR:
/* the ptr parameter is actually a FILE ** in this case. */
if (ptr != NULL) {
fpp = (FILE **)ptr;
*fpp = (FILE *)b->ptr;
}
break;
case BIO_CTRL_GET_CLOSE:
ret = (long)b->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
b->shutdown = (int)num;
break;
case BIO_CTRL_FLUSH:
if (b->flags & BIO_FLAGS_UPLINK)
UP_fflush(b->ptr);
else
diff -rNU 30 ../openssl-1.0.1n-o/crypto/rand/rand_unix.c ./crypto/rand/rand_unix.c
--- ../openssl-1.0.1n-o/crypto/rand/rand_unix.c 2015-06-11 15:01:06.000000000 +0200
+++ ./crypto/rand/rand_unix.c 2015-06-12 03:50:17.000000000 +0200
@@ -242,61 +242,61 @@
# else /* !defined(__OpenBSD__) */
int RAND_poll(void)
{
unsigned long l;
pid_t curr_pid = getpid();
# if defined(DEVRANDOM) || defined(DEVRANDOM_EGD)
unsigned char tmpbuf[ENTROPY_NEEDED];
int n = 0;
# endif
# ifdef DEVRANDOM
static const char *randomfiles[] = { DEVRANDOM };
struct stat randomstats[sizeof(randomfiles) / sizeof(randomfiles[0])];
int fd;
unsigned int i;
# endif
# ifdef DEVRANDOM_EGD
static const char *egdsockets[] = { DEVRANDOM_EGD, NULL };
const char **egdsocket = NULL;
# endif
# ifdef DEVRANDOM
memset(randomstats, 0, sizeof(randomstats));
/*
* Use a random entropy pool device. Linux, FreeBSD and OpenBSD have
* this. Use /dev/urandom if you can as /dev/random may block if it runs
* out of random entries.
*/
for (i = 0; (i < sizeof(randomfiles) / sizeof(randomfiles[0])) &&
(n < ENTROPY_NEEDED); i++) {
- if ((fd = open(randomfiles[i], O_RDONLY
+ if ((fd = open(randomfiles[i], O_RDONLY | O_CLOEXEC
# ifdef O_NONBLOCK
| O_NONBLOCK
# endif
# ifdef O_BINARY
| O_BINARY
# endif
# ifdef O_NOCTTY /* If it happens to be a TTY (god forbid), do
* not make it our controlling tty */
| O_NOCTTY
# endif
)) >= 0) {
int usec = 10 * 1000; /* spend 10ms on each file */
int r;
unsigned int j;
struct stat *st = &randomstats[i];
/*
* Avoid using same input... Used to be O_NOFOLLOW above, but
* it's not universally appropriate...
*/
if (fstat(fd, st) != 0) {
close(fd);
continue;
}
for (j = 0; j < i; j++) {
if (randomstats[j].st_ino == st->st_ino &&
randomstats[j].st_dev == st->st_dev)
break;
}
if (j < i) {
diff -rNU 30 ../openssl-1.0.1n-o/crypto/rand/randfile.c ./crypto/rand/randfile.c
--- ../openssl-1.0.1n-o/crypto/rand/randfile.c 2015-06-11 15:01:06.000000000 +0200
+++ ./crypto/rand/randfile.c 2015-06-12 03:53:02.000000000 +0200
@@ -120,61 +120,61 @@
MS_STATIC unsigned char buf[BUFSIZE];
#ifndef OPENSSL_NO_POSIX_IO
struct stat sb;
#endif
int i, ret = 0, n;
FILE *in;
if (file == NULL)
return (0);
#ifndef OPENSSL_NO_POSIX_IO
# ifdef PURIFY
/*
* struct stat can have padding and unused fields that may not be
* initialized in the call to stat(). We need to clear the entire
* structure before calling RAND_add() to avoid complaints from
* applications such as Valgrind.
*/
memset(&sb, 0, sizeof(sb));
# endif
if (stat(file, &sb) < 0)
return (0);
RAND_add(&sb, sizeof(sb), 0.0);
#endif
if (bytes == 0)
return (ret);
#ifdef OPENSSL_SYS_VMS
in = vms_fopen(file, "rb", VMS_OPEN_ATTRS);
#else
- in = fopen(file, "rb");
+ in = fopen(file, "rbe");
#endif
if (in == NULL)
goto err;
#if defined(S_IFBLK) && defined(S_IFCHR) && !defined(OPENSSL_NO_POSIX_IO)
if (sb.st_mode & (S_IFBLK | S_IFCHR)) {
/*
* this file is a device. we don't want read an infinite number of
* bytes from a random device, nor do we want to use buffered I/O
* because we will waste system entropy.
*/
bytes = (bytes == -1) ? 2048 : bytes; /* ok, is 2048 enough? */
# ifndef OPENSSL_NO_SETVBUF_IONBF
setvbuf(in, NULL, _IONBF, 0); /* don't do buffered reads */
# endif /* ndef OPENSSL_NO_SETVBUF_IONBF */
}
#endif
for (;;) {
if (bytes > 0)
n = (bytes < BUFSIZE) ? (int)bytes : BUFSIZE;
else
n = BUFSIZE;
i = fread(buf, 1, n, in);
if (i <= 0)
break;
#ifdef PURIFY
RAND_add(buf, i, (double)i);
#else
/* even if n != i, use the full array */
RAND_add(buf, n, (double)i);
#endif
@@ -198,91 +198,91 @@
FILE *out = NULL;
int n;
#ifndef OPENSSL_NO_POSIX_IO
struct stat sb;
i = stat(file, &sb);
if (i != -1) {
# if defined(S_ISBLK) && defined(S_ISCHR)
if (S_ISBLK(sb.st_mode) || S_ISCHR(sb.st_mode)) {
/*
* this file is a device. we don't write back to it. we
* "succeed" on the assumption this is some sort of random
* device. Otherwise attempting to write to and chmod the device
* causes problems.
*/
return (1);
}
# endif
}
#endif
#if defined(O_CREAT) && !defined(OPENSSL_NO_POSIX_IO) && !defined(OPENSSL_SYS_VMS)
{
# ifndef O_BINARY
# define O_BINARY 0
# endif
/*
* chmod(..., 0600) is too late to protect the file, permissions
* should be restrictive from the start
*/
- int fd = open(file, O_WRONLY | O_CREAT | O_BINARY, 0600);
+ int fd = open(file, O_WRONLY | O_CREAT | O_BINARY | O_CLOEXEC, 0600);
if (fd != -1)
out = fdopen(fd, "wb");
}
#endif
#ifdef OPENSSL_SYS_VMS
/*
* VMS NOTE: Prior versions of this routine created a _new_ version of
* the rand file for each call into this routine, then deleted all
* existing versions named ;-1, and finally renamed the current version
* as ';1'. Under concurrent usage, this resulted in an RMS race
* condition in rename() which could orphan files (see vms message help
* for RMS$_REENT). With the fopen() calls below, openssl/VMS now shares
* the top-level version of the rand file. Note that there may still be
* conditions where the top-level rand file is locked. If so, this code
* will then create a new version of the rand file. Without the delete
* and rename code, this can result in ascending file versions that stop
* at version 32767, and this routine will then return an error. The
* remedy for this is to recode the calling application to avoid
* concurrent use of the rand file, or synchronize usage at the
* application level. Also consider whether or not you NEED a persistent
* rand file in a concurrent use situation.
*/
out = vms_fopen(file, "rb+", VMS_OPEN_ATTRS);
if (out == NULL)
out = vms_fopen(file, "wb", VMS_OPEN_ATTRS);
#else
if (out == NULL)
- out = fopen(file, "wb");
+ out = fopen(file, "wbe");
#endif
if (out == NULL)
goto err;
#ifndef NO_CHMOD
chmod(file, 0600);
#endif
n = RAND_DATA;
for (;;) {
i = (n > BUFSIZE) ? BUFSIZE : n;
n -= BUFSIZE;
if (RAND_bytes(buf, i) <= 0)
rand_err = 1;
i = fwrite(buf, 1, i, out);
if (i <= 0) {
ret = 0;
break;
}
ret += i;
if (n <= 0)
break;
}
fclose(out);
OPENSSL_cleanse(buf, BUFSIZE);
err:
return (rand_err ? -1 : ret);
}
const char *RAND_file_name(char *buf, size_t size)