Skip to content

Fixes #2397 Add shared session cache in SSL_CTX#3761

Closed
tmshort wants to merge 2 commits intoopenssl:masterfrom
akamai:master-shared-sessions
Closed

Fixes #2397 Add shared session cache in SSL_CTX#3761
tmshort wants to merge 2 commits intoopenssl:masterfrom
akamai:master-shared-sessions

Conversation

@tmshort
Copy link
Contributor

@tmshort tmshort commented Jun 23, 2017

Support for shared session cache via SSL_CTX_share_session_cache().

The SSL_CTX_sessions() API always returns NULL, as the lock for the shared
session cache is not exposed to library consumers.

Use this method to share the cache for the resumption tests.

Checklist
  • documentation is added or updated
  • tests are added or updated

@kaduk
Copy link
Contributor

kaduk commented Jun 23, 2017

If I recall correctly @vdukhovni was interested in something like this.

ssl/ssl_lib.c Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indent removal is unjustified.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops, will fix.

ssl/ssl_lib.c Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you have styling issue in near vicinity, fix it. I mean it should be return l;, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will fix.

ssl/ssl_sess.c Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd say this kind of calls for "philosophical" problem. Locking kind of implies that you "legitimate" "battle" of callback setters. I mean you kind of say "everybody is allowed to set/change callback to their liking at any time and I ensure that it's properly serialized among threads". But this is not true. It's more than likely that it would be inappropriate to change callbacks once object is instantiated. Or at least allow different threads to have different opinions on what callbacks are...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. These callback were originally left in the SSL_CTX (in our original implementation), but were moved to the cache structure for some consistency. However; one only of these callbacks is invoked (regardless of the number of SSL_CTX's sharing the cache), depending on which SSL_CTX is "active" when an SSL_SESSION is added, removed, etc; since the SSL_CTX is passed into the callback. If a list of SSL_CTX's were kept in the cache, then a callback could be invoked for each of them, at which point, having SSL_CTX-specifc callbacks makes sense (but so does having a single callback).

So, I'm kinda "meh" on how the callbacks are stored.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm trying to say is that this seems like case of excessive locking. Or on certain level meaningless locking. Don't callbacks kind of define how SSL_SESSION operates and should be set prior it becomes appropriate to share it? Because in such case, locking is not necessary...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking of a bigger picture; whether these should even be part of the SSL_SESSION_CACHE structure or remain in SSL_CTX. The locking may seem like overkill, but it's safe in all conditions.

ssl/ssl_sess.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is not synchronized like SSL_CTX_sess_set_remove_cb ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a read, not a write, so it's safe. If I were reading multiple things, or had to read multiple values to generate a return value, it would be locked. For example, |session_cache| is always non-NULL, if there was a chance it would be NULL, I would use a lock since I'd have to do a check.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The access to ctx->session_cache is not safe, if session_cache can be changed
simultaneously.
However I agree with @dot-asm that such use should be considered invalid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A processor cannot do a simultaneous read and write to memory; so the pointer will never have an invalid value. If anything, you will get stale data, which may not matter. But @dot-asm's point still applies; and it's questionable if these functions should be in the SSL_SESSION or SSL_CTX; but I think that the functions associate closer with an SSL_SESSION than an SSL_CTX.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I mean, if you overwrite the the session_cache in one thread, and another thread executes something
that uses ctx->session_cache, it will load the pointer into a register and access the object creating
a race with the other thread deleting the old value of session_cache.
If the read/write locking in SSL_CTX_share_session_cache is good for anything then only
if the value is read with read lock at all times.
Have you tried this with thread sanitizer?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point, but it only becomes a problem if the memory is unmapped when freed. The chance that this occurring is infinitely small, but non-zero.
But, the problem you are referring to is slightly bigger as the old session cache is freed before the new one is assigned, so there is an extremely small window where the old session_cache may be freed before the new one is assigned.
I have not had the chance to run it through thread-sanitizer.
But the bigger picture I'm interested in is if these functions belong with the SSL_SESSION_CACHE, or should stay with the SSL_CTX.

ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would this dead-lock if a == b ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, and that'd be bad mojo. I consider that a serious user error. But, from a different viewpoint, it should always succeed.

