Followup to bug 539856: Save actors' IDs in all message handlers to avoid use-after-free when the actor is deleted above the handler in the stack. IRC r=bent
--HG-- extra : transplant_source : %BF%A5%80%B1%A0%E0%8FcZ%9D%02%84%FC%9F%E5%A1R%91n%BD
This commit is contained in:
Родитель
2a0c72702f
Коммит
68991b2f68
|
@ -3485,6 +3485,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
failif = StmtIf(ExprNot(readok))
|
||||
failif.addifstmt(StmtReturn(_Result.PayloadError))
|
||||
|
||||
idvar, saveIdStmts = self.saveActorId(md)
|
||||
case.addstmts(
|
||||
stmts
|
||||
+ [ failif, Whitespace.NL ]
|
||||
|
@ -3497,8 +3498,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
+ self.ctorPrologue(md, errfn=_Result.ValuError,
|
||||
idexpr=_actorHId(actorhandle))
|
||||
+ [ Whitespace.NL ]
|
||||
+ saveIdStmts
|
||||
+ self.invokeRecvHandler(md)
|
||||
+ self.makeReply(md, errfnRecv)
|
||||
+ self.makeReply(md, errfnRecv, idvar)
|
||||
+ [ Whitespace.NL,
|
||||
StmtReturn(_Result.Processed) ])
|
||||
|
||||
|
@ -3513,7 +3515,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
failif = StmtIf(ExprNot(readok))
|
||||
failif.addifstmt(StmtReturn(_Result.PayloadError))
|
||||
|
||||
idvar = ExprVar('__id')
|
||||
idvar, saveIdStmts = self.saveActorId(md)
|
||||
case.addstmts(
|
||||
stmts
|
||||
+ [ failif, Whitespace.NL ]
|
||||
|
@ -3521,8 +3523,7 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
for r in md.returns ]
|
||||
+ self.invokeRecvHandler(md, implicit=0)
|
||||
+ [ Whitespace.NL ]
|
||||
+ [ StmtDecl(Decl(_actorIdType(), idvar.name),
|
||||
self.protocol.routingId()) ]
|
||||
+ saveIdStmts
|
||||
+ self.dtorEpilogue(md, md.actorDecl().var())
|
||||
+ [ Whitespace.NL ]
|
||||
+ self.makeReply(md, errfnRecv, routingId=idvar)
|
||||
|
@ -3540,14 +3541,16 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
failif = StmtIf(ExprNot(readok))
|
||||
failif.addifstmt(StmtReturn(_Result.PayloadError))
|
||||
|
||||
idvar, saveIdStmts = self.saveActorId(md)
|
||||
case.addstmts(
|
||||
stmts
|
||||
+ [ failif, Whitespace.NL ]
|
||||
+ [ StmtDecl(Decl(r.bareType(self.side), r.var().name))
|
||||
for r in md.returns ]
|
||||
+ saveIdStmts
|
||||
+ self.invokeRecvHandler(md)
|
||||
+ [ Whitespace.NL ]
|
||||
+ self.makeReply(md, errfnRecv)
|
||||
+ self.makeReply(md, errfnRecv, routingId=idvar)
|
||||
+ [ StmtReturn(_Result.Processed) ])
|
||||
|
||||
return lbl, case
|
||||
|
@ -3586,9 +3589,9 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
return msgvar, stmts
|
||||
|
||||
|
||||
def makeReply(self, md, errfn, routingId=None):
|
||||
def makeReply(self, md, errfn, routingId):
|
||||
# TODO special cases for async ctor/dtor replies
|
||||
if md.decl.type.isAsync():
|
||||
if not md.decl.type.hasReply():
|
||||
return [ ]
|
||||
|
||||
replyvar = self.replyvar
|
||||
|
@ -3796,6 +3799,17 @@ class _GenerateProtocolActorCode(ipdl.ast.Visitor):
|
|||
args=[ ExprLiteral.String('['+ actorname +'] '+ pfx),
|
||||
ExprVar('stderr') ])) ])
|
||||
|
||||
def saveActorId(self, md):
|
||||
idvar = ExprVar('__id')
|
||||
if md.decl.type.hasReply():
|
||||
# only save the ID if we're actually going to use it, to
|
||||
# avoid unused-variable warnings
|
||||
saveIdStmts = [ StmtDecl(Decl(_actorIdType(), idvar.name),
|
||||
self.protocol.routingId()) ]
|
||||
else:
|
||||
saveIdStmts = [ ]
|
||||
return idvar, saveIdStmts
|
||||
|
||||
|
||||
class _GenerateProtocolParentCode(_GenerateProtocolActorCode):
|
||||
def __init__(self):
|
||||
|
|
Загрузка…
Ссылка в новой задаче