@richsalz
Copy link
Contributor

richsalz commented Jun 26, 2017 via email

@tmshort
Copy link
Contributor Author

tmshort commented Jun 26, 2017

Well it’s a “safe” read if the address isn’t being modified by another thread. We generally don’t care about that, but I just came across code (RAND_get_method) that does. Shrug. This is just a side-note.

Yes, even if the pointer is being modified by another thread, a pointer modification is generally done in one memory operation, so this won't segfault or anything. You might get stale data, which would've been correct at the time the function was invoked.

@tmshort
Copy link
Contributor Author

tmshort commented Jun 26, 2017

Yes, even if the pointer is being modified by another thread, a pointer modification is generally done in one memory operation, so this won't segfault or anything.

The only counter-example I can think of is far pointers in 16-bit x86 code; which we don't support anymore.

@tmshort
Copy link
Contributor Author

tmshort commented Jun 26, 2017

And possibly 32-bit mode on a 80386SX (which has a 16-bit external bus, or any other processor where the memory data bus is less than the address size, such as 68008), but that would be two bus cycles, and still considered a single memory operation.

@tmshort tmshort force-pushed the master-shared-sessions branch from 37f6f16 to 7eff280 Compare June 26, 2017 14:04
@tmshort tmshort changed the title Add shared session cache in SSL_CTX Fixes #2397 Add shared session cache in SSL_CTX Jun 26, 2017
@tmshort
Copy link
Contributor Author

tmshort commented Jun 26, 2017

Fixes #2397

@kaduk
Copy link
Contributor

kaduk commented Jun 26, 2017

Yes, even if the pointer is being modified by another thread, a pointer modification is generally done in one memory operation, so this won't segfault or anything.

The only counter-example I can think of is far pointers in 16-bit x86 code; which we don't support anymore.

I think non-x86 platforms can have non-atomic accesses to word-sized variables, though don't have an example handy.

@richsalz
Copy link
Contributor

richsalz commented Jun 26, 2017 via email

ssl/ssl_lib.c Outdated
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

blank line after decl ...
You could merge declaration with his next assignment line too .

@tmshort tmshort force-pushed the master-shared-sessions branch from 7eff280 to dfb11f3 Compare June 27, 2017 19:53
@tmshort
Copy link
Contributor Author

tmshort commented Jun 27, 2017

I'm updating the get/set routines of SSL_SESSION_CACHE. These should resolve most of the issues raised.

  • Where it is just a get, there is a read lock for the SSL_CTX
  • Where it is just a set, there is a write lock for the SSL_CTX
  • Where it is a set that returns the old value, there is a write lock for both SSL_CTX and SSL_SESSION_CACHE
  • When getting the number of sessions, there is a read lock for both the SSL_CTX and SSL_SESSION_CACHE

Also updated the SSL_CTX_share_session_cache() to avoid the very small window where session_cache might point to a stale object.

@tmshort tmshort force-pushed the master-shared-sessions branch from dfb11f3 to c553771 Compare June 29, 2017 20:31
@bernd-edlinger
Copy link
Member

I wonder if it would be more straight forward to ask the application
to implement the shared session cache via new_session_cb,
remove_session_cb and get_session_cb, maybe together with
session_cache_mode == SSL_SESS_CACHE_NO_INTERNAL_LOOKUP,
or if you want add a completely new facility that uses these callbacks ?

@tmshort
Copy link
Contributor Author

tmshort commented Jul 2, 2017

@bernd-edlinger, this does not replace those callbacks, but provides a simpler mechanism to share sessions among SSL_CTX without having to write a lot of code.

@tmshort tmshort force-pushed the master-shared-sessions branch 3 times, most recently from 617a62b to b73195a Compare July 6, 2017 20:14
@tmshort tmshort force-pushed the master-shared-sessions branch from b73195a to 22938f8 Compare July 27, 2017 19:46
@richsalz
Copy link
Contributor

I'm okay with this; are you, @bernd-edlinger ?

ssl/ssl_lib.c Outdated
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This lock might theoretically cause a dead-lock.
Suppose one thread calls
SSL_CTX_share_session_cache(a.b);
and the other thread calls
SSL_CTX_share_session_cache(b,a);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup, although I would except that SSL_CTX setup occur in an initialization thread, and that two threads wouldn't be modifying separate SSL_CTX's. Although, I did have a design where there was one SSL_CTX per thread that was affinity locked to a processor core... not that we used that.

@bernd-edlinger
Copy link
Member

@richsalz actually I would be more happy to see an explicit SSL_SESSION_CACHE API object,
and assign that to SSL_CTX in the construction, and maybe keep some parts of the
SSL_CTX constant at runtime, if that makes less need for new locks.

@richsalz
Copy link
Contributor

yes, that would be a better approach. Todd's on vacation, let's see what he says when he gets back.

@kaduk
Copy link
Contributor

kaduk commented Aug 16, 2017

Hmm, would that have to wait for 1.2?
I guess the API considerations can be addressed by things like SSL_CTX_new_ex(SSL_METHOD *, SSL_SESSION_CACHE *), and absent this patch the per-SSL_CTX session cache has some immutable fields, so it seems like it could be plausibly done.
You'd still need a lock for the SSL_SESSION_CACHE, just no longer need to hold the SSL_CTX lock to access it as well.

@tmshort tmshort force-pushed the master-shared-sessions branch from 8f95bfb to 12be35a Compare August 25, 2017 14:48
@tmshort
Copy link
Contributor Author

tmshort commented Aug 25, 2017

Ok, rebased, updated the locks and the documentation.

I'm still thinking of adding SSL_SESSION_CACHE_set/get APIs, but have yet to do that.

@tmshort tmshort force-pushed the master-shared-sessions branch from 12be35a to 39630b1 Compare October 23, 2017 14:00
@tmshort tmshort changed the title WIP: Fixes #2397 Add shared session cache in SSL_CTX Fixes #2397 Add shared session cache in SSL_CTX Oct 23, 2017
@tmshort tmshort force-pushed the master-shared-sessions branch from 39630b1 to b56d956 Compare January 10, 2018 20:02
@tmshort
Copy link
Contributor Author

tmshort commented Jan 10, 2018

Rebased

@tmshort
Copy link
Contributor Author

tmshort commented Jan 19, 2018

Looks to be a doc-nits travis failure.

@tmshort tmshort force-pushed the master-shared-sessions branch from 7e9cb34 to 7d47ef8 Compare January 19, 2018 16:49
@mattcaswell mattcaswell modified the milestones: 1.1.1, Post 1.1.1 Jan 24, 2018
@kaduk
Copy link
Contributor

kaduk commented Feb 28, 2018

It looks like at least both this and #4848 are trying to modify and/or extend the behavior of SSL_CTX_new() -- perhaps we should step back and think about what sorts of things we might want to do at the time of SSL_CTX creation and how to have a minimal number of APIs that supports all of those things in a reasonable fashion.

@tmshort
Copy link
Contributor Author

tmshort commented Apr 13, 2018

Given that the SSL_SESSION_CACHE exists as a separate object, and there are potential changes (PR #5945) to add a different version of SSL_CTX_new_ex(), perhaps SSL_SESSION_CACHE can be assigned to a newly created SSL_CTX, i.e. one that has a reference count of 1, and/or no sessions attached to it?

@tmshort tmshort force-pushed the master-shared-sessions branch from de12e07 to 2a14408 Compare May 8, 2018 15:04
tmshort added 2 commits June 14, 2018 14:28
Support for shared session cache via SSL_CTX_share_session_cache().

The SSL_CTX_sessions() API always returns NULL, as the lock for the shared
session cache is not exposed to library consumers.

Use this method to share the cache for the resumption tests.
@tmshort tmshort force-pushed the master-shared-sessions branch from 2a14408 to 957d143 Compare June 14, 2018 18:39
@tmshort tmshort mentioned this pull request Oct 3, 2019
1 task
@tmshort
Copy link
Contributor Author

tmshort commented Jun 9, 2020

We are not going to attempt to get this in...

@tmshort tmshort closed this Jun 9, 2020
@tmshort tmshort deleted the master-shared-sessions branch June 9, 2021 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants